LCOV - code coverage report
Current view: top level - shared/common/src/32_util - m_pptools.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 43.3 % 397 172
Test Date: 2026-09-21 19:39:32 Functions: 87.5 % 8 7

            Line data    Source code
       1              : !!****m* ABINIT/m_pptools
       2              : !! NAME
       3              : !! m_pptools
       4              : !!
       5              : !! FUNCTION
       6              : !!  Helper functions used for post-processing.
       7              : !!
       8              : !! COPYRIGHT
       9              : !! Copyright (C) 2002-2026 ABINIT group (MG, ZL, MJV, BXu)
      10              : !! This file is distributed under the terms of the
      11              : !! GNU General Public License, see ~abinit/COPYING
      12              : !! or http://www.gnu.org/copyleft/gpl.txt .
      13              : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
      14              : !!
      15              : !! SOURCE
      16              : 
      17              : #if defined HAVE_CONFIG_H
      18              : #include "config.h"
      19              : #endif
      20              : 
      21              : #include "abi_common.h"
      22              : 
      23              : MODULE m_pptools
      24              : 
      25              :  use defs_basis
      26              :  use m_errors
      27              :  use m_abicore
      28              :  use m_krank
      29              : 
      30              :  use m_io_tools,        only : open_file
      31              :  use m_fstrings,        only : sjoin, itoa
      32              :  use m_numeric_tools,   only : wrap2_pmhalf
      33              : 
      34              :  implicit none
      35              : 
      36              :  private
      37              : 
      38              :  public :: prmat                ! print real(dp) matrices in an attractive format.
      39              :  public :: write_xsf            ! Open file and Write a generic array in the XSF format (XCrysden format)
      40              :  public :: printxsf             ! Write a generic array in the XSF format (XCrysden format)
      41              :  public :: print_fofr_ri        ! Print the [real, imaginary] part of an array
      42              :  public :: print_fofr_xyzri     ! Print the Cartesian coordinates and the [real,imaginary] part of an array
      43              :  public :: print_fofr_cube      ! Print ||fofr|| in CUBE format.
      44              :  public :: printbxsf            ! Print band structure energies in XCrysDen format.
      45              :  public :: printvtk             ! Print band structure energies and velocities in VTK format.
      46              : 
      47              : CONTAINS  !===========================================================
      48              : !!***
      49              : 
      50              : !!****f* m_pptools/prmat
      51              : !! NAME
      52              : !! prmat
      53              : !!
      54              : !! FUNCTION
      55              : !! This subroutine prints real*8 matrices in an attractive format.
      56              : !!
      57              : !! INPUTS
      58              : !!  mat(mi,nj)= matrix to be printed
      59              : !!  mi        = no rows of mat
      60              : !!  ni        = no rows to print
      61              : !!  nj        = no colums of mat
      62              : !!  unitm     = unit to print to, if not provided std_out is chosen
      63              : !!
      64              : !! OUTPUT
      65              : !!  (only writing)
      66              : !!
      67              : !! SOURCE
      68              : 
      69          624 : subroutine prmat(mat, ni, nj, mi, unitm)
      70              : 
      71              : !Arguments ------------------------------------
      72              : !scalars
      73              :  integer,intent(in)           :: mi,ni,nj
      74              :  integer,intent(in), optional :: unitm
      75              : !arrays
      76              :  real(dp),intent(in)          :: mat(mi,nj)
      77              : 
      78              : !Local variables-------------------------------
      79              : !scalars
      80              :  character(len=1000)    :: msg
      81              :  integer,parameter      :: nline=10
      82              :  integer                :: ii,jj,jstart,jstop,unitn
      83              : ! *************************************************************************
      84              : 
      85          624 :  unitn = std_out; if (present(unitm)) unitn = unitm
      86              : 
      87         1248 :  do jstart = 1, nj, nline
      88          624 :    jstop = min(nj, jstart+nline-1)
      89         2452 :    write(msg, '(3x,10(i4,8x))' ) (jj,jj=jstart,jstop)
      90         1248 :    call wrtout(unitn,msg)
      91              :  end do
      92              : 
      93         1872 :  do ii = 1,ni
      94         3120 :    do jstart= 1, nj, nline
      95         1248 :      jstop = min(nj, jstart+nline-1)
      96         2496 :      if (jstart==1) then
      97         1248 :        write(msg, '(i3,1p,10e12.4)' ) ii, (mat(ii,jj),jj=jstart,jstop)
      98         1248 :        call wrtout(unitn,msg)
      99              :      else
     100            0 :        write(msg, '(3x,1p,10e12.4)' )    (mat(ii,jj),jj=jstart,jstop)
     101            0 :        call wrtout(unitn,msg)
     102              :      end if
     103              :    end do
     104              :  end do
     105              : 
     106          624 : end subroutine prmat
     107              : !!***
     108              : 
     109              : !----------------------------------------------------------------------
     110              : 
     111              : !!****f* m_pptools/write_xsf
     112              : !! NAME
     113              : !! write_xsf
     114              : !!
     115              : !! FUNCTION
     116              : !! Open file and write a generic array in the XSF format (XCrysden format)
     117              : !! See printxsf for the meaning of the arguments.
     118              : !!
     119              : !! OUTPUT
     120              : !! Only write
     121              : !!
     122              : !! SOURCE
     123              : 
     124            8 : subroutine write_xsf(filepath, n1, n2, n3, datagrid, basis, origin, natom, ntypat, typat, xcart, znucl, realrecip)
     125              : 
     126              : !Arguments ------------------------------------
     127              : !scalars
     128              :  character(len=*),intent(in) :: filepath
     129              :  integer,intent(in) :: n1, n2, n3, realrecip, natom, ntypat
     130              : !arrays
     131              :  integer,intent(in) :: typat(natom)
     132              :  real(dp),intent(in) :: basis(3,3), datagrid(n1*n2*n3), origin(3), xcart(3,natom), znucl(ntypat)
     133              : 
     134              : !Local variables-------------------------------
     135              :  integer :: ount
     136              :  character(len=500) :: msg
     137              : ! *************************************************************************
     138              : 
     139            8 :  if (open_file(filepath, msg, newunit=ount, form='formatted', status='unknown', action="write") /= 0) then
     140            0 :    ABI_ERROR(msg)
     141              :  end if
     142              : 
     143            8 :  call printxsf(n1, n2, n3, datagrid, basis, origin, natom, ntypat, typat, xcart, znucl, ount, realrecip)
     144            8 :  close(ount)
     145              : 
     146            8 : end subroutine write_xsf
     147              : !!***
     148              : 
     149              : !----------------------------------------------------------------------
     150              : 
     151              : !!****f* m_pptools/printxsf
     152              : !! NAME
     153              : !! printxsf
     154              : !!
     155              : !! FUNCTION
     156              : !! Write a generic array in the XSF format (XCrysden format)
     157              : !!
     158              : !! INPUTS
     159              : !! n1, n2, n3=grid size along x, y, z
     160              : !! datagrid(n1*n2*n3) = datagrid values stored using the fortran convention
     161              : !! basis(3,3) = basis vectors of the direct real lattice or of the reciprocal lattice (fortran convention)
     162              : !!              (Bohr units if realrecip=0, Bohr^-1 if realrecip=1, see below)
     163              : !! origin(3) = origin of the grid
     164              : !! ount   = unit number of the output file (already open by the caller, not closed here!)
     165              : !! realrecip = 0  for a plot in real space
     166              : !!             1  for a plot in reciprocal space
     167              : !!
     168              : !! OUTPUT
     169              : !! Only write
     170              : !!
     171              : !! SOURCE
     172              : 
     173           20 : subroutine printxsf(n1, n2, n3, datagrid, basis, origin, natom, ntypat, typat, xcart, znucl, ount, realrecip)
     174              : 
     175              : !Arguments ------------------------------------
     176              : !scalars
     177              :  integer,intent(in) :: n1, n2, n3, ount, realrecip, natom, ntypat
     178              : !arrays
     179              :  integer,intent(in) :: typat(natom)
     180              :  real(dp),intent(in) :: basis(3,3), datagrid(n1*n2*n3), origin(3), xcart(3,natom), znucl(ntypat)
     181              : 
     182              : !Local variables-------------------------------
     183              : !scalars
     184              :  integer :: ix,iy,iz,nslice,nsym,iatom
     185              :  real(dp) :: fact
     186              : !arrays
     187           40 :  real(dp) :: tau(3,natom)
     188              : ! *************************************************************************
     189              : 
     190           20 :  if (all(realrecip /= [0, 1])) then
     191            0 :    ABI_BUG(sjoin('The argument realrecip should be 0 or 1, received:', itoa(realrecip)))
     192              :  end if
     193              : 
     194              :  ! conversion between ABINIT default units and XCrysden units
     195           20 :  fact = Bohr_Ang; if (realrecip == 1) fact=one/fact ! since we are in reciprocal space
     196              : 
     197              :  ! TODO insert crystalline structure and dummy atoms in case of reciprocal space need to convert basis too
     198           20 :  write(ount,'(1X,A)')  'DIM-GROUP'
     199           20 :  write(ount,*) '3  1'
     200           20 :  write(ount,'(1X,A)') 'PRIMVEC'
     201           80 :  do iy = 1,3
     202          260 :    write(ount,'(3(ES17.10,2X))') (Bohr_Ang*basis(ix,iy), ix=1,3)
     203              :  end do
     204              : 
     205              :  ! generate translated coordinates to fit origin shift
     206         9144 :  do iatom = 1,natom
     207        36516 :    tau(:,iatom) = xcart(:,iatom) - origin(:)
     208              :  end do
     209              : 
     210           20 :  write(ount,'(1X,A)') 'PRIMCOORD'
     211           20 :  write(ount,*) natom, ' 1'
     212         9144 :  do iatom = 1,natom
     213         9124 :    write(ount,'(i9,3(3X,ES17.10))') NINT(znucl(typat(iatom))), &  ! WARNING alchemy not supported by XCrysden
     214        18268 :      Bohr_Ang*tau(1,iatom), Bohr_Ang*tau(2,iatom), Bohr_Ang*tau(3,iatom)
     215              :  end do
     216           20 :  write(ount,'(1X,A)') 'ATOMS'
     217         9144 :  do iatom = 1,natom
     218         9124 :    write(ount,'(i9,3(3X,ES17.10))') NINT(znucl(typat(iatom))), & ! WARNING alchemy not supported by XCrysden
     219        18268 :      Bohr_Ang*tau(1,iatom), Bohr_Ang*tau(2,iatom), Bohr_Ang*tau(3,iatom)
     220              :  end do
     221              : 
     222           20 :  write(ount,'(a)')' BEGIN_BLOCK_DATAGRID3D'
     223           20 :  write(ount,'(a)')' datagrid'
     224           20 :  write(ount,'(a)')' DATAGRID_3D_DENSITY'
     225              :  ! NOTE: XCrysden uses aperiodical data grid
     226           20 :  write(ount,*)n1+1,n2+1,n3+1
     227           20 :  write(ount,*)origin
     228           80 :  write(ount,*)basis(:,1)*fact
     229           80 :  write(ount,*)basis(:,2)*fact
     230           80 :  write(ount,*)basis(:,3)*fact
     231              : 
     232           20 :  nslice=1
     233          626 :  do iz=1,n3
     234        27624 :    do iy=1,n2
     235        27018 :      write(ount,'(8es16.8)') datagrid(1+n1*(nslice-1):n1+n1*(nslice-1)),datagrid(1+n1*(nslice-1))
     236        27624 :      nslice = nslice+1
     237              :    end do
     238          606 :    nsym=nslice-n2
     239          626 :    write(ount,'(8es16.8)') datagrid(1+n1*(nsym-1):n1+n1*(nsym-1)),datagrid(1+n1*(nsym-1))
     240              :  end do
     241              : 
     242              :  ! Now write upper plane
     243              :  nslice = 1
     244          626 :  do iy=1,n2
     245          606 :    write(ount,'(8es16.8)') datagrid(1+n1*(nslice-1):n1+n1*(nslice-1)),datagrid(1+n1*(nslice-1))
     246          626 :    nslice=nslice+1
     247              :  end do
     248              : 
     249           20 :  nsym = nslice-n2
     250           20 :  write(ount,'(8es16.8)') datagrid(1+n1*(nsym-1):n1+n1*(nsym-1)),datagrid(1+n1*(nsym-1))
     251              : 
     252           20 :  write(ount,'(a)')' END_DATAGRID_3D'
     253           20 :  write(ount,'(a)')' END_BLOCK_DATAGRID3D'
     254              : 
     255           20 : end subroutine printxsf
     256              : !!***
     257              : 
     258              : !----------------------------------------------------------------------
     259              : 
     260              : !!****f* m_pptools/print_fofr_ri
     261              : !! NAME
     262              : !!  print_fofr_ri
     263              : !!
     264              : !! FUNCTION
     265              : !!  Print the [real,imaginary] part of fofr on unit unit
     266              : !!
     267              : !! INPUTS
     268              : !!  ri_mode =
     269              : !!    "RI" if both real and imag part are wanted
     270              : !!    "R"  for real part
     271              : !!    "I"  for imaginary part
     272              : !!  nx,ny,nz,ldx,ldy,ldz = Logical and physical dimensions of the array.
     273              : !!  fofr(2,ldx,ldy,ldz) = Input data
     274              : !!  [unit] = Fortran unit number. Default: std_out
     275              : !!
     276              : !! OUTPUT
     277              : !!  Only writing
     278              : !!
     279              : !! SOURCE
     280              : 
     281            2 : subroutine print_fofr_ri(ri_mode,nx,ny,nz,ldx,ldy,ldz,fofr,unit)
     282              : 
     283              : !Arguments -----------------------------------------------
     284              : !scalars
     285              :  integer,intent(in) :: nx,ny,nz,ldx,ldy,ldz
     286              :  integer,optional,intent(in) :: unit
     287              :  character(len=*),intent(in) :: ri_mode
     288              : !arrays
     289              :  real(dp),intent(in) :: fofr(2,ldx,ldy,ldz)
     290              : 
     291              : !Local variables-------------------------------
     292              :  integer :: ount,ix,iy,iz
     293              : ! *************************************************************************
     294              : 
     295            2 :  ount = std_out; if (PRESENT(unit)) ount = unit
     296              : 
     297            1 :  SELECT CASE (ri_mode)
     298              :  CASE ("RI","ri")
     299           13 :    do iz=1,nz
     300          157 :      do iy=1,ny
     301         1884 :        do ix=1,nx
     302         1872 :          write(ount,'(2f20.16)') fofr(:,ix,iy,iz)
     303              :        end do
     304              :      end do
     305              :    end do
     306              : 
     307              :  CASE ("R","r")
     308           25 :    do iz=1,nz
     309          409 :      do iy=1,ny
     310         4248 :        do ix=1,nx
     311         4224 :          write(ount,'(f20.16)') fofr(1,ix,iy,iz)
     312              :        end do
     313              :      end do
     314              :    end do
     315              : 
     316              :  CASE ("I","i")
     317            0 :    do iz=1,nz
     318            0 :      do iy=1,ny
     319            0 :        do ix=1,nx
     320            0 :          write(ount,'(f20.16)') fofr(2,ix,iy,iz)
     321              :        end do
     322              :      end do
     323              :    end do
     324              : 
     325              :  CASE DEFAULT
     326            2 :    ABI_ERROR("Wrong ri_mode")
     327              :  END SELECT
     328              : 
     329            2 : end subroutine print_fofr_ri
     330              : !!***
     331              : 
     332              : !----------------------------------------------------------------------
     333              : 
     334              : !!****f* m_pptools/print_fofr_xyzri
     335              : !! NAME
     336              : !!  print_fofr_xyzri
     337              : !!
     338              : !! FUNCTION
     339              : !!  Print the Cartesian coordinates and the [real,imaginary] part of fofr on unit unit
     340              : !!
     341              : !! INPUTS
     342              : !!  ri_mode =
     343              : !!    "RI" if both real and imag part are wanted
     344              : !!    "R"  for real part
     345              : !!    "I"  for imaginary part
     346              : !!  nx,ny,nz,ldx,ldy,ldz = Logical and physical dimensions of the array.
     347              : !!  fofr(2,ldx,ldy,ldz) = Input data
     348              : !!  rprimd(3,3)=Lattive vectors in Bohr
     349              : !!  [conv_fact] = Conversion factor for rprimd (rprimd is multiplied by conv_fact). Default is one
     350              : !!  [unit] = Fortran unit number. Default: std_out
     351              : !!
     352              : !! OUTPUT
     353              : !!  Only writing
     354              : !!
     355              : !! SOURCE
     356              : 
     357            1 : subroutine print_fofr_xyzri(ri_mode,nx,ny,nz,ldx,ldy,ldz,fofr,rprimd,conv_fact,unit)
     358              : 
     359              : !Arguments -----------------------------------------------
     360              : !scalars
     361              :  integer,intent(in) :: nx,ny,nz,ldx,ldy,ldz
     362              :  integer,optional,intent(in) :: unit
     363              :  real(dp),optional,intent(in) :: conv_fact
     364              :  character(len=*),intent(in) :: ri_mode
     365              : !arrays
     366              :  real(dp),intent(in) :: rprimd(3,3)
     367              :  real(dp),intent(in) :: fofr(2,ldx,ldy,ldz)
     368              : 
     369              : !Local variables-------------------------------
     370              : !scalars
     371              :  integer :: ount,ix,iy,iz
     372              :  real(dp) :: xnow,ynow,znow,my_cfact
     373              : ! *************************************************************************
     374              : 
     375            1 :  ount = std_out; if (PRESENT(unit)) ount = unit
     376            1 :  my_cfact = one; if (PRESENT(conv_fact)) my_cfact = conv_fact
     377              : 
     378            1 :  SELECT CASE (ri_mode)
     379              :  CASE ("RI","ri")
     380           13 :    do iz=1,nz
     381          157 :      do iy=1,ny
     382         1884 :        do ix=1,nx
     383         1728 :          xnow = rprimd(1,1)*(ix-1)/nx + rprimd(1,2)*(iy-1)/ny + rprimd(1,3)*(iz-1)/nz
     384         1728 :          ynow = rprimd(2,1)*(ix-1)/nx + rprimd(2,2)*(iy-1)/ny + rprimd(2,3)*(iz-1)/nz
     385         1728 :          znow = rprimd(3,1)*(ix-1)/nx + rprimd(3,2)*(iy-1)/ny + rprimd(3,3)*(iz-1)/nz
     386         1872 :          write(ount,'(3f16.10,2f20.16)') my_cfact*xnow, my_cfact*ynow, my_cfact*znow,fofr(:,ix,iy,iz)
     387              :        end do
     388              :      end do
     389              :    end do
     390              : 
     391              :  CASE ("R","r")
     392            0 :    do iz=1,nz
     393            0 :      do iy=1,ny
     394            0 :        do ix=1,nx
     395            0 :          xnow = rprimd(1,1)*(ix-1)/nx + rprimd(1,2)*(iy-1)/ny + rprimd(1,3)*(iz-1)/nz
     396            0 :          ynow = rprimd(2,1)*(ix-1)/nx + rprimd(2,2)*(iy-1)/ny + rprimd(2,3)*(iz-1)/nz
     397            0 :          znow = rprimd(3,1)*(ix-1)/nx + rprimd(3,2)*(iy-1)/ny + rprimd(3,3)*(iz-1)/nz
     398            0 :          write(ount,'(3f16.10,f20.16)') my_cfact*xnow, my_cfact*ynow, my_cfact*znow,fofr(1,ix,iy,iz)
     399              :        end do
     400              :      end do
     401              :    end do
     402              : 
     403              :  CASE ("I","i")
     404            0 :    do iz=1,nz
     405            0 :      do iy=1,ny
     406            0 :        do ix=1,nx
     407            0 :          xnow = rprimd(1,1)*(ix-1)/nx + rprimd(1,2)*(iy-1)/ny + rprimd(1,3)*(iz-1)/nz
     408            0 :          ynow = rprimd(2,1)*(ix-1)/nx + rprimd(2,2)*(iy-1)/ny + rprimd(2,3)*(iz-1)/nz
     409            0 :          znow = rprimd(3,1)*(ix-1)/nx + rprimd(3,2)*(iy-1)/ny + rprimd(3,3)*(iz-1)/nz
     410            0 :          write(ount,'(3f16.10,f20.16)') my_cfact*xnow, my_cfact*ynow, my_cfact*znow,fofr(2,ix,iy,iz)
     411              :        end do
     412              :      end do
     413              :    end do
     414              : 
     415              :  CASE DEFAULT
     416            1 :    ABI_ERROR("Wrong ri_mode")
     417              :  END SELECT
     418              : 
     419            1 : end subroutine print_fofr_xyzri
     420              : !!***
     421              : 
     422              : !----------------------------------------------------------------------
     423              : 
     424              : !!****f* m_pptools/print_fofr_cube
     425              : !! NAME
     426              : !!  print_fofr_cube
     427              : !!
     428              : !! FUNCTION
     429              : !!  Print array fofr in the cube file format
     430              : !!
     431              : !! INPUTS
     432              : !!  nx,ny,nz,ldx,ldy,ldz = Logical and physical dimensions of the array.
     433              : !!  fofr(2,ldx,ldy,ldz) = Input data
     434              : !!  rprimd(3,3)=Lattive vectors in Bohr
     435              : !!  [unit] = Fortran unit number. Default: std_out
     436              : !!
     437              : !! OUTPUT
     438              : !!  Only writing
     439              : !!
     440              : !! SOURCE
     441              : 
     442              : 
     443            1 : subroutine print_fofr_cube(nx,ny,nz,ldx,ldy,ldz,fofr,rprimd,natom,znucl_atom,xcart,unit)
     444              : 
     445              : !Arguments -----------------------------------------------
     446              : !scalars
     447              :  integer,intent(in) :: nx,ny,nz,ldx,ldy,ldz,natom
     448              :  integer,optional,intent(in) :: unit
     449              : !arrays
     450              :  integer,intent(in) :: znucl_atom(natom)
     451              :  real(dp),intent(in) :: rprimd(3,3),xcart(3,natom)
     452              :  real(dp),intent(in) :: fofr(2,ldx,ldy,ldz)
     453              : 
     454              : !Local variables-------------------------------
     455              : !scalars
     456              :  integer,parameter :: cplx=2
     457              :  integer :: ount,ix,iy,iz,iatom
     458              : ! *************************************************************************
     459              : 
     460            1 :  ount = std_out; if (PRESENT(unit)) ount = unit
     461              : 
     462              : ! EXAMPLE FROM THE WEB
     463              : ! CPMD CUBE FILE.
     464              : ! OUTER LOOP: X, MIDDLE LOOP: Y, INNER LOOP: Z
     465              : ! 3    0.000000    0.000000    0.000000
     466              : ! 40    0.283459    0.000000    0.000000
     467              : ! 40    0.000000    0.283459    0.000000
     468              : ! 40    0.000000    0.000000    0.283459
     469              : ! 8    0.000000    5.570575    5.669178    5.593517
     470              : ! 1    0.000000    5.562867    5.669178    7.428055
     471              : ! 1    0.000000    7.340606    5.669178    5.111259
     472              : ! -0.25568E-04  0.59213E-05  0.81068E-05  0.10868E-04  0.11313E-04  0.35999E-05
     473              : 
     474            1 :  write(ount,'(a)') 'ABINIT generated cube file'
     475            1 :  write(ount,'(a)') 'from cut3d tool'
     476              : 
     477            1 :  write(ount,'(i9,3(1x,f12.6))') natom,0.,0.,0.
     478            4 :  write(ount,'(i9,3(1x,f12.6))') nx,(rprimd(iy,1)/nx, iy=1,3)
     479            4 :  write(ount,'(i9,3(1x,f12.6))') ny,(rprimd(iy,2)/ny, iy=1,3)
     480            4 :  write(ount,'(i9,3(1x,f12.6))') nz,(rprimd(iy,3)/nz, iy=1,3)
     481              : 
     482            2 :  do iatom=1,natom
     483            2 :    write(ount,'(i9,4(3X,ES17.10))') znucl_atom(iatom),0.d0,xcart(1:3,iatom)
     484              :  end do
     485              : 
     486              : ! Note C ordering of the indexes
     487              :  if (cplx==2) then
     488           17 :    do ix=1,nx
     489          273 :      do iy=1,ny
     490         4368 :        do iz=1,nz
     491         4352 :          write(ount,'(6(f12.6,2x))') sqrt(fofr(1,ix,iy,iz)**2 + fofr(2,ix,iy,iz)**2 )
     492              :        end do
     493              :      end do
     494              :    end do
     495              :  else
     496              :    do ix=1,nx
     497              :      do iy=1,ny
     498              :        do iz=1,nz
     499              :          write(ount,'(6(f12.6,2x))') fofr(1,ix,iy,iz)
     500              :        end do
     501              :      end do
     502              :    end do
     503              :  end if
     504              : 
     505            1 : end subroutine print_fofr_cube
     506              : !!***
     507              : 
     508              : !----------------------------------------------------------------------
     509              : 
     510              : !!****f* m_pptools/printbxsf
     511              : !! NAME
     512              : !! printbxsf
     513              : !!
     514              : !! FUNCTION
     515              : !!  Print band structure energies in XCrysDen format.
     516              : !!
     517              : !! INPUTS
     518              : !!  eigen(mband,nkpt,nsppol) = eigenvalues in hartree
     519              : !!  ewind = energy window around the fermi level.
     520              : !!          if ewind /= 0 ==> a band is considered in the plot of FSurf
     521              : !!                            only if it is inside [ ef-ewind, ef+ewind ] for some k point
     522              : !!          if ewind == 0 ==> all bands will be keept in the _BXSF file
     523              : !!  fermie = Fermi energy (Hartree)
     524              : !!  gprimd(3,3) = dimensional primitive translations for reciprocal space (bohr^-1)
     525              : !!  kptrlatt(3,3) = reciprocal of lattice vectors for full kpoint grid
     526              : !!  mband = maximum number of bands
     527              : !!  nsppol = 1 for unpolarized, 2 for spin-polarized
     528              : !!  shiftk(3,nshiftk) =shift vector for k point grid
     529              : !!  fname = filename for the fortran file
     530              : !!  symafm(nsym)=(Anti)ferromagnetic symmetries.
     531              : !!  use_afm=.TRUE. if (anti)ferromagnetic symmetries are used.
     532              : !!
     533              : !! OUTPUT
     534              : !!  ierr=Status error.
     535              : !!  BXSF file.
     536              : !!
     537              : !! SOURCE
     538              : 
     539            3 : subroutine printbxsf(eigen,ewind,fermie,gprimd,kptrlatt,mband,&
     540            3 :                     nkptirred,kptirred,nsym,use_afm,symrec,symafm,use_tr,nsppol,shiftk,nshiftk,fname,ierr)
     541              : 
     542              : !Arguments ------------------------------------
     543              : !scalars
     544              :  integer,intent(in) :: mband,nkptirred,nshiftk,nsppol,nsym
     545              :  integer,intent(out) :: ierr
     546              :  real(dp),intent(in) :: ewind,fermie
     547              :  logical,intent(in) :: use_afm,use_tr
     548              :  character(len=*),intent(in) :: fname
     549              : !arrays
     550              :  integer,intent(in) :: kptrlatt(3,3),symafm(nsym),symrec(3,3,nsym)
     551              :  real(dp),intent(in) :: eigen(mband,nkptirred,nsppol),gprimd(3,3)
     552              :  real(dp),intent(in) :: kptirred(3,nkptirred),shiftk(3,nshiftk)
     553              : 
     554              : !Local variables-------------------------------
     555              : !scalars
     556              :  integer,parameter :: enough = 50
     557              :  integer :: iband,ik1,ik2,ik3,ikgrid,ikpt,indx
     558              :  integer :: isppol,isym,maxband,minband,nk1,nk2,nk3,nkptfull,ubxsf,timrev
     559              :  integer :: symkptrank, nsymfm, isymfm
     560              :  real(dp) :: ene
     561              :  character(len=500) :: msg
     562            3 :  type(krank_t) :: krank
     563              : !arrays
     564            3 :  integer,allocatable :: fulltoirred(:),symrecfm(:,:,:)
     565              :  real(dp) :: kptgrid(3),gmet(3,3)
     566              : ! *************************************************************************
     567              : 
     568            3 :  ierr = 0
     569              : 
     570              :  ! Error if klatt is no simple orthogonal lattice (in red space)
     571              :  ! for generalization to MP grids, need new version of XCrysDen
     572              :  if (kptrlatt(1,2)/=0 .or. kptrlatt(1,3)/=0 .or. kptrlatt(2,1)/=0 .or. &
     573            3 :      kptrlatt(2,3)/=0 .or. kptrlatt(3,1)/=0 .or. kptrlatt(3,2)/=0 ) then
     574              :    write(msg,'(3a)')&
     575            0 :     'kptrlatt should be diagonal, for the FS calculation ',ch10,&
     576            0 :     'Action: use an orthogonal k-grid for the GS calculation '
     577            0 :    ABI_COMMENT(msg)
     578            0 :    ierr = ierr + 1
     579              :  end if
     580              : 
     581              :  ! Error if there are not at least 2 kpts in each direction:
     582              :  ! kptrank will fail for the intermediate points below
     583            3 :  if (abs(kptrlatt(1,1)) < 2 .or. abs(kptrlatt(2,2)) < 2 .or. abs(kptrlatt(3,3)) < 2) then
     584              :    write(msg,'(3a)')&
     585            0 :     'You need at least 2 points in each direction in k space to output BXSF files ',ch10,&
     586            0 :     'Action: use an augmented k-grid for the GS calculation (at least 2x2x2) '
     587            0 :    ABI_COMMENT(msg)
     588            0 :    ierr = ierr + 1
     589              :  end if
     590              : 
     591           15 :  if (ANY(ABS(shiftk) > tol10)) then
     592              :    write(msg,'(3a)')&
     593            0 :     'Origin of the k-grid should be (0,0,0) for the FS calculation ',ch10,&
     594            0 :     'Action: use a non-shifted k-grid for the GS calculation. Returning '
     595            0 :    ABI_COMMENT(msg)
     596            0 :    ierr = ierr + 1
     597              :  end if
     598              : 
     599            3 :  if (ierr /= 0) return
     600              : 
     601              :  ! Compute reciprocal space metric.
     602            3 :  gmet = MATMUL(TRANSPOSE(gprimd), gprimd)
     603              : 
     604            3 :  if (use_afm) then
     605            0 :    nsymfm = 0
     606            0 :    do isym = 1, nsym
     607            0 :      if (symafm(isym) == 1) nsymfm = nsymfm+1
     608              :    end do
     609            0 :    ABI_MALLOC(symrecfm, (3,3,nsymfm))
     610            0 :    isymfm = 0
     611            0 :    do isym = 1, nsym
     612            0 :      if (symafm(isym) == 1) then
     613            0 :        isymfm = isymfm + 1
     614            0 :        symrecfm(:,:,isymfm) = symrec(:,:,isym)
     615              :      end if
     616              :    end do
     617              :  else
     618            3 :    nsymfm = nsym
     619            9 :    ABI_MALLOC(symrecfm, (3,3,nsymfm))
     620         1566 :    symrecfm = symrec
     621              :  end if
     622              : 
     623              :  ! Xcrysden uses aperiodic data-grid (images are included in the grid)
     624            3 :  nk1 = kptrlatt(1,1); nk2 = kptrlatt(2,2); nk3 = kptrlatt(3,3)
     625            3 :  nkptfull = (nk1+1) * (nk2+1) * (nk3+1)
     626              : 
     627            9 :  ABI_MALLOC(fulltoirred, (nkptfull))
     628            3 :  timrev = 0; if (use_tr) timrev=1
     629              : 
     630            3 :  call krank%init(nkptirred, kptirred, nsym=nsymfm, symrec=symrecfm, time_reversal=use_tr)
     631              : 
     632              :  ! Xcrysden employs the C-ordering for the Fermi Surface (x-y-z)
     633            3 :  ikgrid=0
     634           38 :  do ik1=0,nk1
     635          489 :    do ik2=0,nk2
     636         6857 :      do ik3=0,nk3
     637              : 
     638         6371 :        ikgrid = ikgrid+1
     639         6371 :        kptgrid(1) = DBLE(ik1)/kptrlatt(1,1)
     640         6371 :        kptgrid(2) = DBLE(ik2)/kptrlatt(2,2)
     641         6371 :        kptgrid(3) = DBLE(ik3)/kptrlatt(3,3)
     642              : 
     643              :        ! Find correspondence between the Xcrysden grid and the IBZ
     644         6371 :        symkptrank = krank%get_rank(kptgrid)
     645         6371 :        fulltoirred(ikgrid) = krank%invrank(symkptrank)
     646              : 
     647         6822 :        if (fulltoirred(ikgrid) < 1) then
     648            0 :          if (ierr <= enough) then
     649              :            write(msg,'(a,3es16.8,2a,i0,2a)')&
     650            0 :             'kpt = ',kptgrid,ch10,' with rank ', symkptrank, ch10,&
     651            0 :             'has no symmetric among the k-points used in the GS calculation '
     652            0 :            ABI_WARNING(msg)
     653              :          end if
     654            0 :          ierr = ierr + 1
     655              :        end if
     656              : 
     657              :      end do !ik1
     658              :    end do !ik2
     659              :  end do !ik3
     660              : 
     661            3 :  call krank%free()
     662              : 
     663            3 :  ABI_CHECK(ierr == 0, "See above warnings")
     664              : 
     665            3 :  if (abs(ewind) < tol12 ) then
     666              :    ! Keep all bands.
     667            3 :    minband=1
     668            3 :    maxband=mband
     669              :  else
     670              :    ! Select a subset of bands.
     671            0 :    minband = mband
     672            0 :    maxband = 0
     673            0 :    ene=abs(ewind)
     674            0 :    do isppol=1,nsppol
     675            0 :      do iband=1,mband
     676            0 :        if(minval(eigen(iband,:,isppol))-fermie < -ene) minband = iband
     677              :      end do
     678            0 :      do iband=mband,1,-1
     679            0 :        if (maxval(eigen(iband,:,isppol))-fermie > ene) maxband = iband
     680              :      end do
     681              :    end do ! isppol
     682              : 
     683              :  end if ! abs(energy_window)
     684              : 
     685              :  ! Dump results to file
     686            3 :  if (open_file(fname,msg, newunit=ubxsf, status='unknown', action="write", form='formatted') /= 0 ) then
     687            0 :    ABI_WARNING(msg)
     688            0 :    ierr=ierr +1; RETURN
     689              :  end if
     690              : 
     691              :  ! Write header
     692            3 :  write(ubxsf,*)' BEGIN_INFO'
     693            3 :  write(ubxsf,*)'   #'
     694            3 :  write(ubxsf,*)'   # this is a Band-XCRYSDEN-Structure-File for Visualization of Fermi Surface'
     695            3 :  write(ubxsf,*)'   # generated by the ABINIT package'
     696            3 :  write(ubxsf,*)'   #'
     697            3 :  write(ubxsf,*)'   #  bands between ',minband,' and ',maxband
     698            3 :  write(ubxsf,*)'   #'
     699            3 :  if (nsppol == 2 ) then
     700            0 :    write(ubxsf,*)'   # NOTE: the first band is relative to spin-up electrons,'
     701            0 :    write(ubxsf,*)'   # the second band to spin-down and so on .. '
     702            0 :    write(ubxsf,*)'   #'
     703              :  end if
     704            3 :  write(ubxsf,*)'   # Launch as: xcrysden --bxsf '
     705            3 :  write(ubxsf,*)'   #'
     706            3 :  write(ubxsf,'(a,es16.8)')'   Fermi Energy: ',fermie
     707            3 :  write(ubxsf,*)' END_INFO'
     708            3 :  write(ubxsf,*)' '
     709            3 :  write(ubxsf,*)' BEGIN_BLOCK_BANDGRID_3D'
     710            3 :  write(ubxsf,*)' band_energies'
     711            3 :  write(ubxsf,*)' BEGIN_BANDGRID_3D'
     712              : 
     713            3 :  write(ubxsf,*)' ',(maxband-minband+1)*nsppol
     714            3 :  write(ubxsf,*)' ',nk1+1,nk2+1,nk3+1
     715            3 :  write(ubxsf,*)' ',shiftk(:,1)
     716              :  ! Angstrom units are used in the BXSF format
     717           12 :  write(ubxsf,*)' ',gprimd(:,1)/Bohr_Ang
     718           12 :  write(ubxsf,*)' ',gprimd(:,2)/Bohr_Ang
     719           12 :  write(ubxsf,*)' ',gprimd(:,3)/Bohr_Ang
     720              : 
     721              :  ! print out data for all relevant bands and full kpt grid (redundant, yes)
     722              :  ! for each kpt in full zone, find equivalent irred kpt and print eigenval
     723            3 :  indx = 0
     724           22 :  do iband=minband,maxband
     725           41 :    do isppol=1,nsppol
     726           19 :      write(ubxsf,*)' BAND: ',indx+minband
     727        26422 :      write(ubxsf,'(7(es16.8))')(eigen(iband,fulltoirred(ikpt),isppol),ikpt=1,nkptfull)
     728           38 :      indx=indx+1
     729              :    end do
     730              :  end do
     731              : 
     732            3 :  write(ubxsf,*)'  END_BANDGRID_3D'
     733            3 :  write(ubxsf,*)' END_BLOCK_BANDGRID_3D'
     734            3 :  close(ubxsf)
     735              : 
     736            3 :  ABI_FREE(fulltoirred)
     737            3 :  ABI_FREE(symrecfm)
     738              : 
     739            3 : end subroutine printbxsf
     740              : !!***
     741              : 
     742              : !!****f* m_pptools/printvtk
     743              : !! NAME
     744              : !! printvtk
     745              : !!
     746              : !! FUNCTION
     747              : !!  Print band structure energies and velocities in VTK format.
     748              : !!
     749              : !! INPUTS
     750              : !!  eigen(mband,nkpt,nsppol) = eigenvalues in hartree
     751              : !!  ewind = energy window around the fermi level.
     752              : !!          if ewind /= 0 ==> a band is considered in the plot of FSurf
     753              : !!                            only if it is inside [ ef-ewind, ef+ewind ] for some k point
     754              : !!          if ewind == 0 ==> all bands will be keept in the _BXSF file
     755              : !!  fermie = Fermi energy (Hartree)
     756              : !!  gprimd(3,3) = dimensional primitive translations for reciprocal space (bohr^-1)
     757              : !!  kptrlatt(3,3) = reciprocal of lattice vectors for full kpoint grid
     758              : !!  mband = maximum number of bands
     759              : !!  nsppol = 1 for unpolarized, 2 for spin-polarized
     760              : !!  shiftk(3,nshiftk) =shift vector for k point grid
     761              : !!  fname = filename for the fortran file
     762              : !!  symafm(nsym)=(Anti)ferromagnetic symmetries.
     763              : !!  use_afm=.TRUE. if (anti)ferromagnetic symmetries are used.
     764              : !!
     765              : !! OUTPUT
     766              : !!  ierr=Status error.
     767              : !!  BXSF file.
     768              : !!
     769              : !! SOURCE
     770              : 
     771            0 : subroutine printvtk(eigen,v_surf,ewind,fermie,gprimd,kptrlatt,mband,&
     772            0 : & nkptirred,kptirred,nsym,use_afm,symrec,symafm,use_tr,nsppol,shiftk,nshiftk,fname,ierr)
     773              : 
     774              : 
     775              : !Arguments ------------------------------------
     776              : !scalars
     777              :  integer,intent(in) :: mband,nkptirred,nshiftk,nsppol,nsym
     778              :  integer,intent(out) :: ierr
     779              :  real(dp),intent(in) :: ewind,fermie
     780              :  logical,intent(in) :: use_afm,use_tr
     781              :  character(len=*),intent(in) :: fname
     782              : !arrays
     783              :  integer,intent(in) :: kptrlatt(3,3),symafm(nsym),symrec(3,3,nsym)
     784              :  real(dp),intent(in) :: eigen(mband,nkptirred,nsppol),gprimd(3,3)
     785              :  real(dp),intent(in) :: v_surf(mband,kptrlatt(1,1)+1,kptrlatt(2,2)+1,kptrlatt(3,3)+1,3,nsppol)
     786              :  real(dp),intent(in) :: kptirred(3,nkptirred),shiftk(3,nshiftk)
     787              : 
     788              : !Local variables-------------------------------
     789              : !scalars
     790              :  integer :: iband,ikgrid,ikpt1,indx
     791              :  integer :: ikpt,jkpt,kkpt,ikpt_fine, ik1, ik2, ik3
     792              :  integer :: isppol,isym,itim,maxband,minband,nk1,nk2,nk3,nkptfull,uvtk,timrev
     793              :  real(dp) :: ene,res,ss,timsign
     794              :  logical :: found
     795              :  character(len=500) :: msg, format_str
     796              : !arrays
     797            0 :  integer,allocatable :: fulltoirred(:)
     798              :  real(dp) :: kconv(3),kpt(3),kptgrid(3),kptsym(3)
     799              : ! *************************************************************************
     800              : 
     801            0 :  ierr=0
     802              : 
     803              : !Error if klatt is no simple orthogonal lattice (in red space)
     804              : !for generalization to MP grids, need new version of XCrysDen
     805              : 
     806              :  if (kptrlatt(1,2)/=0 .or. kptrlatt(1,3)/=0 .or. kptrlatt(2,1)/=0 .or. &
     807            0 :      kptrlatt(2,3)/=0 .or. kptrlatt(3,1)/=0 .or. kptrlatt(3,2)/=0 ) then
     808              :    write(msg,'(3a)')&
     809            0 :     'kptrlatt should be diagonal, for the FS calculation ',ch10,&
     810            0 :     'action: use an orthogonal k-grid for the GS calculation '
     811            0 :    ABI_COMMENT(msg)
     812            0 :    ierr=ierr+1
     813              :  end if
     814              : 
     815            0 :  if (ANY(ABS(shiftk(:,:))>tol10)) then
     816              :    write(msg,'(3a)')&
     817            0 :     'Origin of the k-grid should be (0,0,0) for the FS calculation ',ch10,&
     818            0 :     'Action: use a non-shifted k-grid for the GS calculation. Returning '
     819            0 :    ABI_COMMENT(msg)
     820            0 :    ierr=ierr+1
     821              :  end if
     822              : 
     823            0 :  if (ierr/=0) RETURN
     824              : 
     825              :  ! Xcrysden uses aperiodical data-grid
     826            0 :  nk1 = kptrlatt(1,1)
     827            0 :  nk2 = kptrlatt(2,2)
     828            0 :  nk3 = kptrlatt(3,3)
     829            0 :  nkptfull=(nk1+1)*(nk2+1)*(nk3+1)
     830              : 
     831            0 :  ABI_MALLOC(fulltoirred,(nkptfull))
     832            0 :  timrev=0; if (use_tr) timrev=1
     833              : 
     834              :  !Xcrysden employs C-ordering for the Fermi Surface.
     835            0 :  ierr = 0
     836            0 :  ikgrid=0
     837            0 :  do ik1=0,nk1
     838            0 :    do ik2=0,nk2
     839            0 :      do ik3=0,nk3
     840              : 
     841            0 :        ikgrid=ikgrid+1
     842            0 :        kptgrid(1)=DBLE(ik1)/kptrlatt(1,1)
     843            0 :        kptgrid(2)=DBLE(ik2)/kptrlatt(2,2)
     844            0 :        kptgrid(3)=DBLE(ik3)/kptrlatt(3,3)
     845            0 :        call wrap2_pmhalf(kptgrid(1),kpt(1),res)
     846            0 :        call wrap2_pmhalf(kptgrid(2),kpt(2),res)
     847            0 :        call wrap2_pmhalf(kptgrid(3),kpt(3),res)
     848              : 
     849              :        ! === Find correspondence between the Xcrysden grid and the IBZ ===
     850              :        ! If AFM case, use only Ferromagetic symmetries.
     851            0 :        found=.FALSE.
     852            0 :        irred: do ikpt1=1,nkptirred
     853            0 :          do itim=0,timrev
     854            0 :            do isym=1,nsym
     855            0 :              if (use_afm.and.symafm(isym)==-1) CYCLE
     856            0 :              timsign = one-two*itim
     857              :              kptsym(:) = timsign*(symrec(:,1,isym)*kptirred(1,ikpt1) + &
     858              :                                   symrec(:,2,isym)*kptirred(2,ikpt1) + &
     859            0 :                                   symrec(:,3,isym)*kptirred(3,ikpt1))
     860            0 :              call wrap2_pmhalf(kptsym(1),kconv(1),res)
     861            0 :              call wrap2_pmhalf(kptsym(2),kconv(2),res)
     862            0 :              call wrap2_pmhalf(kptsym(3),kconv(3),res)
     863              :              ! is kconv equivalent to kpt?
     864            0 :              ss= (kpt(1)-kconv(1))**2 + (kpt(2)-kconv(2))**2 + (kpt(3)-kconv(3))**2
     865            0 :              if (ss < tol6) then
     866            0 :                found=.TRUE.
     867            0 :                fulltoirred(ikgrid)=ikpt1
     868              :                exit irred
     869              :              end if
     870              : 
     871              :            end do !itim
     872              :          end do !isym
     873              :        end do irred
     874              : 
     875            0 :        if (.not.found) then
     876              :          write(msg,'(a,3es16.8,2a)')&
     877            0 :           ' kpt = ',kpt,ch10,' has no symmetric among the irred k-points used in the GS calculation '
     878            0 :          ierr=ierr+1
     879            0 :          ABI_ERROR(msg)
     880              :        end if
     881              : 
     882              :      end do !ik1
     883              :    end do !ik2
     884              :  end do !ik3
     885              : 
     886            0 :  if (ierr/=0) then
     887            0 :    ABI_FREE(fulltoirred)
     888            0 :    RETURN
     889              :  end if
     890              : 
     891            0 :  if (abs(ewind) < tol12 ) then
     892              :    ! Keep all bands.
     893              :    minband=1
     894              :    maxband=mband
     895              :  else
     896              :    ! Select a subset of bands.
     897              :    minband = mband
     898              :    maxband = 0
     899              :    ene=abs(ewind)
     900            0 :    do isppol=1,nsppol
     901            0 :      do iband=1,mband
     902            0 :        if(minval(eigen(iband,:,isppol))-fermie < -ene) then
     903            0 :          minband = iband
     904              :        end if
     905              :      end do
     906            0 :      do iband=mband,1,-1
     907            0 :        if (maxval(eigen(iband,:,isppol))-fermie > ene) then
     908            0 :          maxband = iband
     909              :        end if
     910              :      end do
     911              :    end do ! isppol
     912              : 
     913              :  end if ! abs(energy_window)
     914              : 
     915              :  ! Dump the results on file ===
     916            0 :  if (open_file(fname,msg,newunit=uvtk,status='unknown',form='formatted') /= 0) then
     917            0 :    ABI_FREE(fulltoirred)
     918            0 :    ABI_WARNING(msg)
     919            0 :    ierr=ierr +1; RETURN
     920              :  end if
     921              : 
     922              :  ! write header
     923            0 :  write(uvtk,"(a)") '# vtk DataFile Version 2.0'
     924            0 :  write(uvtk,"(a)") 'Eigen values for the Fermi surface'
     925            0 :  write(uvtk,"(a)") 'ASCII'
     926            0 :  write(uvtk,*) ''
     927            0 :  write(uvtk,"(a)") 'DATASET STRUCTURED_GRID'
     928            0 :  write(uvtk,"(a,3i6)") 'DIMENSIONS', nk1+1,nk2+1,nk3+1
     929            0 :  write(uvtk,"(a,i6,a)") 'POINTS',nkptfull,' float'
     930              : 
     931            0 :  do ik3 = 0, nk3
     932            0 :    do ik2 = 0, nk2
     933            0 :      do ik1 = 0, nk1
     934              :        write(uvtk,'(3es16.8)') dble(ik1)/nk1*gprimd(1,1)+ &
     935              :                                dble(ik2)/nk2*gprimd(1,2)+ &
     936            0 :                                dble(ik3)/nk3*gprimd(1,3), &
     937              :                                dble(ik1)/nk1*gprimd(2,1)+ &
     938              :                                dble(ik2)/nk2*gprimd(2,2)+ &
     939            0 :                                dble(ik3)/nk3*gprimd(2,3), &
     940              :                                dble(ik1)/nk1*gprimd(3,1)+ &
     941              :                                dble(ik2)/nk2*gprimd(3,2)+ &
     942            0 :                                dble(ik3)/nk3*gprimd(3,3)
     943              :      end do
     944              :    end do
     945              :  end do
     946              : 
     947              : !print out data for all relevant bands and full kpt grid (redundant, yes)
     948              : !for each kpt in full zone, find equivalent irred kpt and print eigenval
     949            0 :  write(uvtk,*) ''
     950            0 :  write(uvtk,"(a,i6)") 'POINT_DATA',nkptfull
     951            0 :  indx=0
     952            0 :  do iband=minband,maxband
     953            0 :    do isppol=1,nsppol
     954            0 :      if (minband+indx < 10) then
     955            0 :        format_str="(a14,i1,1X,a)"
     956              :      else
     957            0 :        format_str="(a14,i2,1X,a)"
     958              :      end if
     959            0 :      write(uvtk,format_str) 'SCALARS eigval', minband+indx, 'float 1'
     960            0 :      write(uvtk,"(a)") 'LOOKUP_TABLE default'
     961            0 :      write(uvtk,*) ' '
     962            0 :      do kkpt = nk3/2+1, nk3+nk3/2+1
     963            0 :        do jkpt = nk2/2+1, nk2+nk2/2+1
     964            0 :          do ikpt = nk1/2+1, nk1+nk1/2+1
     965            0 :            ik1 = ikpt
     966            0 :            ik2 = jkpt
     967            0 :            ik3 = kkpt
     968            0 :            if (ikpt > nk1+1) ik1 = ikpt - nk1
     969            0 :            if (jkpt > nk2+1) ik2 = jkpt - nk2
     970            0 :            if (kkpt > nk3+1) ik3 = kkpt - nk3
     971              : !          get the index with zyx order
     972            0 :            ikpt_fine = (ik1-1)*(nk2+1)*(nk3+1) + (ik2-1)*(nk3+1) + ik3
     973            0 :            write(uvtk,'(es16.8)') eigen(iband,fulltoirred(ikpt_fine),isppol)
     974              :          end do
     975              :        end do
     976              :      end do
     977            0 :      indx=indx+1
     978              :    end do
     979              :  end do
     980              : 
     981            0 :  write(uvtk,*) ''
     982            0 :  indx=0
     983            0 :  do iband=minband,maxband
     984            0 :    do isppol=1,nsppol
     985            0 :      if (minband+indx < 10) then
     986            0 :        format_str="(a10,i1,1X,a)"
     987              :      else
     988            0 :        format_str="(a10,i2,1X,a)"
     989              :      end if
     990            0 :      write(uvtk,format_str) 'SCALARS ve', minband+indx, 'float'
     991            0 :      write(uvtk,"(a)") 'LOOKUP_TABLE default'
     992            0 :      write(uvtk,*) ' '
     993            0 :      do kkpt = nk3/2+1, nk3+nk3/2+1
     994            0 :        do jkpt = nk2/2+1, nk2+nk2/2+1
     995            0 :          do ikpt = nk1/2+1, nk1+nk1/2+1
     996            0 :            ik1 = ikpt
     997            0 :            ik2 = jkpt
     998            0 :            ik3 = kkpt
     999            0 :            if (ikpt > nk1+1) ik1 = ikpt - nk1
    1000            0 :            if (jkpt > nk2+1) ik2 = jkpt - nk2
    1001            0 :            if (kkpt > nk3+1) ik3 = kkpt - nk3
    1002              : !          write(uvtk,'(3i6,3es16.8)') ik1,ik2,ik3,v_surf(iband,ik1,ik2,ik3,1,isppol), &
    1003              : !          &                                                 v_surf(iband,ik1,ik2,ik3,2,isppol), &
    1004              : !          &                                                 v_surf(iband,ik1,ik2,ik3,3,isppol)
    1005              :            write(uvtk,'(es16.8)') sqrt(v_surf(iband,ik1,ik2,ik3,1,isppol)*v_surf(iband,ik1,ik2,ik3,1,isppol)+ &
    1006              : &           v_surf(iband,ik1,ik2,ik3,2,isppol)*v_surf(iband,ik1,ik2,ik3,2,isppol)+ &
    1007            0 : &           v_surf(iband,ik1,ik2,ik3,3,isppol)*v_surf(iband,ik1,ik2,ik3,3,isppol))
    1008              :          end do
    1009              :        end do
    1010              :      end do
    1011            0 :      write(uvtk,format_str) 'SCALARS vx', minband+indx, 'float'
    1012            0 :      write(uvtk,"(a)") 'LOOKUP_TABLE default'
    1013            0 :      write(uvtk,*) ' '
    1014            0 :      do kkpt = nk3/2+1, nk3+nk3/2+1
    1015            0 :        do jkpt = nk2/2+1, nk2+nk2/2+1
    1016            0 :          do ikpt = nk1/2+1, nk1+nk1/2+1
    1017            0 :            ik1 = ikpt
    1018            0 :            ik2 = jkpt
    1019            0 :            ik3 = kkpt
    1020            0 :            if (ikpt > nk1+1) ik1 = ikpt - nk1
    1021            0 :            if (jkpt > nk2+1) ik2 = jkpt - nk2
    1022            0 :            if (kkpt > nk3+1) ik3 = kkpt - nk3
    1023            0 :            write(uvtk,'(es16.8)') v_surf(iband,ik1,ik2,ik3,1,isppol)
    1024              :          end do
    1025              :        end do
    1026              :      end do
    1027            0 :      write(uvtk,format_str) 'SCALARS vy', minband+indx, 'float'
    1028            0 :      write(uvtk,"(a)") 'LOOKUP_TABLE default'
    1029            0 :      write(uvtk,*) ' '
    1030            0 :      do kkpt = nk3/2+1, nk3+nk3/2+1
    1031            0 :        do jkpt = nk2/2+1, nk2+nk2/2+1
    1032            0 :          do ikpt = nk1/2+1, nk1+nk1/2+1
    1033            0 :            ik1 = ikpt
    1034            0 :            ik2 = jkpt
    1035            0 :            ik3 = kkpt
    1036            0 :            if (ikpt > nk1+1) ik1 = ikpt - nk1
    1037            0 :            if (jkpt > nk2+1) ik2 = jkpt - nk2
    1038            0 :            if (kkpt > nk3+1) ik3 = kkpt - nk3
    1039            0 :            write(uvtk,'(es16.8)') v_surf(iband,ik1,ik2,ik3,2,isppol)
    1040              :          end do
    1041              :        end do
    1042              :      end do
    1043            0 :      write(uvtk,format_str) 'SCALARS vz', minband+indx, 'float'
    1044            0 :      write(uvtk,"(a)") 'LOOKUP_TABLE default'
    1045            0 :      write(uvtk,*) ' '
    1046            0 :      do kkpt = nk3/2+1, nk3+nk3/2+1
    1047            0 :        do jkpt = nk2/2+1, nk2+nk2/2+1
    1048            0 :          do ikpt = nk1/2+1, nk1+nk1/2+1
    1049            0 :            ik1 = ikpt
    1050            0 :            ik2 = jkpt
    1051            0 :            ik3 = kkpt
    1052            0 :            if (ikpt > nk1+1) ik1 = ikpt - nk1
    1053            0 :            if (jkpt > nk2+1) ik2 = jkpt - nk2
    1054            0 :            if (kkpt > nk3+1) ik3 = kkpt - nk3
    1055            0 :            write(uvtk,'(es16.8)') v_surf(iband,ik1,ik2,ik3,3,isppol)
    1056              :          end do
    1057              :        end do
    1058              :      end do
    1059            0 :      indx=indx+1
    1060              :    end do
    1061              :  end do
    1062              : 
    1063            0 :  close (uvtk)
    1064            0 :  ABI_FREE(fulltoirred)
    1065              : 
    1066              : end subroutine printvtk
    1067              : !!***
    1068              : 
    1069              : END MODULE m_pptools
        

Generated by: LCOV version 2.3-1