LCOV - code coverage report
Current view: top level - src/72_response - m_orbmag.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 88.4 % 1185 1048
Test Date: 2026-09-21 13:49:52 Functions: 83.9 % 31 26

            Line data    Source code
       1              : !!*** ABINIT/m_orbmag
       2              : !! NAME
       3              : !!  m_orbmag
       4              : !!
       5              : !! FUNCTION
       6              : !!  This module contains the declaration of data types and methods
       7              : !!  used to handle orbital magnetization
       8              : !!
       9              : !! COPYRIGHT
      10              : !! Copyright (C) 2011-2026 ABINIT group (JWZ)
      11              : !! This file is distributed under the terms of the
      12              : !! GNU General Public License, see ~abinit/COPYING
      13              : !! or http://www.gnu.org/copyleft/gpl.txt .
      14              : !!
      15              : !! NOTES
      16              : !! These routines implement the theory developed in Zwanziger, Torrent, Gonze
      17              : !! Phys Rev B 107, 165157 (2023). This paper will be referred to in the comments as ZTG23.
      18              : !!
      19              : !! SOURCE
      20              : 
      21              : #if defined HAVE_CONFIG_H
      22              : #include "config.h"
      23              : #endif
      24              : 
      25              : #include "abi_common.h"
      26              : 
      27              : ! note: in a typical index over lmn2_size, think of it as row ilmn, column jlmn for element d_ij.
      28              : ! In pawinit line 356, klmn is constructed such that ilmn <= jlmn. Thus we have the upper triangular
      29              : ! part of the dij matrix. When looping over both ilmn and jlmn, element dij with i>j is constructed
      30              : ! by symmetry from element dji.
      31              : #define MATPACK(row,col) (MAX(row,col)*(MAX(row,col)-1)/2 + MIN(row,col))
      32              : 
      33              : #define EPSABG(i,j,k) (((i - j) * (j - k) * (k - i)) / 2)
      34              : 
      35              : module m_orbmag
      36              : 
      37              :   use defs_basis
      38              :   use m_errors
      39              :   use m_abicore
      40              :   use m_xmpi
      41              :   use m_dtset
      42              : 
      43              :   use defs_datatypes,     only : pseudopotential_type
      44              :   use defs_abitypes,      only : MPI_type
      45              :   use m_crystal,          only : crystal_t
      46              :   use m_cgprj,            only : getcprj
      47              :   use m_cgtools,          only : cg_zdotc,cg_zdotu,projbd
      48              :   use m_dtfil
      49              :   use m_ebands
      50              :   use m_fft,              only : fourwf
      51              :   use m_getghc,           only : getghc
      52              :   use m_getgh1c
      53              :   use m_hamiltonian
      54              :   use m_hdr
      55              :   use m_kg,               only : getph,mkkin,mkkpg,ph1d3d
      56              :   use m_mkffnl,           only : mkffnl
      57              :   use m_mpinfo,           only : proc_distrb_cycle,proc_distrb_nband
      58              :   use m_nctk
      59              :   use netcdf
      60              :   use m_nonlop,           only : nonlop
      61              :   use m_pawcprj,          only : pawcprj_type, pawcprj_alloc, pawcprj_free,pawcprj_getdim, pawcprj_get, pawcprj_put
      62              :   use m_pawdij,           only : pawv1
      63              :   use m_pawfgr,           only : pawfgr_type
      64              :   use m_pawfgrtab,        only : pawfgrtab_type
      65              :   use m_paw_ij,           only : paw_ij_type
      66              :   use m_pawrad,           only : nderiv_gen,pawrad_type,pawrad_deducer0,simp_gen,poisson
      67              :   use m_paw_sphharm,      only : setsym_ylm,slxyzs,realgaunt,make_dyadic
      68              :   use m_pawtab,           only : pawtab_type
      69              :   use m_spacepar,         only : make_vectornd
      70              :   use m_time,             only : cwtime, timab
      71              : 
      72              :   implicit none
      73              : 
      74              :   ! these parameters name the various output terms
      75              :   integer,parameter :: chern_nterms=2
      76              :   integer,parameter :: ibcc=1,ibvv1=2
      77              :   integer,parameter :: orbmag_nterms=6
      78              :   integer,parameter :: incc=1,invv1=2,invv2=3
      79              :   integer,parameter :: innl=4,inlr=5,inbm=6
      80              : 
      81              :   ! these parameters are constants used repeatedly
      82              : 
      83              :   ! accounts for exp(i k.r) in abinit derivatives rather than exp( 2pi i k.r)
      84              :   real(dp),parameter :: c2=one/(two_pi*two_pi)
      85              :   complex(dp),parameter :: com=-half*j_dpc  ! Orbital magnetism pre-factor
      86              :   complex(dp),parameter :: cbc=-com ! Berry curvature pre-factor
      87              : 
      88              :   ! local datatype for orbmag data on kpt mesh, for eventual output to netcdf
      89              :   type,private :: orbmag_mesh_type
      90              :     ! scalars
      91              : 
      92              :     integer :: mband, nkpt, nsppol
      93              :     ! number of bands, kpts, spin polarizations
      94              : 
      95              :     integer :: natom, ntypat
      96              :     ! atoms and types of atoms
      97              : 
      98              :     integer :: chern_nterms
      99              :     ! number of chern terms to store on the kpt mesh
     100              :     ! CC, VV1, VV2
     101              : 
     102              :     integer :: orbmag_nterms
     103              :     ! number of orbmag terms to store on the kpt mesh
     104              :     ! CC, VV1, VV2, NL, L_R, B.M
     105              : 
     106              :     integer :: n4,n5,n6
     107              :     ! real space grid dimenions for rmesh
     108              : 
     109              :     real(dp),allocatable :: lambsig(:)
     110              :     ! lambsig(ntypat)
     111              : 
     112              :     real(dp),allocatable :: nucdipmom(:,:)
     113              :     ! nucdipmom(3,natom)
     114              : 
     115              :     real(dp),allocatable :: cmesh(:,:,:,:,:)
     116              :     ! 3 for the 3 directions
     117              :     ! cmesh(mband,nkpt,nsppol,3,chern_terms)
     118              :     
     119              :     real(dp),allocatable :: chern_terms(:,:,:,:)
     120              :     ! 3 for the 3 directions
     121              :     ! chern_terms(dtset%mband,dtset%nsppol,3,chern_nterms)
     122              : 
     123              :     real(dp),allocatable :: chern_trace(:,:)
     124              :     ! 3 for the 3 directions
     125              :     ! chern_trace(3,chern_nterms)
     126              : 
     127              :     real(dp),allocatable :: omesh(:,:,:,:,:)
     128              :     ! 3 for the 3 directions
     129              :     ! omesh(mband,nkpt,nsppol,3,orbmag_terms)
     130              :     
     131              :     real(dp),allocatable :: orbmag_terms(:,:,:,:)
     132              :     ! 3 for the 3 directions
     133              :     ! orbmag_terms(dtset%mband,dtset%nsppol,3,orbmag_nterms)
     134              :     
     135              :     real(dp),allocatable :: orbmag_trace(:,:)
     136              :     ! 3 for the 3 directions
     137              :     ! orbmag_trace(3,orbmag_nterms)
     138              :     
     139              :     real(dp),allocatable :: rmesh(:,:,:,:,:)
     140              :     ! total orbmag on real mesh
     141              :     ! 3 for the 3 directions
     142              :     ! rmesh(n4,n5,n6,3,orbmag_nterms)
     143              :     
     144              :     real(dp),allocatable :: rmesh_int(:,:)
     145              :     ! integrated orbmag on real mesh, useful for checking
     146              :     ! 3 for the 3 directions
     147              :     ! rmesh_int(3,orbmag_nterms)
     148              : 
     149              :     contains
     150              : 
     151              :       procedure :: init => orbmag_init
     152              :       procedure :: free => orbmag_free
     153              :       procedure :: mpisum => orbmag_mpisum
     154              :       procedure :: term_scale => orbmag_term_scale
     155              :       procedure :: output => orbmag_output
     156              : 
     157              :   end type orbmag_mesh_type
     158              : 
     159              :   ! local datatype for various onsite terms. Probably overkill, but convenient.
     160              :   type,private :: dterm_type
     161              :     ! scalars
     162              :     integer :: lmnmax
     163              :     integer :: lmn2max
     164              :     integer :: natom
     165              :     integer :: ndij
     166              :     integer :: has_aij=0
     167              :     integer :: has_qij=0
     168              :     integer :: has_LR=0
     169              :     integer :: has_BM=0
     170              : 
     171              :     ! sum of \Delta A_ij
     172              :     ! typically will be just paw_ij
     173              :     ! aij(natom,lmn2max,ndij)
     174              :     complex(dp),allocatable :: aij(:,:,:)
     175              : 
     176              :     ! <phi|phi> - <tphi|tphi>
     177              :     ! qij(natom,lmn2max,ndij)
     178              :     complex(dp),allocatable :: qij(:,:,:)
     179              : 
     180              :     ! onsite L_R/2
     181              :     ! <phi|L_R/2|phi> - <tphi|L_R/2|tphi>
     182              :     ! ebk_LR(2*lmn2max,natom,ndij,3)
     183              :     real(dp),allocatable :: ekb_LR(:,:,:,:)
     184              : 
     185              :     ! ebk_BM(2*lmn2max,natom,ndij,3)
     186              :     real(dp),allocatable :: ekb_BM(:,:,:,:)
     187              : 
     188              :     contains
     189              : 
     190              :       procedure :: init => dterm_init
     191              :       procedure :: free => dterm_free
     192              : 
     193              :   end type dterm_type
     194              : 
     195              :   ! Bound methods:
     196              : 
     197              :   public :: orbmag
     198              :   public :: orbmag_ncpp
     199              : 
     200              :   private :: orbmag_cc_k
     201              :   private :: orbmag_cc_k_ncpp
     202              :   private :: orbmag_vv_k
     203              :   private :: orbmag_nl_k
     204              :   private :: nonlop_orbmag_nl
     205              :   private :: orbmag_nl1_k
     206              :   private :: me_proj_mesh
     207              : !  private :: cprj_test
     208              :   private :: make_d
     209              :   private :: dterm_aij
     210              :   private :: dterm_qij
     211              :   private :: dterm_LR
     212              :   private :: dterm_BM
     213              :   private :: local_fermie
     214              : 
     215              :   private :: lamb_core
     216              :   private :: make_pcg1
     217              :   private :: gauge_treatment
     218              :   private :: para_to_diag
     219              :   private :: orbmag_init
     220              :   private :: orbmag_free
     221              :   private :: orbmag_mpisum
     222              :   private :: orbmag_term_scale
     223              :   private :: orbmag_output
     224              :   private :: orbmag_ncwrite   ! Write orbmag_mesh contributions to netcdf file.
     225              :   private :: dterm_init
     226              :   private :: dterm_free
     227              : 
     228              : CONTAINS  !========================================================================================
     229              : !!***
     230              : 
     231              : !!****f* ABINIT/orbmag_ncpp
     232              : !! NAME
     233              : !! orbmag_ncpp
     234              : !!
     235              : !! FUNCTION
     236              : !! This routine computes the orbital magnetization and Berry curvature based on input
     237              : !! wavefunctions and DDK wavefuntions, specialized for NCPP
     238              : !!
     239              : !! INPUTS
     240              : !!  cg(2,mcg)=all ground state wavefunctions
     241              : !!  cg1(2,mcg1,3)=all DDK wavefunctions in all 3 directions
     242              : !!  cprj(dtset%natom,mcprj)<type(pawcprj_type)>=all ground state cprj
     243              : !!  crystal(crystal_t)=structured datatype holding details about unit cell
     244              : !!  dtfil <type(datafiles_type)>=variables related to files
     245              : !!  dtset <type(dataset_type)>=all input variables for this dataset
     246              : !!  ebands_k(ebands_t)=structured datatype holding GS eigenvalues
     247              : !!  gsqcut=large sphere cut-off
     248              : !!  hdr(hdr_type)=structured dataype with header info for eventual output
     249              : !!  kg(3,mpw*mkmem_rbz)=basis sphere of planewaves at k
     250              : !!  mcg=dimension of cg
     251              : !!  mcg1=dimension of cg1
     252              : !!  mcprj=dimension of cprj
     253              : !!  mkmem_rbz=kpts in memory
     254              : !!  mpi_enreg<type(MPI_type)>=information about MPI parallelization
     255              : !!  mpw=max number of planewaves at k
     256              : !!  nfftf=(effective) number of FFT grid points (for this proc) for the "fine" grid (see NOTES in respfn.F90)
     257              : !!  ngfftf(18)=FFT grid size information (from pawfgr%ngfft)
     258              : !!  paw_ij(dtset%natom) <type(paw_ij_type)>=paw arrays given on (i,j) channels for the GS
     259              : !!  pawfgr <type(pawfgr_type)>=fine grid parameters and related data
     260              : !!  pawrad(dtset%ntypat) <type(pawrad_type)>=paw radial mesh and related data
     261              : !!  pawtab(dtset%ntypat) <type(pawtab_type)>=paw tabulated starting data
     262              : !!  psps <type(pseudopotential_type)>=variables related to pseudopotentials
     263              : !!  rprimd(3,3)=real space translation vectors
     264              : !!  usevxctau=1 if kinetic energy density contribution has to be included (mGGA)
     265              : !!  vtrial(nfftf,dtset%nspden)=GS potential (Hartree)
     266              : !!  vxctau(nfftf,nspden,4*usevxctau)=derivative of e_xc with respect to kinetic energy density, for mGGA
     267              : !!  ylm(mpw*mkmem_rbz,psps%mpsang*psps%mpsang*psps%useylm)=all ylm's
     268              : !!  ylmgr(mpw*mkmem_rbz,3,psps%mpsang*psps%mpsang*psps%useylm)=gradients of ylm's
     269              : !!
     270              : !! OUTPUT
     271              : !!  only printing in call to orbmag_output
     272              : !!
     273              : !! SIDE EFFECTS
     274              : !!
     275              : !! TODO
     276              : !!
     277              : !! NOTES
     278              : !! See Zwanziger, Torrent, and Gonze Phys Rev B 107, 165157 (2023), "ZTG23"
     279              : !! DDK wavefunctions are used for the derivatives.
     280              : !!
     281              : !! SOURCE
     282              : 
     283            1 : subroutine orbmag_ncpp(cg,cg1,dtfil,dtset,crystal,ebands_k,kg,gsqcut,hdr,&
     284            1 :     & mcg,mcg1,mkmem_rbz,mpi_enreg,mpw,nfftf,ngfftf,pawfgr,pawtab,psps,&
     285            1 :     & usevxctau,vtrial,vxctau)
     286              : 
     287              :  !Arguments ------------------------------------
     288              :  !scalars
     289              :  integer,intent(in) :: mcg,mcg1,mkmem_rbz,mpw,nfftf,usevxctau
     290              :  real(dp),intent(in) :: gsqcut
     291              :  type(crystal_t),intent(in) :: crystal
     292              :  type(datafiles_type), intent(in) :: dtfil
     293              :  type(dataset_type),intent(in) :: dtset
     294              :  type(ebands_t),intent(in) :: ebands_k
     295              :  type(hdr_type),intent(in) :: hdr
     296              :  type(MPI_type), intent(inout) :: mpi_enreg
     297              :  type(pawfgr_type),intent(in) :: pawfgr
     298              :  type(pseudopotential_type), intent(in) :: psps
     299              : 
     300              :  !arrays
     301              :  integer,intent(in) :: kg(3,mpw*mkmem_rbz),ngfftf(18)
     302              :  real(dp),intent(in) :: cg(2,mcg),cg1(2,mcg1,3)
     303              :  real(dp),intent(inout) :: vtrial(nfftf,dtset%nspden)
     304              :  real(dp),intent(inout) :: vxctau(nfftf,dtset%nspden,4*usevxctau)
     305              :  type(pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw)
     306              : 
     307              :  !Local
     308              :  !scalars
     309              :  character(len=fnlen) :: fname
     310              :  integer :: bdtot_index,dimffnl,exchn2n3d,iatom,icg,ider,idir,ikg,ikg1,ikpt
     311              :  integer :: indx,isppol,istwf_k,itypat
     312              :  integer :: mcgk,me,my_nspinor,nband_k,nband_me,ncid
     313              :  integer :: ngfft1,ngfft2,ngfft3,ngfft4,ngfft5,ngfft6
     314              :  integer :: nkpg,nn,nproc,npw_k,npwsp,nucdip_dirs,spaceComm,usecprj_local=0
     315              :  integer,parameter :: master=0
     316              :  real(dp) :: ecut_eff,fermie
     317              :  logical :: has_nucdip
     318            1 :  type(gs_hamiltonian_type) :: gs_hamk
     319            1 :  type(orbmag_mesh_type) :: orbmag_mesh
     320              : 
     321              :  !arrays
     322            1 :  integer,allocatable :: atindx(:),atindx1(:),kg_k(:,:),nattyp(:)
     323              :  real(dp) :: kpoint(3),omlamb(3)
     324            1 :  real(dp),allocatable :: cg1_k(:,:,:),eig_k(:)
     325            1 :  real(dp),allocatable,target :: cg_k(:,:)
     326            1 :  real(dp),allocatable :: ffnl_k(:,:,:,:),kinpw(:),kpg_k(:,:),occ_k(:),ph1d(:,:),ph3d(:,:,:)
     327            1 :  real(dp),allocatable :: trnrm(:),vlocal(:,:,:,:),vectornd(:,:,:),vectornd_pac(:,:,:,:,:)
     328            1 :  real(dp),allocatable :: vxctaulocal(:,:,:,:,:),ylm_k(:,:),ylmgr_k(:,:,:)
     329            1 :  type(paw_ij_type),allocatable :: ncpp_paw_ij(:)
     330              : 
     331              :  !----------------------------------------------
     332              : 
     333              :  ! set up basic FFT parameters
     334            1 :  my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor)
     335            1 :  istwf_k = 1
     336            1 :  spaceComm=mpi_enreg%comm_cell
     337            1 :  nproc=xmpi_comm_size(spaceComm)
     338            1 :  me = mpi_enreg%me_kpt
     339            1 :  ngfft1=dtset%ngfft(1) ; ngfft2=dtset%ngfft(2) ; ngfft3=dtset%ngfft(3)
     340            1 :  ngfft4=dtset%ngfft(4) ; ngfft5=dtset%ngfft(5) ; ngfft6=dtset%ngfft(6)
     341            1 :  ecut_eff = dtset%ecut*(dtset%dilatmx)**2
     342            1 :  exchn2n3d = 0; ikg1 = 0
     343              : 
     344              :  ! Fermi energy
     345            1 :  call local_fermie(dtset,ebands_k,fermie,mpi_enreg)
     346              : 
     347              :  ! initialize orbmag_mesh datatype
     348            1 :  call orbmag_mesh%init(dtset)
     349           10 :  orbmag_mesh%nucdipmom=dtset%nucdipmom
     350              :  ! if user input lambsig specifically in the input file, use it
     351            3 :  if ( any ( abs(dtset%lambsig).GT.tol8 ) ) then
     352            0 :    orbmag_mesh%lambsig=dtset%lambsig
     353              :  ! else use the value read in to pawtab structure (which might well be zero)
     354            1 :  else if (psps%usepaw .EQ. 1) then
     355            0 :    orbmag_mesh%lambsig=pawtab(1:dtset%ntypat)%lamb_shielding
     356              :  else
     357            3 :    orbmag_mesh%lambsig=zero
     358              :  end if
     359              : 
     360              : 
     361              :  !Definition of atindx array
     362              :  !Generate an index table of atoms, in order for them to be used type after type.
     363            3 :  ABI_MALLOC(atindx,(dtset%natom))
     364            2 :  ABI_MALLOC(atindx1,(dtset%natom))
     365            3 :  ABI_MALLOC(nattyp,(psps%ntypat))
     366            3 :  indx=1
     367            3 :  do itypat=1,psps%ntypat
     368            2 :    nattyp(itypat)=0
     369            7 :    do iatom=1,dtset%natom
     370            6 :      if(dtset%typat(iatom)==itypat)then
     371            2 :        atindx(iatom)=indx
     372            2 :        atindx1(indx)=iatom
     373            2 :        indx=indx+1
     374            2 :        nattyp(itypat)=nattyp(itypat)+1
     375              :      end if
     376              :    end do
     377              :  end do
     378              : 
     379            1 :  ABI_MALLOC(ncpp_paw_ij,(0))
     380            3 :  ABI_MALLOC(ph1d,(2,3*(2*dtset%mgfft+1)*dtset%natom))
     381            1 :  call getph(atindx,dtset%natom,ngfft1,ngfft2,ngfft3,ph1d,crystal%xred)
     382              : 
     383              :  !==== Initialize most of the Hamiltonian ====
     384              :  !Allocate all arrays and initialize quantities that do not depend on k and spin.
     385              :  !gs_hamk is the normal hamiltonian at k
     386              :  call gs_hamk%init(psps,pawtab,dtset%nspinor,dtset%nsppol,dtset%nspden,dtset%natom,&
     387              :       & dtset%typat,crystal%xred,dtset%nfft,dtset%mgfft,dtset%ngfft,crystal%rprimd,&
     388              :       & dtset%nloalg,paw_ij=ncpp_paw_ij,ph1d=ph1d,usecprj=usecprj_local,&
     389            1 :       & nucdipmom=dtset%nucdipmom)
     390              : 
     391              :  ! iterate over spin channels
     392            1 :  bdtot_index=0
     393            1 :  icg = 0
     394            2 :  do isppol = 1, dtset%nsppol
     395              : 
     396              :    !========= construct local potential ==================
     397            6 :    ABI_MALLOC(vlocal,(ngfft4,ngfft5,ngfft6,gs_hamk%nvloc))
     398              :    call gspot_transgrid_and_pack(isppol, psps%usepaw, dtset%paral_kgb, dtset%nfft, dtset%ngfft, nfftf, &
     399            1 :      & dtset%nspden, gs_hamk%nvloc, 1, pawfgr, mpi_enreg, vtrial, vlocal)
     400            1 :    call gs_hamk%load_spin(isppol,vlocal=vlocal,with_nonlocal=.true.)
     401              : 
     402              :    !========  compute nuclear dipole vector potential (may be zero) ==========
     403            5 :    has_nucdip = ANY( ABS(dtset%nucdipmom) .GT. tol8 )
     404            1 :    if(has_nucdip) then
     405            1 :      nucdip_dirs=3
     406            5 :      ABI_MALLOC(vectornd,(nfftf,dtset%nspden,nucdip_dirs))
     407        12295 :      vectornd = zero
     408              :      call make_vectornd(1,gsqcut,psps%usepaw,mpi_enreg,dtset%natom,nfftf,ngfftf,&
     409            1 :        & dtset%nspden,dtset%nucdipmom,crystal%rprimd,vectornd,crystal%xred)
     410            7 :      ABI_MALLOC(vectornd_pac,(ngfft4,ngfft5,ngfft6,gs_hamk%nvloc,nucdip_dirs))
     411              :      call gspot_transgrid_and_pack(isppol, psps%usepaw, dtset%paral_kgb, dtset%nfft, dtset%ngfft, nfftf, &
     412            1 :           & dtset%nspden, gs_hamk%nvloc, nucdip_dirs, pawfgr, mpi_enreg, vectornd,vectornd_pac)
     413            1 :      ABI_FREE(vectornd)
     414            1 :      call gs_hamk%load_spin(isppol,vectornd=vectornd_pac)
     415              :    else
     416            0 :      nucdip_dirs=0
     417              :    end if
     418              : 
     419              :  !  !========  compute vxctaulocal if vxctau present =====================
     420              : 
     421            1 :    if (usevxctau==1) then
     422            0 :      ABI_MALLOC(vxctaulocal,(ngfft4,ngfft5,ngfft6,gs_hamk%nvloc,4))
     423              :      call gspot_transgrid_and_pack(isppol, psps%usepaw, dtset%paral_kgb, dtset%nfft, dtset%ngfft, nfftf, &
     424            0 :        & dtset%nspden, gs_hamk%nvloc, 4, pawfgr, mpi_enreg, vxctau, vxctaulocal)
     425            0 :      call gs_hamk%load_spin(isppol, vxctaulocal=vxctaulocal)
     426              :    end if
     427              : 
     428            1 :    ikg = 0
     429              :    !============= BIG FAT KPT LOOP :) ===========================
     430           33 :    do ikpt = 1, dtset%nkpt
     431              : 
     432           32 :      nband_k=dtset%nband(ikpt+(isppol-1)*dtset%nkpt)
     433           32 :      nband_me = proc_distrb_nband(mpi_enreg%proc_distrb,ikpt,nband_k,isppol,me)
     434              : 
     435              :      ! if the current kpt is not on the current processor, cycle
     436           32 :      if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me)) then
     437           32 :        bdtot_index=bdtot_index+nband_k
     438              :        cycle
     439              :      end if
     440              : 
     441          128 :      kpoint(:)=ebands_k%kptns(:,ikpt)
     442           32 :      npw_k = ebands_k%npwarr(ikpt)
     443           32 :      npwsp = npw_k*dtset%nspinor
     444              : 
     445              :      ! retrieve kg_k at this k point
     446           96 :      ABI_MALLOC(kg_k,(3,npw_k))
     447        18752 :      kg_k(1:3,1:npw_k) = kg(1:3,ikg+1:ikg+npw_k)
     448              : 
     449              :      ! retrieve ylm at this k point
     450          128 :      ABI_MALLOC(ylm_k,(npw_k,psps%mpsang*psps%mpsang*psps%useylm))
     451          128 :      ABI_MALLOC(ylmgr_k,(npw_k,3,psps%mpsang*psps%mpsang*psps%useylm))
     452              : 
     453              :      ! retrieve occupation numbers at this k point
     454           96 :      ABI_MALLOC(occ_k,(nband_k))
     455          160 :      occ_k(:)=ebands_k%occ(1:nband_k,ikpt,isppol)
     456              : 
     457              :      ! Compute kinetic energy at kpt
     458           96 :      ABI_MALLOC(kinpw,(npw_k))
     459         4712 :      kinpw(:) = zero
     460              :      call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,crystal%gmet,&
     461           32 :        & kg_k,kinpw,kpoint,npw_k,0,0)
     462              : 
     463              :      ! Compute k+G at this k point (relevant only for useylm=1)
     464           32 :      nkpg=3*dtset%optforces*dtset%nloalg(3)
     465          128 :      ABI_MALLOC(kpg_k,(npw_k,nkpg))
     466           32 :      call mkkpg(kg_k,kpg_k,kpoint,nkpg,npw_k)
     467              : 
     468          128 :      ABI_MALLOC(ph3d,(2,npw_k,dtset%natom))
     469              : 
     470              :  !   Compute nonlocal form factors ffnl at all (k+G):
     471           32 :      ider=0;idir=0;dimffnl=1
     472          160 :      ABI_MALLOC(ffnl_k,(npw_k,dimffnl,psps%lmnmax,dtset%ntypat))
     473              :      call mkffnl(psps%dimekb,dimffnl,psps%ekb,ffnl_k,psps%ffspl,&
     474              :        & crystal%gmet,crystal%gprimd,ider,idir,psps%indlmn,&
     475              :        & kg_k,kpg_k,kpoint,psps%lmnmax,&
     476              :        & psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg,&
     477              :        & npw_k,dtset%ntypat,psps%pspso,psps%qgrid_ff,crystal%rmet,&
     478           32 :        & psps%usepaw,psps%useylm,ylm_k,ylmgr_k,kinpw=kinpw)
     479              :      !  - Load k-dependent quantities in the Hamiltonian
     480              :      call gs_hamk%load_k(kpt_k=kpoint(:),istwf_k=istwf_k,npw_k=npw_k,&
     481              :        & kinpw_k=kinpw,kg_k=kg_k,kpg_k=kpg_k,ffnl_k=ffnl_k,ph3d_k=ph3d,&
     482           32 :        & compute_ph3d=.TRUE.,compute_gbound=(mpi_enreg%paral_kgb.NE.1))
     483              : 
     484           32 :      ABI_SFREE(ylm_k)
     485           32 :      ABI_SFREE(ylmgr_k)
     486              :      
     487              :      ! retrieve ground state wavefunctions at this k point and isppol
     488           32 :      mcgk = npw_k*nband_k*dtset%nspinor
     489           96 :      ABI_MALLOC(cg_k,(2,mcgk))
     490        56224 :      cg_k = cg(1:2,icg+1:icg+mcgk)
     491              : 
     492              :      ! retrieve first order wavefunctions at this k point and isppol
     493          128 :      ABI_MALLOC(cg1_k,(2,mcgk,3))
     494       168640 :      cg1_k = cg1(1:2,icg+1:icg+mcgk,1:3)
     495              : 
     496              :      ! retrieve zeroth order eigenvalues at this k point and isppol
     497           64 :      ABI_MALLOC(eig_k,(nband_k))
     498          160 :      eig_k(:)=ebands_k%eig(1:nband_k,ikpt,isppol)
     499              : 
     500              :      ! set up normalization factors at this k point
     501           64 :      ABI_MALLOC(trnrm,(nband_k))
     502          160 :      trnrm(1:nband_k) = ebands_k%occ(1:nband_k,ikpt,isppol)*dtset%wtk(ikpt)/crystal%ucvol
     503              : 
     504              :      !--------------------------------------------------------------------------------
     505              :      ! Finally ready to compute contributions to orbital magnetism and Berry curvature
     506              :      !--------------------------------------------------------------------------------
     507              : 
     508              :      ! ZTG23 Eq. 36 term 2 and Eq. 46 term 1
     509              :      call orbmag_cc_k_ncpp(dtset,eig_k,fermie,cg1_k,gs_hamk,ikpt,isppol,&
     510           32 :        & mcgk,mpi_enreg,nband_k,npw_k,orbmag_mesh)
     511              : 
     512              :      ! accumulate terms
     513          160 :      do nn = 1, nband_k
     514          128 :        if(abs(trnrm(nn)).LT.tol8) cycle
     515              :        orbmag_mesh%chern_terms(nn,isppol,1:3,ibcc:ibvv1) = orbmag_mesh%chern_terms(nn,isppol,1:3,ibcc:ibvv1) + &
     516         2176 :            & trnrm(nn)*orbmag_mesh%cmesh(nn,ikpt,isppol,1:3,ibcc:ibvv1)
     517              :        orbmag_mesh%orbmag_terms(nn,isppol,1:3,incc:inbm) = orbmag_mesh%orbmag_terms(nn,isppol,1:3,incc:inbm) + &
     518         6304 :            & trnrm(nn)*orbmag_mesh%omesh(nn,ikpt,isppol,1:3,incc:inbm)
     519              :      end do ! loop on bands
     520              : 
     521           32 :      icg = icg + mcgk
     522           32 :      ikg = ikg + npw_k
     523           32 :      bdtot_index=bdtot_index+nband_k
     524              : 
     525           32 :      ABI_SFREE(ffnl_k)
     526           32 :      ABI_SFREE(ph3d)
     527           32 :      ABI_SFREE(kpg_k)
     528           32 :      ABI_SFREE(kg_k)
     529           32 :      ABI_SFREE(kinpw)
     530           32 :      ABI_SFREE(cg_k)
     531           32 :      ABI_SFREE(cg1_k)
     532           32 :      ABI_SFREE(eig_k)
     533           32 :      ABI_SFREE(occ_k)
     534           33 :      ABI_SFREE(trnrm)
     535              : 
     536              :    end do ! end loop over kpts
     537              : 
     538            1 :    ABI_SFREE(vlocal)
     539            1 :    ABI_SFREE(vectornd_pac)
     540            2 :    ABI_SFREE(vxctaulocal)
     541              : 
     542              :  end do ! end loop over isppol
     543              : 
     544              :  ! accumulate data over processors
     545            1 :  call orbmag_mesh%mpisum(nproc,spaceComm)
     546              :  
     547              :  ! prepare terms for output to abo file
     548            1 :  call orbmag_mesh%term_scale(crystal,dtset)
     549              : 
     550              :  ! get the Lamb term
     551            1 :  call lamb_core(atindx,dtset,omlamb,pawtab,psps%usepaw)
     552              : 
     553              :  ! output raw data to netcdf file for more detailed postprocessing
     554            1 :  if (me == master) then
     555            1 :    fname = trim(dtfil%filnam_ds(4))//'_ORBMAG.nc'
     556            1 :    NCF_CHECK(nctk_open_create(ncid, fname, xmpi_comm_self))
     557            1 :    call orbmag_ncwrite(crystal,dtset,ebands_k,hdr,ncid,orbmag_mesh)
     558            1 :    NCF_CHECK(nf90_close(ncid))
     559              :  end if
     560              : 
     561              :  ! output summary to abo file
     562            1 :  call orbmag_mesh%output(dtset,omlamb)
     563              : 
     564              : !!---------------------------------------------------
     565              : !! deallocate memory
     566              : !!---------------------------------------------------
     567              : 
     568            1 :  call gs_hamk%free()
     569            1 :  call orbmag_mesh%free()
     570            1 :  ABI_SFREE(ncpp_paw_ij)
     571            1 :  ABI_SFREE(ph1d)
     572            1 :  ABI_SFREE(atindx)
     573            1 :  ABI_SFREE(atindx1)
     574            1 :  ABI_SFREE(nattyp)
     575              : 
     576              : 
     577            2 : end subroutine orbmag_ncpp
     578              : !!***
     579              : 
     580              : 
     581              : !!****f* ABINIT/orbmag
     582              : !! NAME
     583              : !! orbmag
     584              : !!
     585              : !! FUNCTION
     586              : !! This routine computes the orbital magnetization and Berry curvature based on input
     587              : !! wavefunctions and DDK wavefuntions.
     588              : !!
     589              : !! INPUTS
     590              : !!  cg(2,mcg)=all ground state wavefunctions
     591              : !!  cg1(2,mcg1,3)=all DDK wavefunctions in all 3 directions
     592              : !!  cprj(dtset%natom,mcprj)<type(pawcprj_type)>=all ground state cprj
     593              : !!  crystal(crystal_t)=structured datatype holding details about unit cell
     594              : !!  dtfil <type(datafiles_type)>=variables related to files
     595              : !!  dtset <type(dataset_type)>=all input variables for this dataset
     596              : !!  ebands_k(ebands_t)=structured datatype holding GS eigenvalues
     597              : !!  gsqcut=large sphere cut-off
     598              : !!  hdr(hdr_type)=structured dataype with header info for eventual output
     599              : !!  kg(3,mpw*mkmem_rbz)=basis sphere of planewaves at k
     600              : !!  mcg=dimension of cg
     601              : !!  mcg1=dimension of cg1
     602              : !!  mcprj=dimension of cprj
     603              : !!  mkmem_rbz=kpts in memory
     604              : !!  mpi_enreg<type(MPI_type)>=information about MPI parallelization
     605              : !!  mpw=max number of planewaves at k
     606              : !!  nfftf=(effective) number of FFT grid points (for this proc) for the "fine" grid (see NOTES in respfn.F90)
     607              : !!  ngfftf(18)=FFT grid size information (from pawfgr%ngfft)
     608              : !!  paw_ij(dtset%natom) <type(paw_ij_type)>=paw arrays given on (i,j) channels for the GS
     609              : !!  pawfgr <type(pawfgr_type)>=fine grid parameters and related data
     610              : !!  pawrad(dtset%ntypat) <type(pawrad_type)>=paw radial mesh and related data
     611              : !!  pawtab(dtset%ntypat) <type(pawtab_type)>=paw tabulated starting data
     612              : !!  psps <type(pseudopotential_type)>=variables related to pseudopotentials
     613              : !!  rprimd(3,3)=real space translation vectors
     614              : !!  usevxctau=1 if kinetic energy density contribution has to be included (mGGA)
     615              : !!  vtrial(nfftf,dtset%nspden)=GS potential (Hartree)
     616              : !!  vxctau(nfftf,nspden,4*usevxctau)=derivative of e_xc with respect to kinetic energy density, for mGGA
     617              : !!  ylm(mpw*mkmem_rbz,psps%mpsang*psps%mpsang*psps%useylm)=all ylm's
     618              : !!  ylmgr(mpw*mkmem_rbz,3,psps%mpsang*psps%mpsang*psps%useylm)=gradients of ylm's
     619              : !!
     620              : !! OUTPUT
     621              : !!  only printing in call to orbmag_output
     622              : !!
     623              : !! SIDE EFFECTS
     624              : !!
     625              : !! TODO
     626              : !!
     627              : !! NOTES
     628              : !! See Zwanziger, Torrent, and Gonze Phys Rev B 107, 165157 (2023), "ZTG23"
     629              : !! DDK wavefunctions are used for the derivatives.
     630              : !!
     631              : !! SOURCE
     632              : 
     633           16 : subroutine orbmag(cg,cg1,cprj,crystal,dtfil,dtset,ebands_k,gsqcut,hdr,kg,mcg,mcg1,&
     634           16 :     & mcprj,mkmem_rbz,mpi_enreg,mpw,nfftf,ngfftf,paw_ij,pawfgr,pawrad,&
     635           16 :     & pawtab,psps,usevxctau,vtrial,vxctau,ylm,ylmgr)
     636              : 
     637              :  !Arguments ------------------------------------
     638              :  !scalars
     639              :  integer,intent(in) :: mcprj,mcg,mcg1,mkmem_rbz,mpw,nfftf,usevxctau
     640              :  real(dp),intent(in) :: gsqcut
     641              :  type(crystal_t),intent(in) :: crystal
     642              :  type(datafiles_type), intent(in) :: dtfil
     643              :  type(dataset_type),intent(in) :: dtset
     644              :  type(ebands_t),intent(in) :: ebands_k
     645              :  type(hdr_type),intent(in) :: hdr
     646              :  type(MPI_type), intent(inout) :: mpi_enreg
     647              :  type(pawfgr_type),intent(in) :: pawfgr
     648              :  type(pseudopotential_type), intent(in) :: psps
     649              : 
     650              :  !arrays
     651              :  integer,intent(in) :: kg(3,mpw*mkmem_rbz),ngfftf(18)
     652              :  real(dp),intent(in) :: cg(2,mcg),cg1(2,mcg1,3)
     653              :  real(dp),intent(inout) :: vtrial(nfftf,dtset%nspden)
     654              :  real(dp),intent(inout) :: vxctau(nfftf,dtset%nspden,4*usevxctau)
     655              :  real(dp),intent(in) :: ylm(mpw*mkmem_rbz,psps%mpsang*psps%mpsang*psps%useylm)
     656              :  real(dp),intent(in) :: ylmgr(mpw*mkmem_rbz,3,psps%mpsang*psps%mpsang*psps%useylm)
     657              :  type(pawcprj_type),intent(in) ::  cprj(dtset%natom,mcprj)
     658              :  type(paw_ij_type),intent(inout) :: paw_ij(dtset%natom*psps%usepaw)
     659              :  type(pawrad_type),intent(in) :: pawrad(dtset%ntypat*psps%usepaw)
     660              :  type(pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw)
     661              : 
     662              :  !Local
     663              :  !scalars
     664              :  character(len=fnlen) :: fname
     665              :  integer :: adir,bdtot_index,choice,cpopt,dimffnl,exchn2n3d
     666              :  integer :: iat,iatom,icg,icprj,ider,idir
     667              :  integer :: ikg,ikg1,ikpt,ilm,indx,isppol,istwf_k,itypat,lmn2max
     668              :  integer :: me,mcgk,mcprjk,my_nspinor,nband_k,nband_me,ncid,ngfft1,ngfft2,ngfft3,ngfft4
     669              :  integer :: ngfft5,ngfft6,nn,nkpg,npw_k,npwsp,nproc,nucdip_dirs,spaceComm
     670              :  integer,parameter :: master=0
     671              :  real(dp) :: arg,ecut_eff,fermie
     672              :  logical :: has_nucdip
     673           16 :  type(dterm_type) :: dterm
     674           16 :  type(gs_hamiltonian_type) :: gs_hamk
     675           16 :  type(orbmag_mesh_type) :: orbmag_mesh
     676              : 
     677              :  !arrays
     678           16 :  integer,allocatable :: atindx(:),atindx1(:),dimlmn(:),kg_k(:,:),nattyp(:)
     679              :  real(dp) :: kpoint(3),omlamb(3)
     680           16 :  real(dp),allocatable :: cg1_k(:,:,:),cwavef(:,:),dkinpw(:,:),eig_k(:)
     681           16 :  real(dp),allocatable :: ffnl_k(:,:,:,:),kinpw(:),kpg_k(:,:),occ_k(:)
     682           16 :  real(dp),allocatable,target :: cg_k(:,:),gcg1_k(:,:,:)
     683           16 :  real(dp),allocatable,target :: ph1d(:,:)
     684           16 :  real(dp),allocatable :: ph3d(:,:,:),phkxred(:,:),trnrm(:)
     685           16 :  real(dp),allocatable :: vectornd(:,:,:),vectornd_pac(:,:,:,:,:),vlocal(:,:,:,:)
     686           16 :  real(dp),allocatable :: vxctaulocal(:,:,:,:,:)
     687           16 :  real(dp),allocatable :: ylm_k(:,:),ylmgr_k(:,:,:)
     688           16 :  type(pawcprj_type),allocatable :: cprj_k(:,:),cprj1_k(:,:,:),cwaveprj(:,:)
     689              : 
     690              :  !----------------------------------------------
     691              : 
     692              :  ! set up basic FFT parameters
     693           16 :  my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor)
     694           16 :  istwf_k = 1
     695           16 :  spaceComm=mpi_enreg%comm_cell
     696           16 :  nproc=xmpi_comm_size(spaceComm)
     697           16 :  me = mpi_enreg%me_kpt
     698           16 :  ngfft1=dtset%ngfft(1) ; ngfft2=dtset%ngfft(2) ; ngfft3=dtset%ngfft(3)
     699           16 :  ngfft4=dtset%ngfft(4) ; ngfft5=dtset%ngfft(5) ; ngfft6=dtset%ngfft(6)
     700           16 :  ecut_eff = dtset%ecut*(dtset%dilatmx)**2
     701           16 :  exchn2n3d = 0; ikg1 = 0
     702              : 
     703              :  ! Fermi energy
     704           16 :  call local_fermie(dtset,ebands_k,fermie,mpi_enreg)
     705              : 
     706              :  !Definition of atindx array
     707              :  !Generate an index table of atoms, in order for them to be used type after type.
     708           48 :  ABI_MALLOC(atindx,(dtset%natom))
     709           32 :  ABI_MALLOC(atindx1,(dtset%natom))
     710           48 :  ABI_MALLOC(nattyp,(psps%ntypat))
     711           16 :  indx=1
     712           44 :  do itypat=1,psps%ntypat
     713           28 :    nattyp(itypat)=0
     714           96 :    do iatom=1,dtset%natom
     715           80 :      if(dtset%typat(iatom)==itypat)then
     716           28 :        atindx(iatom)=indx
     717           28 :        atindx1(indx)=iatom
     718           28 :        indx=indx+1
     719           28 :        nattyp(itypat)=nattyp(itypat)+1
     720              :      end if
     721              :    end do
     722              :  end do
     723              : 
     724           48 :  ABI_MALLOC(ph1d,(2,3*(2*dtset%mgfft+1)*dtset%natom))
     725           16 :  call getph(atindx,dtset%natom,ngfft1,ngfft2,ngfft3,ph1d,crystal%xred)
     726              : 
     727           48 :  ABI_MALLOC(kg_k,(3,mpw))
     728           48 :  ABI_MALLOC(kinpw,(mpw))
     729           16 :  if (abs(dtset%orbmag) .EQ. 3) then
     730            0 :    ABI_MALLOC(dkinpw,(mpw,3))
     731              :  end if
     732              : 
     733           32 :  ABI_MALLOC(dimlmn,(dtset%natom))
     734           16 :  call pawcprj_getdim(dimlmn,dtset%natom,nattyp,dtset%ntypat,dtset%typat,pawtab,'O')
     735              : 
     736          120 :  ABI_MALLOC(cwaveprj,(dtset%natom,dtset%nspinor))
     737           16 :  call pawcprj_alloc(cwaveprj,0,dimlmn)
     738              : 
     739           16 :  lmn2max = psps%lmnmax*(psps%lmnmax+1)/2
     740              :  ! note: in make_d, terms will be filled as iatom using atindx
     741           16 :  call dterm%init(psps%lmnmax,lmn2max,dtset%natom,paw_ij(1)%ndij)
     742           16 :  call make_d(atindx,dterm,dtset,crystal%gprimd,paw_ij,pawrad,pawtab,psps)
     743              : 
     744              :  ! initialize orbmag_mesh datatype
     745           16 :  call orbmag_mesh%init(dtset)
     746          144 :  orbmag_mesh%nucdipmom=dtset%nucdipmom
     747              :  ! if user input lambsig specifically in the input file, use it
     748           32 :  if ( any ( abs(dtset%lambsig).GT.tol8 ) ) then
     749           46 :    orbmag_mesh%lambsig=dtset%lambsig
     750              :  ! else use the value read in to pawtab structure (which might well be zero)
     751              :  else
     752           14 :    orbmag_mesh%lambsig=pawtab(1:dtset%ntypat)%lamb_shielding
     753              :  end if
     754              : 
     755              :  !==== Initialize most of the Hamiltonian ====
     756              :  !Allocate all arrays and initialize quantities that do not depend on k and spin.
     757              :  !gs_hamk is the normal hamiltonian at k
     758              :  call gs_hamk%init(psps,pawtab,dtset%nspinor,dtset%nsppol,dtset%nspden,dtset%natom,&
     759              :       & dtset%typat,crystal%xred,dtset%nfft,dtset%mgfft,dtset%ngfft,crystal%rprimd,&
     760           16 :       & dtset%nloalg,nucdipmom=dtset%nucdipmom,paw_ij=paw_ij)
     761              : 
     762              :  ! iterate over spin channels
     763           16 :  bdtot_index=0
     764           16 :  icg = 0
     765           16 :  icprj = 0
     766           33 :  do isppol = 1, dtset%nsppol
     767              : 
     768              :    !========= construct local potential ==================
     769          102 :    ABI_MALLOC(vlocal,(ngfft4,ngfft5,ngfft6,gs_hamk%nvloc))
     770              :    call gspot_transgrid_and_pack(isppol, psps%usepaw, dtset%paral_kgb, dtset%nfft, dtset%ngfft, nfftf, &
     771           17 :      & dtset%nspden, gs_hamk%nvloc, 1, pawfgr, mpi_enreg, vtrial, vlocal)
     772           17 :    call gs_hamk%load_spin(isppol,vlocal=vlocal,with_nonlocal=.true.)
     773              : 
     774              :    !========  compute nuclear dipole vector potential (may be zero) ==========
     775           69 :    has_nucdip = ANY( ABS(dtset%nucdipmom) .GT. tol8 )
     776           17 :    if(has_nucdip) then
     777           17 :      nucdip_dirs=3
     778           85 :      ABI_MALLOC(vectornd,(nfftf,dtset%nspden,nucdip_dirs))
     779      4309757 :      vectornd = zero
     780              :      call make_vectornd(1,gsqcut,psps%usepaw,mpi_enreg,dtset%natom,nfftf,ngfftf,&
     781           17 :        & dtset%nspden,dtset%nucdipmom,crystal%rprimd,vectornd,crystal%xred)
     782          119 :      ABI_MALLOC(vectornd_pac,(ngfft4,ngfft5,ngfft6,gs_hamk%nvloc,nucdip_dirs))
     783              :      call gspot_transgrid_and_pack(isppol, psps%usepaw, dtset%paral_kgb, dtset%nfft, dtset%ngfft, nfftf, &
     784           17 :           & dtset%nspden, gs_hamk%nvloc, nucdip_dirs, pawfgr, mpi_enreg, vectornd,vectornd_pac)
     785           17 :      ABI_FREE(vectornd)
     786           17 :      call gs_hamk%load_spin(isppol,vectornd=vectornd_pac)
     787              :    else
     788            0 :      nucdip_dirs=0
     789              :    end if
     790              : 
     791              :    !========  compute vxctaulocal if vxctau present =====================
     792              : 
     793           17 :    if (usevxctau==1) then
     794           14 :      ABI_MALLOC(vxctaulocal,(ngfft4,ngfft5,ngfft6,gs_hamk%nvloc,4))
     795              :      call gspot_transgrid_and_pack(isppol, psps%usepaw, dtset%paral_kgb, dtset%nfft, dtset%ngfft, nfftf, &
     796            2 :        & dtset%nspden, gs_hamk%nvloc, 4, pawfgr, mpi_enreg, vxctau, vxctaulocal)
     797            2 :      call gs_hamk%load_spin(isppol, vxctaulocal=vxctaulocal)
     798              :    end if
     799              : 
     800           17 :    ikg = 0
     801              :    !============= BIG FAT KPT LOOP :) ===========================
     802          692 :    do ikpt = 1, dtset%nkpt
     803              : 
     804          675 :      nband_k=dtset%nband(ikpt+(isppol-1)*dtset%nkpt)
     805          675 :      nband_me = proc_distrb_nband(mpi_enreg%proc_distrb,ikpt,nband_k,isppol,me)
     806              : 
     807              :      ! if the current kpt is not on the current processor, cycle
     808          675 :      if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me)) then
     809          675 :        bdtot_index=bdtot_index+nband_k
     810              :        cycle
     811              :      end if
     812              : 
     813         2700 :      kpoint(:)=ebands_k%kptns(:,ikpt)
     814          675 :      npw_k = ebands_k%npwarr(ikpt)
     815          675 :      npwsp = npw_k*dtset%nspinor
     816              : 
     817              :      ! retrieve kg_k at this k point
     818       516967 :      kg_k(1:3,1:npw_k) = kg(1:3,ikg+1:ikg+npw_k)
     819              : 
     820              :      ! retrieve ylm at this k point
     821         2700 :      ABI_MALLOC(ylm_k,(npw_k,psps%mpsang*psps%mpsang))
     822         2700 :      ABI_MALLOC(ylmgr_k,(npw_k,3,psps%mpsang*psps%mpsang*psps%useylm))
     823         3375 :      do ilm=1,psps%mpsang*psps%mpsang
     824       518992 :        ylm_k(1:npw_k,ilm)=ylm(1+ikg:npw_k+ikg,ilm)
     825      1560351 :        ylmgr_k(1:npw_k,1:3,ilm)=ylmgr(1+ikg:npw_k+ikg,1:3,ilm)
     826              :      end do
     827              : 
     828              :      ! retrieve occupation numbers at this k point
     829         2025 :      ABI_MALLOC(occ_k,(nband_k))
     830              :      !occ_k(:)=occ(1+bdtot_index:nband_k+bdtot_index)
     831         4911 :      occ_k(:)=ebands_k%occ(1:nband_k,ikpt,isppol)
     832              : 
     833              :      ! Compute kinetic energy at kpt
     834       132460 :      kinpw(:) = zero
     835              :      call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,crystal%gmet,&
     836          675 :        & kg_k,kinpw,kpoint,npw_k,0,0)
     837          675 :      if (abs(dtset%orbmag).EQ.3) then
     838            0 :        do adir=1,3
     839              :          call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,crystal%gmet,&
     840            0 :            & kg_k,dkinpw(:,adir),kpoint,npw_k,adir,0)
     841              :        end do
     842              :      end if
     843              : 
     844              :      ! Compute k+G at this k point
     845          675 :      nkpg = 3
     846         2700 :      ABI_MALLOC(kpg_k,(npw_k,nkpg))
     847          675 :      call mkkpg(kg_k,kpg_k,kpoint,nkpg,npw_k)
     848              : 
     849              :      ! Make 3d phase factors
     850         2025 :      ABI_MALLOC(phkxred,(2,dtset%natom))
     851         1766 :      do iat = 1, dtset%natom
     852         1091 :        iatom = atindx(iat)
     853         4364 :        arg=two_pi*DOT_PRODUCT(kpoint,crystal%xred(:,iat))
     854         1766 :        phkxred(1,iatom)=DCOS(arg);phkxred(2,iatom)=DSIN(arg)
     855              :      end do
     856         2700 :      ABI_MALLOC(ph3d,(2,npw_k,dtset%natom))
     857              :      call ph1d3d(1,dtset%natom,kg_k,dtset%natom,dtset%natom,&
     858          675 :        & npw_k,ngfft1,ngfft2,ngfft3,phkxred,ph1d,ph3d)
     859              : 
     860              :      ! Compute nonlocal form factors ffnl at all (k+G):
     861          675 :      ider=1 ! ffnl and 1st derivatives
     862          675 :      idir=4 ! ignored when ider = 0; idir=0 means d ffnl/ dk in reduced units referenced
     863              :             ! to reciprocal translations
     864              :             ! idir=4 meand d ffnl / dk in reduced units referenced to real space
     865              :             ! translations. rfddk = 1 wavefunctions are computed using this convention.
     866          675 :      dimffnl=4 ! 1 + number of derivatives
     867         4050 :      ABI_MALLOC(ffnl_k,(npw_k,dimffnl,psps%lmnmax,dtset%ntypat))
     868              :      call mkffnl(psps%dimekb,dimffnl,psps%ekb,ffnl_k,psps%ffspl,&
     869              :        & crystal%gmet,crystal%gprimd,ider,idir,psps%indlmn,&
     870              :        & kg_k,kpg_k,kpoint,psps%lmnmax,&
     871              :        & psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg,&
     872              :        & npw_k,dtset%ntypat,psps%pspso,psps%qgrid_ff,crystal%rmet,&
     873          675 :        & psps%usepaw,psps%useylm,ylm_k,ylmgr_k)
     874              :      !  - Load k-dependent quantities in the Hamiltonian
     875              :      call gs_hamk%load_k(kpt_k=kpoint(:),istwf_k=istwf_k,npw_k=npw_k,&
     876              :        & kinpw_k=kinpw,kg_k=kg_k,kpg_k=kpg_k,ffnl_k=ffnl_k,ph3d_k=ph3d,&
     877          675 :        & compute_gbound=.TRUE.)
     878              : 
     879          675 :      ABI_SFREE(ylm_k)
     880          675 :      ABI_SFREE(ylmgr_k)
     881              :      
     882              :      ! retrieve ground state wavefunctions at this k point and isppol
     883          675 :      mcgk = npw_k*nband_k*dtset%nspinor
     884         2025 :      ABI_MALLOC(cg_k,(2,mcgk))
     885      2664978 :      cg_k = cg(1:2,icg+1:icg+mcgk)
     886              : 
     887              :      ! retrieve first order wavefunctions at this k point and isppol
     888         2700 :      ABI_MALLOC(cg1_k,(2,mcgk,3))
     889      7994259 :      cg1_k = cg1(1:2,icg+1:icg+mcgk,1:3)
     890              : 
     891              :      ! retrieve zeroth order eigenvalues at this k point and isppol
     892         1350 :      ABI_MALLOC(eig_k,(nband_k))
     893              :      !eig_k(:)=eigen0(1+bdtot_index:nband_k+bdtot_index)
     894         4911 :      eig_k(:)=ebands_k%eig(1:nband_k,ikpt,isppol)
     895              : 
     896              :      ! retrieve cprj_k at this k point and isppol
     897          675 :      mcprjk = nband_k*dtset%nspinor
     898        16420 :      ABI_MALLOC(cprj_k,(dtset%natom,mcprjk))
     899          675 :      call pawcprj_alloc(cprj_k,cprj(1,1)%ncpgr,dimlmn)
     900              :      call pawcprj_get(atindx,cprj_k,cprj,dtset%natom,1,icprj,ikpt,0,isppol,dtset%mband,&
     901          675 :        & mkmem_rbz,dtset%natom,nband_k,nband_k,dtset%nspinor,dtset%nsppol,0)
     902              : 
     903              :      ! gauge treatment of cg1_k
     904         1350 :      ABI_MALLOC(gcg1_k,(2,mcgk,3))
     905              :      call gauge_treatment(atindx,cg_k,cg1_k,cprj_k,dimlmn,dkinpw,dtset,eig_k,gcg1_k,gs_hamk,&
     906              :          & ikpt,isppol,mcgk,mcprjk,mkmem_rbz,mpi_enreg,mpw,nband_k,ngfft4,ngfft5,ngfft6,npw_k,&
     907          675 :          & nucdip_dirs,occ_k,vectornd_pac)
     908              :      
     909              :      ! compute <p|gcg1> cprjs
     910        46560 :      ABI_MALLOC(cprj1_k,(dtset%natom,mcprjk,3))
     911         2700 :      do adir = 1, 3
     912         2700 :        call pawcprj_alloc(cprj1_k(:,:,adir),0,dimlmn)
     913              :      end do
     914          675 :      choice = 1
     915          675 :      cpopt = 0
     916          675 :      idir = 0
     917         2025 :      ABI_MALLOC(cwavef,(2,npwsp))
     918         4911 :      do nn = 1, nband_k
     919        17619 :        do adir = 1, 3
     920      8003592 :          cwavef(1:2,1:npwsp) = gcg1_k(1:2,(nn-1)*npwsp+1:nn*npwsp,adir)
     921              :          call getcprj(choice,cpopt,cwavef,cwaveprj,gs_hamk%ffnl_k,idir,&
     922              :            & psps%indlmn,istwf_k,kg_k,gs_hamk%kpg_k,kpoint,psps%lmnmax,dtset%mgfft,&
     923              :            & mpi_enreg,1,dtset%natom,nattyp,dtset%ngfft,dtset%nloalg,npw_k,&
     924              :            & dtset%nspinor,dtset%ntypat,phkxred,ph1d,gs_hamk%ph3d_k,&
     925        12708 :            & crystal%ucvol,psps%useylm)
     926              :          call pawcprj_put(atindx,cwaveprj,cprj1_k(:,:,adir),dtset%natom,&
     927              :            & nn,0,ikpt,0,isppol,dtset%mband,mkmem_rbz,dtset%natom,1,nband_k,&
     928        16944 :            & dimlmn,dtset%nspinor,dtset%nsppol,0)
     929              :        end do
     930              :      end do
     931          675 :      ABI_SFREE(cwavef)
     932          675 :      ABI_SFREE(phkxred)
     933              : 
     934              :      ! set up normalization factors at this k point
     935         1350 :      ABI_MALLOC(trnrm,(nband_k))
     936         4911 :      trnrm(1:nband_k) = ebands_k%occ(1:nband_k,ikpt,isppol)*dtset%wtk(ikpt)/crystal%ucvol
     937              : 
     938              :      !--------------------------------------------------------------------------------
     939              :      ! Finally ready to compute contributions to orbital magnetism and Berry curvature
     940              :      !--------------------------------------------------------------------------------
     941              : 
     942              :      ! ZTG23 Eq. 36 term 2 and Eq. 46 term 1
     943              :      call orbmag_cc_k(atindx,cprj1_k,dimlmn,dtset,eig_k,fermie,gcg1_k,gs_hamk,ikpt,isppol,&
     944          675 :        & mcgk,mcprjk,mkmem_rbz,mpi_enreg,nband_k,npw_k,orbmag_mesh,trnrm)
     945              : 
     946              :      ! ZTG23 Eq. 36 terms 3 and 4 and Eq. 46 term 2
     947              :      call orbmag_vv_k(atindx,cg_k,cprj_k,dimlmn,dtset,eig_k,fermie,gcg1_k,gs_hamk,ikpt,isppol,&
     948          675 :        & mcgk,mcprjk,mkmem_rbz,mpi_enreg,nband_k,npw_k,orbmag_mesh,trnrm)
     949              : 
     950              :      ! ZTG23 Eq. 36 term 1
     951              :      call orbmag_nl_k(atindx,cg_k,cprj_k,dimlmn,dterm,dtset,eig_k,gs_hamk,ikpt,isppol,&
     952          675 :        & mcgk,mcprjk,mkmem_rbz,mpi_enreg,nband_k,npw_k,orbmag_mesh,pawtab,trnrm)
     953              : 
     954              :      ! ZTG23 text after Eq. 42
     955              :      ! <L_R> contribution
     956              :      call orbmag_nl1_k(atindx,cg_k,cprj_k,dimlmn,dterm,dtset,gs_hamk,ikpt,inlr,isppol,&
     957          675 :        & mcgk,mcprjk,mkmem_rbz,mpi_enreg,nband_k,npw_k,orbmag_mesh,trnrm)
     958              : 
     959              :      ! ZTG23 Eq. 43
     960              :      ! A0.An contribution
     961              :      call orbmag_nl1_k(atindx,cg_k,cprj_k,dimlmn,dterm,dtset,gs_hamk,ikpt,inbm,isppol,&
     962          675 :        & mcgk,mcprjk,mkmem_rbz,mpi_enreg,nband_k,npw_k,orbmag_mesh,trnrm)
     963              : 
     964              :      ! accumulate terms
     965         4911 :      do nn = 1, nband_k
     966         4236 :        if(abs(trnrm(nn)).LT.tol8) cycle
     967              :        orbmag_mesh%chern_terms(nn,isppol,1:3,ibcc:ibvv1) = orbmag_mesh%chern_terms(nn,isppol,1:3,ibcc:ibvv1) + &
     968        57290 :            & trnrm(nn)*orbmag_mesh%cmesh(nn,ikpt,isppol,1:3,ibcc:ibvv1)
     969              :        orbmag_mesh%orbmag_terms(nn,isppol,1:3,incc:inbm) = orbmag_mesh%orbmag_terms(nn,isppol,1:3,incc:inbm) + &
     970       166671 :            & trnrm(nn)*orbmag_mesh%omesh(nn,ikpt,isppol,1:3,incc:inbm)
     971              :      end do ! loop on bands
     972              : 
     973          675 :      icg = icg + mcgk
     974          675 :      icprj = icprj + mcprjk
     975          675 :      ikg = ikg + npw_k
     976          675 :      bdtot_index=bdtot_index+nband_k
     977              : 
     978          675 :      ABI_SFREE(ffnl_k)
     979          675 :      ABI_SFREE(ph3d)
     980          675 :      ABI_SFREE(kpg_k)
     981          675 :      ABI_SFREE(cg_k)
     982          675 :      ABI_SFREE(cg1_k)
     983          675 :      ABI_SFREE(gcg1_k)
     984          675 :      ABI_SFREE(eig_k)
     985          675 :      ABI_SFREE(occ_k)
     986          675 :      call pawcprj_free(cprj_k)
     987         9135 :      ABI_SFREE(cprj_k)
     988         2700 :      do adir = 1, 3
     989         2700 :        call pawcprj_free(cprj1_k(:,:,adir))
     990              :      end do
     991        26055 :      ABI_SFREE(cprj1_k)
     992          692 :      ABI_SFREE(trnrm)
     993              : 
     994              :    end do ! end loop over kpts
     995              : 
     996           17 :    ABI_SFREE(vlocal)
     997           17 :    ABI_SFREE(vectornd_pac)
     998           33 :    ABI_SFREE(vxctaulocal)
     999              : 
    1000              :  end do ! end loop over isppol
    1001              : 
    1002              :  ! accumulate data over processors
    1003           16 :  call orbmag_mesh%mpisum(nproc,spaceComm)
    1004              :  
    1005              :  ! prepare terms for output to abo file
    1006           16 :  call orbmag_mesh%term_scale(crystal,dtset)
    1007              : 
    1008              :  ! get the Lamb term
    1009           16 :  call lamb_core(atindx,dtset,omlamb,pawtab,psps%usepaw)
    1010              : 
    1011              :  ! output raw data to netcdf file for more detailed postprocessing
    1012           16 :  if (me == master) then
    1013           16 :    fname = trim(dtfil%filnam_ds(4))//'_ORBMAG.nc'
    1014           16 :    NCF_CHECK(nctk_open_create(ncid, fname, xmpi_comm_self))
    1015           16 :    call orbmag_ncwrite(crystal,dtset,ebands_k,hdr,ncid,orbmag_mesh)
    1016           16 :    NCF_CHECK(nf90_close(ncid))
    1017              :  end if
    1018              : 
    1019              :  ! output summary to abo file
    1020           16 :  call orbmag_mesh%output(dtset,omlamb)
    1021              : 
    1022              : !---------------------------------------------------
    1023              : ! deallocate memory
    1024              : !---------------------------------------------------
    1025              : 
    1026           16 :  call gs_hamk%free()
    1027              : 
    1028           16 :  ABI_SFREE(kg_k)
    1029           16 :  ABI_SFREE(kinpw)
    1030           16 :  ABI_SFREE(dkinpw)
    1031           16 :  ABI_SFREE(ph1d)
    1032              : 
    1033           16 :  ABI_SFREE(atindx)
    1034           16 :  ABI_SFREE(atindx1)
    1035           16 :  ABI_SFREE(nattyp)
    1036              : 
    1037           16 :  ABI_FREE(dimlmn)
    1038           16 :  call pawcprj_free(cwaveprj)
    1039           52 :  ABI_FREE(cwaveprj)
    1040              : 
    1041           16 :  call dterm%free()
    1042           16 :  call orbmag_mesh%free()
    1043              : 
    1044           32 : end subroutine orbmag
    1045              : !!***
    1046              : 
    1047              : !!****f*m_orbmag/orbmag_mpisum
    1048              : !! NAME
    1049              : !! orbmag_mpisum
    1050              : !!
    1051              : !! FUNCTION
    1052              : !! accumulate data in orbmag_mesh_type over processes
    1053              : !!
    1054              : !! INPUTS
    1055              : !!
    1056              : !! OUTPUT
    1057              : !!
    1058              : !! SOURCE
    1059              : 
    1060           17 : subroutine orbmag_mpisum(self,nproc,spaceComm)
    1061              :   !Arguments
    1062              :   class(orbmag_mesh_type),intent(inout),target :: self
    1063              :   integer,intent(in) :: nproc,spaceComm
    1064              : 
    1065              :   !Local variables
    1066              :   integer :: buff_size,ierr
    1067           17 :   real(dp),allocatable :: buffer1(:),buffer2(:)
    1068              : 
    1069           17 :   if (nproc > 1) then
    1070            0 :     if (allocated(self%cmesh)) then
    1071            0 :       buff_size=size(self%cmesh)
    1072            0 :       ABI_MALLOC(buffer1,(buff_size))
    1073            0 :       ABI_MALLOC(buffer2,(buff_size))
    1074            0 :       buffer1=zero;buffer2=zero
    1075              :       buffer1(1:buff_size) = &
    1076            0 :         & reshape(self%cmesh,(/self%mband*self%nkpt*self%nsppol*3*chern_nterms/))
    1077            0 :       call xmpi_sum(buffer1,buffer2,buff_size,spaceComm,ierr)
    1078              :       self%cmesh(1:self%mband,1:self%nkpt,1:self%nsppol,1:3,1:chern_nterms)=&
    1079            0 :         & reshape(buffer2,(/self%mband,self%nkpt,self%nsppol,3,chern_nterms/))
    1080            0 :       ABI_FREE(buffer1)
    1081            0 :       ABI_FREE(buffer2)
    1082              :     end if
    1083            0 :     if (allocated(self%chern_terms)) then
    1084            0 :       buff_size=size(self%chern_terms)
    1085            0 :       ABI_MALLOC(buffer1,(buff_size))
    1086            0 :       ABI_MALLOC(buffer2,(buff_size))
    1087            0 :       buffer1=zero;buffer2=zero
    1088              :       buffer1(1:buff_size) = &
    1089            0 :         & reshape(self%chern_terms,(/self%mband*self%nsppol*3*chern_nterms/))
    1090            0 :       call xmpi_sum(buffer1,buffer2,buff_size,spaceComm,ierr)
    1091              :       self%chern_terms(1:self%mband,1:self%nsppol,1:3,1:chern_nterms)=&
    1092            0 :         & reshape(buffer2,(/self%mband,self%nsppol,3,chern_nterms/))
    1093            0 :       ABI_FREE(buffer1)
    1094            0 :       ABI_FREE(buffer2)
    1095              :     end if
    1096            0 :     if (allocated(self%omesh)) then
    1097            0 :       buff_size=size(self%omesh)
    1098            0 :       ABI_MALLOC(buffer1,(buff_size))
    1099            0 :       ABI_MALLOC(buffer2,(buff_size))
    1100            0 :       buffer1=zero;buffer2=zero
    1101              :       buffer1(1:buff_size) = &
    1102            0 :         & reshape(self%omesh,(/self%mband*self%nkpt*self%nsppol*3*orbmag_nterms/))
    1103            0 :       call xmpi_sum(buffer1,buffer2,buff_size,spaceComm,ierr)
    1104              :       self%omesh(1:self%mband,1:self%nkpt,1:self%nsppol,1:3,1:orbmag_nterms)=&
    1105            0 :         & reshape(buffer2,(/self%mband,self%nkpt,self%nsppol,3,orbmag_nterms/))
    1106            0 :       ABI_FREE(buffer1)
    1107            0 :       ABI_FREE(buffer2)
    1108              :     end if
    1109            0 :     if (allocated(self%orbmag_terms)) then
    1110            0 :       buff_size=size(self%orbmag_terms)
    1111            0 :       ABI_MALLOC(buffer1,(buff_size))
    1112            0 :       ABI_MALLOC(buffer2,(buff_size))
    1113            0 :       buffer1=zero;buffer2=zero
    1114              :       buffer1(1:buff_size) = &
    1115            0 :         & reshape(self%orbmag_terms,(/self%mband*self%nsppol*3*orbmag_nterms/))
    1116            0 :       call xmpi_sum(buffer1,buffer2,buff_size,spaceComm,ierr)
    1117              :       self%orbmag_terms(1:self%mband,1:self%nsppol,1:3,1:orbmag_nterms)=&
    1118            0 :         & reshape(buffer2,(/self%mband,self%nsppol,3,orbmag_nterms/))
    1119            0 :       ABI_FREE(buffer1)
    1120            0 :       ABI_FREE(buffer2)
    1121              :     end if
    1122            0 :     if (allocated(self%rmesh)) then
    1123            0 :       buff_size=size(self%rmesh)
    1124            0 :       ABI_MALLOC(buffer1,(buff_size))
    1125            0 :       ABI_MALLOC(buffer2,(buff_size))
    1126            0 :       buffer1=zero;buffer2=zero
    1127              :       buffer1(1:buff_size) = &
    1128            0 :         & reshape(self%rmesh,(/self%n4*self%n5*self%n6*3*orbmag_nterms/))
    1129            0 :       call xmpi_sum(buffer1,buffer2,buff_size,spaceComm,ierr)
    1130              :       self%rmesh(1:self%n4,1:self%n5,1:self%n6,1:3,1:orbmag_nterms)=&
    1131            0 :         & reshape(buffer2,(/self%n4,self%n5,self%n6,3,orbmag_nterms/))
    1132            0 :       ABI_FREE(buffer1)
    1133            0 :       ABI_FREE(buffer2)
    1134              :     end if
    1135              :  
    1136              :   end if
    1137              : 
    1138           17 : end subroutine orbmag_mpisum
    1139              : !!***
    1140              :   
    1141              : 
    1142              : !!****f*m_orbmag/orbmag_term_scale
    1143              : !! NAME
    1144              : !! orbmag_term_scale
    1145              : !!
    1146              : !! FUNCTION
    1147              : !! change frames and scale terms as needed
    1148              : !!
    1149              : !! INPUTS
    1150              : !!
    1151              : !! OUTPUT
    1152              : !!
    1153              : !! SOURCE
    1154              : 
    1155           17 : subroutine orbmag_term_scale(self,crystal,dtset)
    1156              : 
    1157              :   !Arguments ------------------------------------
    1158              :   !scalars
    1159              :   class(orbmag_mesh_type),intent(inout),target :: self
    1160              :   type(crystal_t),intent(in) :: crystal
    1161              :   type(dataset_type),intent(in) :: dtset
    1162              : 
    1163              :   !arrays
    1164              : 
    1165              :   !Local variables -------------------------
    1166              :   !scalars
    1167              :   integer :: i4,i5,i6,isppol,iterm,nn
    1168              :   !arrays
    1169              : 
    1170              : !--------------------------------------------------------------------
    1171              : 
    1172          119 :  do iterm = 1, orbmag_nterms
    1173          227 :    do isppol = 1, dtset%nsppol
    1174          762 :      do nn = 1, self%mband
    1175          660 :        if((iterm.EQ.inlr).OR.(iterm.EQ.inbm)) then
    1176              :          self%orbmag_terms(nn,isppol,1:3,iterm) = &
    1177         3864 :            & MATMUL(crystal%rprimd,self%orbmag_terms(nn,isppol,1:3,iterm))
    1178              :        else
    1179              :          self%orbmag_terms(nn,isppol,1:3,iterm) = &
    1180         5888 :            & crystal%ucvol*MATMUL(crystal%gprimd,self%orbmag_terms(nn,isppol,1:3,iterm))
    1181              :        end if
    1182              :      end do ! nn
    1183              :    end do !isppol
    1184              :  end do
    1185              : 
    1186           17 :  if (dtset%orbmag .EQ. 4) then
    1187            7 :    do iterm = 1, orbmag_nterms
    1188          277 :      do i4=1,self%n4
    1189        12426 :        do i5=1,self%n5
    1190       559170 :          do i6=1,self%n6
    1191       558900 :            if((iterm.EQ.inlr).OR.(iterm.EQ.inbm)) then
    1192              :              self%rmesh(i4,i5,i6,1:3,iterm) = &
    1193      3827250 :                & MATMUL(crystal%rprimd,self%rmesh(i4,i5,i6,1:3,iterm))
    1194              :            else
    1195              :              self%rmesh(i4,i5,i6,1:3,iterm) = &
    1196      5832000 :                & crystal%ucvol*MATMUL(crystal%gprimd,self%rmesh(i4,i5,i6,1:3,iterm))
    1197              :            end if
    1198              :          end do
    1199              :        end do
    1200              :      end do
    1201              :    end do
    1202              :  end if
    1203              : 
    1204           17 :  if (dtset%orbmag .EQ. 4) then
    1205            7 :    do iterm = 1, orbmag_nterms
    1206           24 :      self%rmesh_int(1:3,iterm) = zero
    1207          277 :      do i4=1,self%n4
    1208        12426 :        do i5=1,self%n5
    1209       559170 :          do i6=1,self%n6
    1210              :            self%rmesh_int(1:3,iterm) = self%rmesh_int(1:3,iterm) + &
    1211      2199150 :              & self%rmesh(i4,i5,i6,1:3,iterm)
    1212              :          end do
    1213              :        end do
    1214              :      end do
    1215              :    end do
    1216              :  end if
    1217              : 
    1218           51 :  do iterm = 1, chern_nterms
    1219           87 :    do isppol = 1, dtset%nsppol
    1220          254 :      do nn = 1, self%mband
    1221              :        self%chern_terms(nn,isppol,1:3,iterm) = &
    1222         2980 :          & crystal%ucvol*MATMUL(crystal%gprimd,self%chern_terms(nn,isppol,1:3,iterm))
    1223              :      end do ! nn
    1224              :    end do !isppol
    1225              :  end do
    1226              : 
    1227              :  !! convert orbmag magnetization to orbital moment
    1228              :  !! Berry curvature terms are ignored
    1229         2405 :  self%orbmag_terms(:,:,:,incc:inbm)=crystal%ucvol*self%orbmag_terms(:,:,:,incc:inbm)
    1230              : 
    1231              :  !! accumulate trace of terms 
    1232           35 :  do isppol = 1, dtset%nsppol
    1233          127 :    do nn = 1, self%mband
    1234              :      self%orbmag_trace(1:3,1:orbmag_nterms) = self%orbmag_trace(1:3,1:orbmag_nterms) + &
    1235         2300 :        & self%orbmag_terms(nn,isppol,1:3,1:orbmag_nterms)
    1236              :      self%chern_trace(1:3,1:chern_nterms) = self%chern_trace(1:3,1:chern_nterms) + &
    1237          846 :        & self%chern_terms(nn,isppol,1:3,1:chern_nterms)
    1238              :    end do ! nn
    1239              :  end do ! isppol
    1240              : 
    1241           17 : end subroutine orbmag_term_scale
    1242              : !!***
    1243              : 
    1244              : !!****f* ABINIT/orbmag_nl1_k
    1245              : !! NAME
    1246              : !! orbmag_nl1_k
    1247              : !!
    1248              : !! FUNCTION
    1249              : !! make NL(1) term at k
    1250              : !!
    1251              : !! INPUTS
    1252              : !!  atindx(natom)=index table for atoms (see gstate.f)
    1253              : !!  cg_k(2,mcgk) ground state wavefunctions at this k point
    1254              : !!  cprj_k(dtset%natom,mcprjk)<type(pawcprj_type)>=cprj for cg_k
    1255              : !!  dimlmn(dtset%natom)=cprj lmn dimensions
    1256              : !!  dterm <type(dterm_type)> data related to onsite interactions
    1257              : !!  dtset <type(dataset_type)>=all input variables for this dataset
    1258              : !!  gs_hamk<type(gs_hamiltonian_type)>=ground state Hamiltonian at this k
    1259              : !!  ikpt=current k pt
    1260              : !!  isppol=current spin polarization
    1261              : !!  mcgk=2nd dimension of cg_k
    1262              : !!  mcprjk=dimension of cprj_k
    1263              : !!  mkmem_rbz=kpts in memory
    1264              : !!  mpi_enreg<type(MPI_type)>=information about MPI parallelization
    1265              : !!  nband_k=bands at this kpt
    1266              : !!  oterm=chooses which onsite term to apply
    1267              : !!  npw_k=planewaves at this k point
    1268              : !!  pawtab(dtset%ntypat) <type(pawtab_type)>=paw tabulated starting data
    1269              : !!
    1270              : !! OUTPUT
    1271              : !!
    1272              : !! SIDE EFFECTS
    1273              : !!  orbmag_mesh%omesh
    1274              : !!  if nl1_option = 1, orbmag contribution of <L_R> is returned
    1275              : !!  if nl1_option = 2, orbmag contribution of <A0.An> is returned
    1276              : !!
    1277              : !! TODO
    1278              : !!
    1279              : !! NOTES
    1280              : !!  returns \sum_{Rij}<u|p_i>a_ij<p_j|u> for various a_ij inputs
    1281              : !!
    1282              : !! SOURCE
    1283              : 
    1284         1350 : subroutine orbmag_nl1_k(atindx,cg_k,cprj_k,dimlmn,dterm,dtset,gs_hamk,ikpt,&
    1285         1350 :     & oterm,isppol,mcgk,mcprjk,mkmem_rbz,mpi_enreg,nband_k,npw_k,orbmag_mesh,trnrm)
    1286              : 
    1287              :   !Arguments ------------------------------------
    1288              :   !scalars
    1289              :   integer,intent(in) :: ikpt,isppol,mcgk,mcprjk,mkmem_rbz,nband_k,npw_k,oterm
    1290              :   type(dterm_type),intent(in) :: dterm
    1291              :   type(dataset_type),intent(in) :: dtset
    1292              :   type(gs_hamiltonian_type),intent(inout) :: gs_hamk
    1293              :   type(MPI_type), intent(inout) :: mpi_enreg
    1294              :   type(orbmag_mesh_type),intent(inout) :: orbmag_mesh
    1295              : 
    1296              :   !arrays
    1297              :   integer,intent(in) :: atindx(dtset%natom),dimlmn(dtset%natom)
    1298              :   real(dp),intent(in) :: trnrm(nband_k)
    1299              :   real(dp),intent(in),target :: cg_k(2,mcgk)
    1300              :   type(pawcprj_type),intent(in) :: cprj_k(dtset%natom,mcprjk)
    1301              : 
    1302              :   !Local variables -------------------------
    1303              :   !scalars
    1304              :   integer :: adir,choice,cpopt,dimekb1,dimekb2,dimekb3
    1305              :   integer :: n4,n5,n6,ndat,nn,nnlout,npwsp
    1306              :   integer :: paw_opt,signs,tim_nonlop
    1307              :   complex(dp) :: prefac_m,ormesh_fac
    1308              :   logical :: need_ormesh
    1309         1350 :   type(gs_hamiltonian_type),target :: gs_hamk_local
    1310              :   !arrays
    1311              :   real(dp) :: enlout(1),lambda(1),udotu(2)
    1312         1350 :   real(dp),allocatable :: fofr(:,:,:,:),svectout(:,:)
    1313         1350 :   real(dp),allocatable,target :: vectout(:,:)
    1314         1350 :   real(dp),pointer :: cwavef(:,:)
    1315         1350 :   type(pawcprj_type),allocatable :: cwaveprj(:,:)
    1316              : !--------------------------------------------------------------------
    1317              : 
    1318         1350 :  npwsp = npw_k*dtset%nspinor
    1319         1350 :  prefac_m = cone
    1320         4050 :  ABI_MALLOC(vectout,(2,npwsp))
    1321         2700 :  ABI_MALLOC(svectout,(2,npwsp))
    1322              : 
    1323              :  ! make a deep copy of gs_hamk so we can sub in the LR and BM 
    1324              :  ! Dij values without destroying gs_hamk
    1325         1350 :  call gs_hamk%copy(gs_hamk_local)
    1326         1350 :  dimekb1=size(gs_hamk_local%ekb_spin,1)
    1327         1350 :  dimekb2=size(gs_hamk_local%ekb_spin,2)
    1328         1350 :  dimekb3=size(gs_hamk_local%ekb_spin,3)
    1329              : 
    1330         1350 :  need_ormesh = (dtset%orbmag .EQ. 4)
    1331         1350 :  if (need_ormesh) then
    1332            2 :    n4=dtset%ngfft(4); n5=dtset%ngfft(5); n6=dtset%ngfft(6); ndat=1
    1333           10 :    ABI_MALLOC(fofr,(2,n4,n5,n6*ndat))
    1334              :  end if
    1335              :  
    1336         9700 :  ABI_MALLOC(cwaveprj,(dtset%natom,dtset%nspinor))
    1337         1350 :  call pawcprj_alloc(cwaveprj,cprj_k(1,1)%ncpgr,dimlmn)
    1338              :  
    1339         9822 :  do nn = 1, nband_k
    1340         8472 :    cwavef => cg_k(1:2,(nn-1)*npwsp+1:nn*npwsp)
    1341              :    call pawcprj_get(atindx,cwaveprj,cprj_k,dtset%natom,nn,0,ikpt,0,isppol,dtset%mband,&
    1342         8472 :      & mkmem_rbz,dtset%natom,1,nband_k,dtset%nspinor,dtset%nsppol,0)
    1343              :   
    1344        35238 :    do adir = 1, 3
    1345              :      
    1346      5848488 :      gs_hamk_local%ekb_spin = zero
    1347        38124 :      select case (oterm)
    1348              :      case ( inlr )
    1349              :        gs_hamk_local%ekb_spin(1:dimekb1,1:dimekb2,1:dimekb3,1,1) = &
    1350      2784396 :          & dterm%ekb_LR(1:dimekb1,1:dimekb2,1:dimekb3,adir)
    1351              :      case ( inbm )
    1352              :        gs_hamk_local%ekb_spin(1:dimekb1,1:dimekb2,1:dimekb3,1,1) = &
    1353      2784396 :          & dterm%ekb_BM(1:dimekb1,1:dimekb2,1:dimekb3,adir)
    1354              :      case default
    1355        25416 :        gs_hamk_local%ekb_spin(1:dimekb1,1:dimekb2,1:dimekb3,1,1) = zero
    1356              :      end select
    1357              : 
    1358              :      ! use nonlop to construct vectout = \sum_ij |p_i>D_ij<p_j|unk>
    1359        25416 :      choice = 1; cpopt = 4; paw_opt = 1; signs = 2; nnlout = 1; ndat = 1
    1360              :      call nonlop(choice,cpopt,cwaveprj,enlout,gs_hamk_local,adir,lambda,mpi_enreg,ndat,nnlout,&
    1361        25416 :        & paw_opt,signs,svectout,tim_nonlop,cwavef,vectout)
    1362        25416 :      udotu=cg_zdotc(npwsp,cwavef,vectout)
    1363        25416 :      orbmag_mesh%omesh(nn,ikpt,isppol,adir,oterm) = udotu(1)
    1364              : 
    1365        33888 :      if (need_ormesh) then
    1366           24 :        ormesh_fac = prefac_m*trnrm(nn)
    1367           24 :        call me_proj_mesh(cwavef,fofr,gs_hamk,vectout,mpi_enreg,n4,n5,n6,ndat,npw_k,ormesh_fac)
    1368      2236704 :        orbmag_mesh%rmesh(:,:,:,adir,oterm)=orbmag_mesh%rmesh(:,:,:,adir,oterm)+fofr(1,:,:,:)
    1369              :      end if
    1370              : 
    1371              :    end do !adir
    1372              :  
    1373              :  end do !nn
    1374              : 
    1375         1350 :  call pawcprj_free(cwaveprj)
    1376         4044 :  ABI_SFREE(cwaveprj)
    1377         1350 :  IF(ASSOCIATED(cwavef)) NULLIFY(cwavef)
    1378         1350 :  ABI_SFREE(fofr)
    1379         1350 :  ABI_SFREE(vectout)
    1380         1350 :  ABI_SFREE(svectout)
    1381              :  
    1382         1350 :  call gs_hamk_local%free()
    1383              : 
    1384         2700 : end subroutine orbmag_nl1_k
    1385              : !!***
    1386              : 
    1387              : !!****f* ABINIT/orbmag_nl_k
    1388              : !! NAME
    1389              : !! orbmag_nl_k
    1390              : !!
    1391              : !! FUNCTION
    1392              : !! make NL term at k
    1393              : !!
    1394              : !! INPUTS
    1395              : !!  atindx(natom)=index table for atoms (see gstate.f)
    1396              : !!  cprj_k(dtset%natom,mcprjk)<type(pawcprj_type)>=cprj for cg_k
    1397              : !!  dimlmn(dtset%natom)=cprj lmn dimensions
    1398              : !!  dterm <type(dterm_type)> data related to onsite interactions
    1399              : !!  dtset <type(dataset_type)>=all input variables for this dataset
    1400              : !!  eig_k(nband_k)=gs eigenvalues at this kpt
    1401              : !!  ikpt=current k pt
    1402              : !!  isppol=current spin polarization
    1403              : !!  mcprjk=dimension of cprj_k
    1404              : !!  mkmem_rbz=kpts in memory
    1405              : !!  nband_k=bands at this kpt
    1406              : !!  pawtab(dtset%ntypat) <type(pawtab_type)>=paw tabulated starting data
    1407              : !!
    1408              : !! OUTPUT
    1409              : !!
    1410              : !! SIDE EFFECTS
    1411              : !!  orbmag_mesh%omesh
    1412              : !!
    1413              : !! TODO
    1414              : !!
    1415              : !! NOTES
    1416              : !! computes -\frac{i}{2}\sum_{Rij}<u|d_b p_i>D^0_{ij} - E^0s^0_{ij}<d_g p_j|u>
    1417              : !! This is ZTG23 Eq. 36 term 1
    1418              : !!
    1419              : !! SOURCE
    1420              : 
    1421          675 : subroutine orbmag_nl_k(atindx,cg_k,cprj_k,dimlmn,dterm,dtset,eig_k,gs_hamk,ikpt,isppol,&
    1422          675 :     & mcgk,mcprjk,mkmem_rbz,mpi_enreg,nband_k,npw_k,orbmag_mesh,pawtab,trnrm)
    1423              : 
    1424              :   !Arguments ------------------------------------
    1425              :   !scalars
    1426              :   integer,intent(in) :: ikpt,isppol,mcgk,mcprjk,mkmem_rbz,nband_k,npw_k
    1427              :   type(dterm_type),intent(in) :: dterm
    1428              :   type(dataset_type),intent(in) :: dtset
    1429              :   type(gs_hamiltonian_type),intent(inout) :: gs_hamk
    1430              :   type(MPI_type), intent(inout) :: mpi_enreg
    1431              :   type(orbmag_mesh_type),intent(inout) :: orbmag_mesh
    1432              : 
    1433              :   !arrays
    1434              :   integer,intent(in) :: atindx(dtset%natom),dimlmn(dtset%natom)
    1435              :   real(dp),intent(in),target :: cg_k(2,mcgk)
    1436              :   real(dp),intent(in) :: eig_k(nband_k),trnrm(nband_k)
    1437              :   type(pawcprj_type),intent(in) :: cprj_k(dtset%natom,mcprjk)
    1438              :   type(pawtab_type),intent(in) :: pawtab(dtset%ntypat)
    1439              : 
    1440              :   !Local variables -------------------------
    1441              :   !scalars
    1442              :   integer :: adir,bdir,gdir,n4,n5,n6,ndat,nn,npwsp
    1443              :   complex(dp) :: prefac_m,ormesh_fac,txt
    1444              :   logical :: need_ormesh
    1445              :   !arrays
    1446              :   real(dp) :: nonlop_udotu(2)
    1447          675 :   real(dp),allocatable :: fofr(:,:,:,:),svectout(:,:)
    1448              :   real(dp),allocatable,target :: vectout(:,:)
    1449          675 :   real(dp),pointer :: unk(:,:)
    1450          675 :   type(pawcprj_type),allocatable :: cwaveprj(:,:)
    1451              : 
    1452              : !--------------------------------------------------------------------
    1453              : 
    1454          675 :  npwsp = npw_k*dtset%nspinor
    1455         2025 :  ABI_MALLOC(vectout,(2,npwsp))
    1456         1350 :  ABI_MALLOC(svectout,(2,npwsp))
    1457              :  
    1458          675 :  need_ormesh = (dtset%orbmag .EQ. 4)
    1459          675 :  if (need_ormesh) then
    1460            1 :    n4=dtset%ngfft(4); n5=dtset%ngfft(5); n6=dtset%ngfft(6); ndat=1
    1461            5 :    ABI_MALLOC(fofr,(2,n4,n5,n6*ndat))
    1462              :  end if
    1463              :  
    1464         4850 :  ABI_MALLOC(cwaveprj,(dtset%natom,dtset%nspinor))
    1465          675 :  call pawcprj_alloc(cwaveprj,cprj_k(1,1)%ncpgr,dimlmn)
    1466              : 
    1467         4911 :  do nn = 1, nband_k
    1468              : 
    1469         4236 :    unk => cg_k(1:2,(nn-1)*npwsp+1:nn*npwsp)
    1470              :    call pawcprj_get(atindx,cwaveprj,cprj_k,dtset%natom,nn,0,ikpt,0,isppol,dtset%mband,&
    1471         4236 :      & mkmem_rbz,dtset%natom,1,nband_k,dtset%nspinor,dtset%nsppol,0)
    1472              : 
    1473         4236 :    prefac_m = -com*c2
    1474        17619 :    do adir = 1, 3
    1475              :      ! even permutation of adir,bdir,gdir
    1476              :      ! cross product term adir,gdir,bdir leads to (-i/2)(Z-Z*) and 
    1477              :      ! double the original even term
    1478        12708 :      bdir=modulo(adir,3)+1
    1479        12708 :      gdir=modulo(bdir,3)+1
    1480              :      
    1481              :      call nonlop_orbmag_nl(atindx,cwaveprj,bdir,gdir,dterm,dtset,eig_k(nn),gs_hamk,npw_k,&
    1482        12708 :       & pawtab,vectout)
    1483              :      
    1484        12708 :      nonlop_udotu(1:2)=cg_zdotc(npwsp,unk,vectout)
    1485        12708 :      txt=prefac_m*CMPLX(nonlop_udotu(1),nonlop_udotu(2))
    1486              : 
    1487              :      orbmag_mesh%omesh(nn,ikpt,isppol,adir,innl) = &
    1488        12708 :        &orbmag_mesh%omesh(nn,ikpt,isppol,adir,innl) + two*REAL(txt)
    1489              : 
    1490        16944 :      if (need_ormesh) then
    1491           12 :        ormesh_fac = trnrm(nn)*prefac_m
    1492           12 :        call me_proj_mesh(unk,fofr,gs_hamk,vectout,mpi_enreg,n4,n5,n6,ndat,npw_k,ormesh_fac)
    1493              :        orbmag_mesh%rmesh(:,:,:,adir,innl)=&
    1494      1118352 :          &orbmag_mesh%rmesh(:,:,:,adir,innl)+two*fofr(1,:,:,:)
    1495              :      end if
    1496              : 
    1497              :    end do ! adir
    1498              : 
    1499              :  end do !nn
    1500              : 
    1501          675 :  call pawcprj_free(cwaveprj)
    1502         2022 :  ABI_SFREE(cwaveprj)
    1503          675 :  IF(ASSOCIATED(unk)) NULLIFY(unk)
    1504          675 :  ABI_SFREE(fofr)
    1505          675 :  ABI_SFREE(vectout)
    1506          675 :  ABI_SFREE(svectout)
    1507              : 
    1508         1350 : end subroutine orbmag_nl_k
    1509              : !!***
    1510              : 
    1511              : !!****f* ABINIT/orbmag_cc_k_ncpp
    1512              : !! NAME
    1513              : !! orbmag_cc_k_ncpp
    1514              : !!
    1515              : !! FUNCTION
    1516              : !! computes <P_c du/dk|H + E*S|P_c du/dk> term in orbital magnetism, for NCPP
    1517              : !!
    1518              : !! INPUTS
    1519              : !!  atindx(natom)=index table for atoms (see gstate.f)
    1520              : !!  cprj1_k(dtset%natom,mcprjk)<type(pawcprj_type)>=cprj for Pc cg1_k
    1521              : !!  dimlmn(dtset%natom)=cprj lmn dimensions
    1522              : !!  dtset <type(dataset_type)>=all input variables for this dataset
    1523              : !!  eig_k(nband_k)=gs eigenvalues at this kpt
    1524              : !!  fermie=offset energy to use
    1525              : !!  gcg1_k(2,mcgk,3)=gauge adjusted cg1_k
    1526              : !!  gs_hamk<type(gs_hamiltonian_type)>=ground state Hamiltonian at this k
    1527              : !!  ikpt=current k pt
    1528              : !!  isppol=current spin polarization
    1529              : !!  mcgk=dimension of cg_k
    1530              : !!  mcprjk=dimension of cprj_k
    1531              : !!  mkmem_rbz=kpts in memory
    1532              : !!  mpi_enreg<type(MPI_type)>=information about MPI parallelization
    1533              : !!  nband_k=bands at this kpt
    1534              : !!  npw_k=number of planewaves at this kpt
    1535              : !!  occ_k=band occupations at this kpt
    1536              : !!  ucvol=unit cell volume
    1537              : !!
    1538              : !! OUTPUT
    1539              : !!
    1540              : !! SIDE EFFECTS
    1541              : !!  orbmag_mesh%omesh, orbmag_mesh%cmesh
    1542              : !!
    1543              : !! TODO
    1544              : !!
    1545              : !! NOTES
    1546              : !! ZTG23 Eq. 36 term 2 and Eq. 46 term 1
    1547              : !!
    1548              : !! SOURCE
    1549              : 
    1550           32 : subroutine orbmag_cc_k_ncpp(dtset,eig_k,fermie,gcg1_k,gs_hamk,ikpt,isppol,&
    1551              :     & mcgk,mpi_enreg,nband_k,npw_k,orbmag_mesh)
    1552              : 
    1553              :   !Arguments ------------------------------------
    1554              :   !scalars
    1555              :   integer,intent(in) :: ikpt,isppol,mcgk,nband_k,npw_k
    1556              :   real(dp),intent(in) :: fermie
    1557              :   type(dataset_type),intent(in) :: dtset
    1558              :   type(gs_hamiltonian_type),intent(inout) :: gs_hamk
    1559              :   type(MPI_type), intent(inout) :: mpi_enreg
    1560              :   type(orbmag_mesh_type),intent(inout) :: orbmag_mesh
    1561              : 
    1562              :   !arrays
    1563              :   real(dp),intent(in) :: eig_k(nband_k)
    1564              :   real(dp),intent(in),target :: gcg1_k(2,mcgk,3)
    1565              : 
    1566              :   !Local variables -------------------------
    1567              :   !scalars
    1568              :   integer :: adir,bdir,cpopt,gdir
    1569              :   integer :: ndat,nn,npwsp,sij_opt,tim_getghc,type_calc
    1570              :   real(dp) :: lams
    1571              :   complex(dp) :: prefac_b,prefac_m
    1572              :   !arrays
    1573              :   real(dp) bdot(2),mdot(2)
    1574           32 :   real(dp),allocatable :: gec(:,:),gvnlxc(:,:)
    1575           32 :   real(dp),allocatable,target :: ghc(:,:)
    1576           32 :   real(dp),pointer :: du_dbeta(:,:),du_dgamma(:,:)
    1577              :   complex(dp) :: m1(3),b1(3)
    1578           32 :   type(pawcprj_type),allocatable :: cwaveprj1(:,:)
    1579              : !--------------------------------------------------------------------
    1580              : 
    1581           32 :  npwsp = npw_k*dtset%nspinor
    1582              : 
    1583           96 :  ABI_MALLOC(ghc,(2,npwsp))
    1584           64 :  ABI_MALLOC(gec,(2,npwsp))
    1585           64 :  ABI_MALLOC(gvnlxc,(2,npwsp))
    1586           64 :  ABI_MALLOC(cwaveprj1,(dtset%natom,0))
    1587              : 
    1588           32 :  tim_getghc = 0
    1589           32 :  lams = zero
    1590           32 :  ndat = 1
    1591              :  
    1592           32 :  prefac_b = cbc*c2
    1593           32 :  prefac_m = com*c2
    1594          160 :  do nn = 1, nband_k
    1595          128 :    cpopt = -1; sij_opt = 0
    1596          128 :    type_calc = 0 ! apply local and non-local Hamiltonian
    1597              : 
    1598              :    m1 = czero
    1599              :    b1 = czero
    1600              : 
    1601          544 :    do adir = 1, 3
    1602              : 
    1603              :      ! even permutation of adir,bdir,gdir
    1604              :      ! cross product term adir,gdir,bdir leads to (-i/2)(Z-Z*) and 
    1605              :      ! double the original even term
    1606          384 :      bdir=modulo(adir,3)+1
    1607          384 :      gdir=modulo(bdir,3)+1
    1608              :      
    1609          384 :      du_dgamma => gcg1_k(1:2,(nn-1)*npwsp+1:nn*npwsp,gdir)
    1610              : 
    1611              :      ! compute H|Pc d_\gamma u>
    1612              :      ! [H+(E - 2\mu)]|ket> is needed for orbmag
    1613              :      ! -2|ket> needed for chern
    1614              :      call getghc(cpopt,du_dgamma,cwaveprj1,ghc,gec,gs_hamk,gvnlxc,lams,mpi_enreg,&
    1615          384 :        & ndat,dtset%prtvol,sij_opt,tim_getghc,type_calc)
    1616              : 
    1617       168864 :      gec(1:2,1:npwsp) = (eig_k(nn) - two*fermie)*du_dgamma(1:2,1:npwsp)
    1618       168864 :      ghc(1:2,1:npwsp) = ghc(1:2,1:npwsp) + gec(1:2,1:npwsp)
    1619              : 
    1620          384 :      du_dbeta => gcg1_k(1:2,(nn-1)*npwsp+1:nn*npwsp,bdir)
    1621         1536 :      mdot = cg_zdotc(npwsp,du_dbeta,ghc); bdot = -two*cg_zdotc(npwsp,du_dbeta,du_dgamma)
    1622              : 
    1623              :      ! cross product term adir,gdir,bdir leads to (-i/2)(Z-Z*) and 
    1624              :      ! double the original even term: this is the origin of the factor of two
    1625              :       orbmag_mesh%omesh(nn,ikpt,isppol,adir,incc) =  &
    1626              :        & orbmag_mesh%omesh(nn,ikpt,isppol,adir,incc) + &
    1627          384 :        & two*real(prefac_m*CMPLX(mdot(1),mdot(2)))
    1628              :       orbmag_mesh%cmesh(nn,ikpt,isppol,adir,ibcc) = &
    1629              :        & orbmag_mesh%cmesh(nn,ikpt,isppol,adir,ibcc) - &
    1630          512 :        & four*real(prefac_b*CMPLX(bdot(1),bdot(2)))
    1631              : 
    1632              :    end do ! adir
    1633              : 
    1634              :  end do !nn
    1635              : 
    1636           32 :  if(ASSOCIATED(du_dbeta)) NULLIFY(du_dbeta)
    1637           32 :  if(ASSOCIATED(du_dgamma)) NULLIFY(du_dgamma)
    1638              : 
    1639           32 :  ABI_SFREE(ghc)
    1640           32 :  ABI_SFREE(gec)
    1641           32 :  ABI_SFREE(gvnlxc)
    1642           32 :  ABI_SFREE(cwaveprj1)
    1643              : 
    1644           64 : end subroutine orbmag_cc_k_ncpp
    1645              : !!***
    1646              : 
    1647              : 
    1648              : !!****f* ABINIT/orbmag_cc_k
    1649              : !! NAME
    1650              : !! orbmag_cc_k
    1651              : !!
    1652              : !! FUNCTION
    1653              : !! computes <P_c du/dk|H + E*S|P_c du/dk> term in orbital magnetism
    1654              : !!
    1655              : !! INPUTS
    1656              : !!  atindx(natom)=index table for atoms (see gstate.f)
    1657              : !!  cprj1_k(dtset%natom,mcprjk)<type(pawcprj_type)>=cprj for Pc cg1_k
    1658              : !!  dimlmn(dtset%natom)=cprj lmn dimensions
    1659              : !!  dtset <type(dataset_type)>=all input variables for this dataset
    1660              : !!  eig_k(nband_k)=gs eigenvalues at this kpt
    1661              : !!  fermie=offset energy to use
    1662              : !!  gcg1_k(2,mcgk,3)=gauge adjusted cg1_k
    1663              : !!  gs_hamk<type(gs_hamiltonian_type)>=ground state Hamiltonian at this k
    1664              : !!  ikpt=current k pt
    1665              : !!  isppol=current spin polarization
    1666              : !!  mcgk=dimension of cg_k
    1667              : !!  mcprjk=dimension of cprj_k
    1668              : !!  mkmem_rbz=kpts in memory
    1669              : !!  mpi_enreg<type(MPI_type)>=information about MPI parallelization
    1670              : !!  nband_k=bands at this kpt
    1671              : !!  npw_k=number of planewaves at this kpt
    1672              : !!  occ_k=band occupations at this kpt
    1673              : !!  ucvol=unit cell volume
    1674              : !!
    1675              : !! OUTPUT
    1676              : !!
    1677              : !! SIDE EFFECTS
    1678              : !!  orbmag_mesh%omesh, orbmag_mesh%cmesh
    1679              : !!
    1680              : !! TODO
    1681              : !!
    1682              : !! NOTES
    1683              : !! ZTG23 Eq. 36 term 2 and Eq. 46 term 1
    1684              : !!
    1685              : !! SOURCE
    1686              : 
    1687          675 : subroutine orbmag_cc_k(atindx,cprj1_k,dimlmn,dtset,eig_k,fermie,&
    1688          675 :     & gcg1_k,gs_hamk,ikpt,isppol,mcgk,mcprjk,mkmem_rbz,mpi_enreg,nband_k,&
    1689          675 :     & npw_k,orbmag_mesh,trnrm)
    1690              : 
    1691              :   !Arguments ------------------------------------
    1692              :   !scalars
    1693              :   integer,intent(in) :: ikpt,isppol,mcgk,mcprjk,mkmem_rbz,nband_k,npw_k
    1694              :   real(dp),intent(in) :: fermie
    1695              :   type(dataset_type),intent(in) :: dtset
    1696              :   type(gs_hamiltonian_type),intent(inout) :: gs_hamk
    1697              :   type(MPI_type), intent(inout) :: mpi_enreg
    1698              :   type(orbmag_mesh_type),intent(inout) :: orbmag_mesh
    1699              : 
    1700              :   !arrays
    1701              :   integer,intent(in) :: atindx(dtset%natom),dimlmn(dtset%natom)
    1702              :   real(dp),intent(in) :: eig_k(nband_k),trnrm(nband_k)
    1703              :   real(dp),intent(in),target :: gcg1_k(2,mcgk,3)
    1704              :   type(pawcprj_type),intent(in) :: cprj1_k(dtset%natom,mcprjk,3)
    1705              : 
    1706              :   !Local variables -------------------------
    1707              :   !scalars
    1708              :   integer :: adir,bdir,cpopt,dum_dnlbra,dum_dnlket,gdir
    1709              :   integer :: ndat,n4,n5,n6,nn,npwsp,sij_opt,tim_getghc,type_calc
    1710              :   real(dp) :: lams
    1711              :   complex(dp) :: ormesh_fac,prefac_b,prefac_m
    1712              :   logical :: need_ormesh
    1713              :   !arrays
    1714              :   real(dp) bdot(2),mdot(2)
    1715          675 :   real(dp),allocatable :: fofr(:,:,:,:),gsc(:,:),gvnlxc(:,:)
    1716          675 :   real(dp),allocatable,target :: ghc(:,:)
    1717          675 :   real(dp),pointer :: du_dbeta(:,:),du_dgamma(:,:)
    1718              :   complex(dp) :: m1(3),b1(3)
    1719          675 :   type(pawcprj_type),allocatable :: cwaveprj1(:,:)
    1720              : !--------------------------------------------------------------------
    1721              : 
    1722          675 :  npwsp = npw_k*dtset%nspinor
    1723          675 :  need_ormesh = (dtset%orbmag .EQ. 4)
    1724              : 
    1725         2025 :  ABI_MALLOC(ghc,(2,npwsp))
    1726         1350 :  ABI_MALLOC(gsc,(2,npwsp))
    1727         1350 :  ABI_MALLOC(gvnlxc,(2,npwsp))
    1728         4850 :  ABI_MALLOC(cwaveprj1,(dtset%natom,dtset%nspinor))
    1729          675 :  call pawcprj_alloc(cwaveprj1,0,dimlmn)
    1730              : 
    1731          675 :  tim_getghc = 0
    1732          675 :  lams = zero
    1733          675 :  ndat = 1
    1734              :  
    1735          675 :  if (need_ormesh) then
    1736            1 :    dum_dnlbra = 0; dum_dnlket = 0
    1737            1 :    n4=dtset%ngfft(4); n5=dtset%ngfft(5); n6=dtset%ngfft(6); ndat=1
    1738            5 :    ABI_MALLOC(fofr,(2,n4,n5,n6*ndat))
    1739              :  end if
    1740              : 
    1741          675 :  prefac_b = cbc*c2
    1742          675 :  prefac_m = com*c2
    1743         4911 :  do nn = 1, nband_k
    1744              : 
    1745              :    m1 = czero
    1746              :    b1 = czero
    1747              : 
    1748        17619 :    do adir = 1, 3
    1749              : 
    1750              :      ! even permutation of adir,bdir,gdir
    1751              :      ! cross product term adir,gdir,bdir leads to (-i/2)(Z-Z*) and 
    1752              :      ! double the original even term
    1753        12708 :      bdir=modulo(adir,3)+1
    1754        12708 :      gdir=modulo(bdir,3)+1
    1755              :      
    1756        12708 :      cpopt = 2
    1757        12708 :      du_dgamma => gcg1_k(1:2,(nn-1)*npwsp+1:nn*npwsp,gdir)
    1758              : 
    1759              :      call pawcprj_get(atindx,cwaveprj1,cprj1_k(:,:,gdir),dtset%natom,nn,0,ikpt,0,isppol,dtset%mband,&
    1760        12708 :        & mkmem_rbz,dtset%natom,1,nband_k,dtset%nspinor,dtset%nsppol,0)
    1761              : 
    1762              :      ! compute H|Pc d_\gamma u> and S|Pc d_\gamma u>
    1763              :      ! [H+E*S - 2\mu*S]|ket> is needed for orbmag
    1764              :      ! -2*S|ket> needed for Chern
    1765        12708 :      type_calc = 0 ! apply local and non-local Hamiltonian
    1766        12708 :      sij_opt = 1 ! compute gsc in addition to ghc
    1767              :      call getghc(cpopt,du_dgamma,cwaveprj1,ghc,gsc,gs_hamk,gvnlxc,lams,mpi_enreg,&
    1768        12708 :        & ndat,dtset%prtvol,sij_opt,tim_getghc,type_calc)
    1769              : 
    1770      8003592 :      ghc(1:2,1:npwsp) = ghc(1:2,1:npwsp) + gsc(1:2,1:npwsp)*(eig_k(nn) - two*fermie)
    1771              : 
    1772        12708 :      du_dbeta => gcg1_k(1:2,(nn-1)*npwsp+1:nn*npwsp,bdir)
    1773        12708 :      mdot = cg_zdotc(npwsp,du_dbeta,ghc); bdot = cg_zdotc(npwsp,du_dbeta,gsc)
    1774              : 
    1775              :      ! cross product term adir,gdir,bdir leads to (-i/2)(Z-Z*) and 
    1776              :      ! double the original even term: this is the origin of the factor of two
    1777              :       orbmag_mesh%omesh(nn,ikpt,isppol,adir,incc) =  &
    1778              :        & orbmag_mesh%omesh(nn,ikpt,isppol,adir,incc) + &
    1779        12708 :        & two*real(prefac_m*CMPLX(mdot(1),mdot(2)))
    1780              :       orbmag_mesh%cmesh(nn,ikpt,isppol,adir,ibcc) = &
    1781              :        & orbmag_mesh%cmesh(nn,ikpt,isppol,adir,ibcc) - &
    1782        12708 :        & four*real(prefac_b*CMPLX(bdot(1),bdot(2)))
    1783              : 
    1784        16944 :      if (need_ormesh) then
    1785           12 :        ormesh_fac = trnrm(nn)*prefac_m
    1786           12 :        call me_proj_mesh(du_dbeta,fofr,gs_hamk,ghc,mpi_enreg,n4,n5,n6,ndat,npw_k,ormesh_fac)
    1787              :        orbmag_mesh%rmesh(:,:,:,adir,incc)=&
    1788      1118352 :          &orbmag_mesh%rmesh(:,:,:,adir,incc)+two*fofr(1,:,:,:)
    1789              :      end if
    1790              : 
    1791              :    end do ! adir
    1792              : 
    1793              :  end do !nn
    1794              : 
    1795          675 :  if(ASSOCIATED(du_dbeta)) NULLIFY(du_dbeta)
    1796          675 :  if(ASSOCIATED(du_dgamma)) NULLIFY(du_dgamma)
    1797              : 
    1798          675 :  ABI_SFREE(ghc)
    1799          675 :  ABI_SFREE(gsc)
    1800          675 :  ABI_SFREE(gvnlxc)
    1801          675 :  call pawcprj_free(cwaveprj1)
    1802         2022 :  ABI_SFREE(cwaveprj1)
    1803          675 :  ABI_SFREE(fofr)
    1804              : 
    1805         1350 : end subroutine orbmag_cc_k
    1806              : !!***
    1807              : 
    1808              : !!****f* ABINIT/orbmag_vv_k
    1809              : !! NAME
    1810              : !! orbmag_vv_k
    1811              : !!
    1812              : !! FUNCTION
    1813              : !! orbmag_vv_k
    1814              : !!
    1815              : !! INPUTS
    1816              : !!  atindx(natom)=index table for atoms (see gstate.f)
    1817              : !!  cg_k(2,mcgk)=ground state wavefunctions at this k point
    1818              : !!  cprj_k(dtset%natom,mcprjk)<type(pawcprj_type)>=cprj for cg_k
    1819              : !!  dimlmn(dtset%natom)=cprj lmn dimensions
    1820              : !!  dtset <type(dataset_type)>=all input variables for this dataset
    1821              : !!  eig_k(nband_k)=gs eigenvalues at this kpt
    1822              : !!  fermie=offset energy to use
    1823              : !!  gcg1_k(2,mcgk,3)=gauge treated cg1_k
    1824              : !!  gs_hamk<type(gs_hamiltonian_type)>=ground state Hamiltonian at this k
    1825              : !!  ikpt=current k pt
    1826              : !!  isppol=current spin polarization
    1827              : !!  mcgk=dimension of cg_k
    1828              : !!  mcprjk=dimension of cprj_k
    1829              : !!  mkmem_rbz=kpts in memory
    1830              : !!  mpi_enreg<type(MPI_type)>=information about MPI parallelization
    1831              : !!  nband_k=bands at this kpt
    1832              : !!  npw_k=number of planewaves at this kpt
    1833              : !!
    1834              : !! OUTPUT
    1835              : !!
    1836              : !! SIDE EFFECTS
    1837              : !!  orbmag_mesh%omesh, orbmag_mesh%cmesh
    1838              : !!
    1839              : !! TODO
    1840              : !!
    1841              : !! NOTES
    1842              : !! contributions (1) <Pc d_b u|E d_gS|u> + <u|E d_bS|Pc d_g u> and
    1843              : !! (2) \sum_n' <u |d_b ES|u_n'><u_n'|d_g ES|u> to orbital magnetization
    1844              : !! these are ZTG23 Eq 36 terms 3 and 4, and Eq. 46 term 2
    1845              : !!
    1846              : !! SOURCE
    1847              : 
    1848          675 : subroutine orbmag_vv_k(atindx,cg_k,cprj_k,dimlmn,dtset,eig_k,fermie,gcg1_k,gs_hamk,&
    1849          675 :     & ikpt,isppol,mcgk,mcprjk,mkmem_rbz,mpi_enreg,nband_k,npw_k,orbmag_mesh,trnrm)
    1850              : 
    1851              :   !Arguments ------------------------------------
    1852              :   !scalars
    1853              :   integer,intent(in) :: ikpt,isppol,mcgk,mcprjk,mkmem_rbz,nband_k,npw_k
    1854              :   real(dp),intent(in) :: fermie
    1855              :   type(dataset_type),intent(in) :: dtset
    1856              :   type(gs_hamiltonian_type),intent(inout) :: gs_hamk
    1857              :   type(MPI_type), intent(inout) :: mpi_enreg
    1858              :   type(orbmag_mesh_type),intent(inout) :: orbmag_mesh
    1859              : 
    1860              :   !arrays
    1861              :   integer,intent(in) :: atindx(dtset%natom),dimlmn(dtset%natom)
    1862              :   real(dp),intent(in) :: eig_k(nband_k),trnrm(nband_k)
    1863              :   real(dp),intent(in),target :: cg_k(2,mcgk),gcg1_k(2,mcgk,3)
    1864              :   type(pawcprj_type),intent(in) :: cprj_k(dtset%natom,mcprjk)
    1865              : 
    1866              :   !Local variables -------------------------
    1867              :   !scalars
    1868              :   integer :: adir,bdir,choice,cpopt,dnl_dum,fourwf_cplex,fourwf_option,gdir
    1869              :   integer :: n4,n5,n6,ndat,nn,nnlout,np,npwsp,paw_opt,signs,tim_fourwf,tim_getghc
    1870              :   complex(dp) :: b1,bdotc,bpdotc,gdotc,gpdotc,m1,mv2b,ormesh_fac,prefac_b,prefac_m
    1871              :   logical :: need_ormesh
    1872              :   !arrays
    1873              :   real(dp) :: bdot(2),bpdot(2),gdot(2),gpdot(2),enlout(1),lamv(1)
    1874          675 :   real(dp),allocatable :: fofr(:,:,:,:),proj_un(:,:),vectout(:,:)
    1875          675 :   real(dp),allocatable,target :: svectoutb(:,:),svectoutbp(:,:),svectoutg(:,:)
    1876          675 :   real(dp),pointer :: bra(:,:),du_dbeta(:,:),du_dgamma(:,:),unk(:,:)
    1877          675 :   type(pawcprj_type),allocatable :: cwaveprj(:,:),vv2_cwaveprj(:,:)
    1878              : !--------------------------------------------------------------------
    1879              : 
    1880          675 :  npwsp = npw_k*dtset%nspinor
    1881          675 :  fourwf_cplex = 1
    1882          675 :  fourwf_option = 0
    1883          675 :  tim_fourwf = 1
    1884          675 :  need_ormesh = (dtset%orbmag .EQ. 4)
    1885              : 
    1886         2025 :  ABI_MALLOC(vectout,(2,npwsp))
    1887         1350 :  ABI_MALLOC(svectoutb,(2,npwsp))
    1888         1350 :  ABI_MALLOC(svectoutg,(2,npwsp))
    1889         4850 :  ABI_MALLOC(cwaveprj,(dtset%natom,dtset%nspinor))
    1890         4175 :  ABI_MALLOC(vv2_cwaveprj,(dtset%natom,dtset%nspinor))
    1891          675 :  call pawcprj_alloc(cwaveprj,cprj_k(1,1)%ncpgr,dimlmn)
    1892          675 :  call pawcprj_alloc(vv2_cwaveprj,cprj_k(1,1)%ncpgr,dimlmn)
    1893              : 
    1894          675 :  tim_getghc = 0
    1895          675 :  lamv = zero
    1896          675 :  ndat = 1
    1897          675 :  nnlout = 1
    1898          675 :  cpopt = 4 ! cprj and derivs in memory
    1899          675 :  choice = 5 ! apply dS/dk
    1900          675 :  paw_opt = 3 ! retain dS/dk|u>
    1901          675 :  signs = 2
    1902              : 
    1903          675 :  if (need_ormesh) then
    1904            1 :    dnl_dum=0
    1905            1 :    n4=dtset%ngfft(4); n5=dtset%ngfft(5); n6=dtset%ngfft(6); ndat=1
    1906            2 :    ABI_MALLOC(proj_un,(2,npwsp))
    1907            2 :    ABI_MALLOC(svectoutbp,(2,npwsp))
    1908            5 :    ABI_MALLOC(fofr,(2,n4,n5,n6*ndat))
    1909              :  end if
    1910              : 
    1911          675 :  prefac_b = cbc*c2
    1912          675 :  prefac_m = com*c2
    1913         4911 :  do nn = 1, nband_k
    1914              :      
    1915              :    ! extract |u_nk>
    1916         4236 :    unk => cg_k(1:2,(nn-1)*npwsp+1:nn*npwsp)
    1917              :    call pawcprj_get(atindx,cwaveprj,cprj_k,dtset%natom,nn,0,ikpt,0,isppol,dtset%mband,&
    1918         4236 :      & mkmem_rbz,dtset%natom,1,nband_k,dtset%nspinor,dtset%nsppol,0)
    1919              : 
    1920        17619 :    do adir=1,3
    1921              :      ! even permutation of adir,bdir,gdir
    1922              :      ! cross product term adir,gdir,bdir leads to (-i/2)(Z-Z*) and 
    1923              :      ! double the original even term
    1924        12708 :      bdir=modulo(adir,3)+1
    1925        12708 :      gdir=modulo(bdir,3)+1
    1926              : 
    1927              :      ! compute dS/dk_b|u_nk>
    1928              :      call nonlop(choice,cpopt,cwaveprj,enlout,gs_hamk,bdir,lamv,mpi_enreg,ndat,nnlout,&
    1929        12708 :        & paw_opt,signs,svectoutb,tim_getghc,unk,vectout)
    1930              : 
    1931              :      ! compute dS/dk_g |u_nk>
    1932              :      call nonlop(choice,cpopt,cwaveprj,enlout,gs_hamk,gdir,lamv,mpi_enreg,ndat,nnlout,&
    1933        12708 :        & paw_opt,signs,svectoutg,tim_getghc,unk,vectout)
    1934              : 
    1935              :      ! extract |Pc du/dk_b>
    1936        12708 :      du_dbeta => gcg1_k(1:2,(nn-1)*npwsp+1:nn*npwsp,bdir)
    1937        12708 :      gdot=cg_zdotc(npwsp,du_dbeta,svectoutg); gdotc=CMPLX(gdot(1),gdot(2))
    1938              : 
    1939              :      ! extract |Pc du/dk_g>
    1940        12708 :      du_dgamma => gcg1_k(1:2,(nn-1)*npwsp+1:nn*npwsp,gdir)
    1941        12708 :      bdot=cg_zdotc(npwsp,du_dgamma,svectoutb); bdotc=CMPLX(bdot(1),bdot(2))
    1942              : 
    1943              :      ! here is <Pc du/dk_b|dS/dk_g|u_nk>*E_nk
    1944        12708 :      b1    = -prefac_b*gdotc
    1945        12708 :      m1    =  prefac_m*gdotc*(eig_k(nn) - fermie)
    1946              : 
    1947              :      ! add CONJG(<Pc du/dk_b|dS/dk_g|u_nk>)*E_nk
    1948        12708 :      b1    = b1    - prefac_b*CONJG(bdotc)
    1949        12708 :      m1    = m1    + prefac_m*CONJG(bdotc)*(eig_k(nn) - fermie)
    1950              :    
    1951              :      orbmag_mesh%omesh(nn,ikpt,isppol,adir,invv1) = &
    1952        12708 :        & orbmag_mesh%omesh(nn,ikpt,isppol,adir,invv1) + two*real(m1)
    1953              :      
    1954              :      orbmag_mesh%cmesh(nn,ikpt,isppol,adir,ibvv1) = &
    1955        12708 :        & orbmag_mesh%cmesh(nn,ikpt,isppol,adir,ibvv1) + two*real(b1)
    1956              : 
    1957        12708 :      if (need_ormesh) then
    1958              :        
    1959           12 :        ormesh_fac = trnrm(nn)*prefac_m*(eig_k(nn) - fermie)
    1960              : 
    1961           12 :        call me_proj_mesh(du_dbeta,fofr,gs_hamk,svectoutg,mpi_enreg,n4,n5,n6,ndat,npw_k,ormesh_fac)
    1962              :        orbmag_mesh%rmesh(:,:,:,adir,invv1)=&
    1963      1118352 :          &orbmag_mesh%rmesh(:,:,:,adir,invv1)+two*fofr(1,:,:,:)
    1964              :        
    1965           12 :        call me_proj_mesh(svectoutb,fofr,gs_hamk,du_dgamma,mpi_enreg,n4,n5,n6,ndat,npw_k,ormesh_fac)
    1966              :        orbmag_mesh%rmesh(:,:,:,adir,invv1)=&
    1967      1118352 :          &orbmag_mesh%rmesh(:,:,:,adir,invv1)+two*fofr(1,:,:,:)
    1968              :       
    1969              :      end if
    1970              : 
    1971        12708 :      mv2b = czero
    1972        50202 :      do np = nn+1, nband_k
    1973        37494 :        bra => cg_k(1:2,(np-1)*npwsp+1:np*npwsp)
    1974        37494 :        gpdot=cg_zdotc(npwsp,bra,svectoutg); gpdotc=CMPLX(gpdot(1),gpdot(2))
    1975        37494 :        bpdot=cg_zdotc(npwsp,bra,svectoutb); bpdotc=CMPLX(bpdot(1),bpdot(2))
    1976        50202 :        mv2b = mv2b + prefac_m*CONJG(bpdotc)*gpdotc*(eig_k(nn) - eig_k(np))
    1977              :      end do ! np
    1978              :     
    1979              :      ! Note that term VV2 has a minus sign in contrast to VV1 (see ZTG Eq. 36)
    1980              :      orbmag_mesh%omesh(nn,ikpt,isppol,adir,invv2) = &
    1981        12708 :        & orbmag_mesh%omesh(nn,ikpt,isppol,adir,invv2) - two*real(mv2b)
    1982              : 
    1983        16944 :      if (need_ormesh) then
    1984              : 
    1985              :        ! project dS/dk_g|u> onto valence space
    1986       181488 :        proj_un = zero
    1987           60 :        do np=1,nband_k
    1988           48 :          bra => cg_k(1:2,(np-1)*npwsp+1:np*npwsp)
    1989           48 :          gpdot=cg_zdotc(npwsp,bra,svectoutg)
    1990              :          proj_un(1,1:npwsp) = proj_un(1,1:npwsp) + &
    1991       242016 :            & bra(1,1:npwsp)*gpdot(1) - bra(2,1:npwsp)*gpdot(2)
    1992              :          proj_un(2,1:npwsp) = proj_un(2,1:npwsp) + &
    1993       242028 :            & bra(1,1:npwsp)*gpdot(2) + bra(2,1:npwsp)*gpdot(1)
    1994              :        end do
    1995              : 
    1996              :        ! compute dS/dk_b \sum_' |u'><u'|dS/dk_g|u>
    1997           12 :        cpopt = -1 ! cprj and derivs computed and not saved
    1998              :        call nonlop(choice,cpopt,vv2_cwaveprj,enlout,gs_hamk,bdir,lamv,mpi_enreg,ndat,nnlout,&
    1999           12 :          & paw_opt,signs,svectoutbp,tim_getghc,proj_un,vectout)
    2000           12 :        cpopt = 4 ! change cpopt back to its usual value in this routine
    2001           12 :        ormesh_fac = trnrm(nn)*prefac_m*(eig_k(nn) - fermie)
    2002           12 :        call me_proj_mesh(unk,fofr,gs_hamk,svectoutbp,mpi_enreg,n4,n5,n6,ndat,npw_k,ormesh_fac)
    2003              :        orbmag_mesh%rmesh(:,:,:,adir,invv2)=&
    2004      1118352 :          &orbmag_mesh%rmesh(:,:,:,adir,invv2)-two*fofr(1,:,:,:)
    2005              : 
    2006              :      end if ! computation of vv2 for rmesh
    2007              : 
    2008              :    end do ! adir
    2009              : 
    2010              :  end do !nn
    2011              : 
    2012          675 :  IF(ASSOCIATED(du_dbeta)) NULLIFY(du_dbeta)
    2013          675 :  IF(ASSOCIATED(du_dgamma)) NULLIFY(du_dgamma)
    2014          675 :  IF(ASSOCIATED(unk)) NULLIFY(unk)
    2015          675 :  IF(ASSOCIATED(bra)) NULLIFY(bra)
    2016              : 
    2017          675 :  ABI_SFREE(vectout) 
    2018          675 :  ABI_SFREE(svectoutb)
    2019          675 :  ABI_SFREE(svectoutg)
    2020          675 :  call pawcprj_free(cwaveprj)
    2021          675 :  call pawcprj_free(vv2_cwaveprj)
    2022         2022 :  ABI_SFREE(cwaveprj)
    2023         2022 :  ABI_SFREE(vv2_cwaveprj)
    2024          675 :  ABI_SFREE(fofr)
    2025          675 :  ABI_SFREE(proj_un)
    2026          675 :  ABI_SFREE(svectoutbp)
    2027              : 
    2028         1350 : end subroutine orbmag_vv_k
    2029              : !!***
    2030              : 
    2031              : !!****f* ABINIT/para_to_diag
    2032              : !! NAME
    2033              : !! para_to_diag
    2034              : !!
    2035              : !! FUNCTION
    2036              : !! convert cg1_k wavefunction from parallel to diagonal gauge
    2037              : !!
    2038              : !! INPUTS
    2039              : !!  atindx(natom)=index table for atoms (see gstate.f)
    2040              : !!  cg_k(2,mcgk)=ground state wavefunctions at this k point
    2041              : !!  cg1_k(2,mcgk,3)=DDK wavefunctions at this k point, all 3 directions
    2042              : !!  cprj_k(dtset%natom,mcprjk)<type(pawcprj_type)>=cprj for cg_k
    2043              : !!  dimlmn(dtset%natom)=cprj lmn dimensions
    2044              : !!  dtset <type(dataset_type)>=all input variables for this dataset
    2045              : !!  gs_hamk<type(gs_hamiltonian_type)>=ground state Hamiltonian at this k
    2046              : !!  ikpt=current k pt
    2047              : !!  isppol=current spin polarization
    2048              : !!  mcgk=dimension of cg_k
    2049              : !!  mcprjk=dimension of cprj_k
    2050              : !!  mkmem_rbz=kpts in memory
    2051              : !!  mpi_enreg<type(MPI_type)>=information about MPI parallelization
    2052              : !!  nband_k=bands at this kpt
    2053              : !!  npw_k=number of planewaves at this kpt
    2054              : !!  occ_k=band occupations at this kpt
    2055              : !!
    2056              : !! OUTPUT
    2057              : !!  gcg1_k(2,mcgk,3)=cg1_k converted to requested gauge and/or projection
    2058              : !!
    2059              : !! NOTES
    2060              : !!
    2061              : !! SOURCE
    2062              : 
    2063            0 : subroutine para_to_diag(atindx,cg_k,cg1_k,cprj_k,dimlmn,dkinpw,dtset,eig_k,gcg1_k,gs_hamk,&
    2064              :     & ikpt,isppol,mcgk,mcprjk,mkmem_rbz,mpi_enreg,mpw,nband_k,ngfft4,ngfft5,ngfft6,npw_k,&
    2065            0 :     & nucdip_dirs,occ_k,vectornd_pac)
    2066              : 
    2067              :   !Arguments ------------------------------------
    2068              :   !scalars
    2069              :   integer,intent(in) :: ikpt,isppol,mcgk,mcprjk,mkmem_rbz,mpw,nband_k,ngfft4,ngfft5,ngfft6
    2070              :   integer,intent(in) :: npw_k,nucdip_dirs
    2071              :   type(dataset_type),intent(in) :: dtset
    2072              :   type(gs_hamiltonian_type),intent(inout) :: gs_hamk
    2073              :   type(MPI_type), intent(inout) :: mpi_enreg
    2074              : 
    2075              :   !arrays
    2076              :   integer,intent(in) :: atindx(dtset%natom),dimlmn(dtset%natom)
    2077              :   real(dp),intent(in) :: cg_k(2,mcgk),cg1_k(2,mcgk,3),eig_k(nband_k),dkinpw(mpw,3),occ_k(nband_k)
    2078              :   real(dp),intent(in) :: vectornd_pac(ngfft4,ngfft5,ngfft6,gs_hamk%nvloc,nucdip_dirs)
    2079              :   real(dp),intent(out) :: gcg1_k(2,mcgk,3)
    2080              :   type(pawcprj_type),intent(in) ::  cprj_k(dtset%natom,mcprjk)
    2081              : 
    2082              :   !Local variables -------------------------
    2083              :   !scalars
    2084              :   integer :: adir,berryopt,cplex,iband,ipert,jband,ndat,npwsp
    2085              :   integer :: optlocal,optnl,opt_gvnlx1,sij_opt,tim_getgh1c,usevnl
    2086              :   real(dp) :: corrfac,deltae,pertr,perti,pertsize
    2087            0 :   type(rf_hamiltonian_type) :: rf_hamk
    2088              :   !arrays
    2089              :   real(dp) :: hij(2),lambda(1),sij(2)
    2090            0 :   real(dp),allocatable :: cwavef(:,:),dcg1(:,:),gh1c(:,:)
    2091            0 :   real(dp),allocatable :: grad_berry(:,:),gs1c(:,:),gvnlx1(:,:)
    2092            0 :   real(dp),allocatable :: vectornd_pac_idir(:,:,:,:)
    2093            0 :   type(pawcprj_type),allocatable :: cwaveprj(:,:)
    2094              : 
    2095              : !--------------------------------------------------------------------
    2096              : 
    2097            0 :   berryopt=0
    2098            0 :   ndat=1
    2099            0 :   optlocal=0
    2100            0 :   optnl=2
    2101            0 :   opt_gvnlx1=0
    2102            0 :   sij_opt=1
    2103            0 :   tim_getgh1c=0
    2104            0 :   usevnl = 0
    2105            0 :   lambda(1) = zero
    2106              : 
    2107            0 :   ipert=dtset%natom+1 ! DDK
    2108            0 :   cplex=1 ! real space 1-order functions on FFT grid are REAL 
    2109            0 :   call rf_hamk%init(cplex,gs_hamk,ipert)
    2110              : 
    2111            0 :   npwsp = npw_k*dtset%nspinor
    2112              : 
    2113            0 :   ABI_MALLOC(cwaveprj,(dtset%natom,dtset%nspinor))
    2114            0 :   call pawcprj_alloc(cwaveprj,3,dimlmn)
    2115            0 :   ABI_MALLOC(cwavef,(2,npwsp))
    2116            0 :   ABI_MALLOC(gh1c,(2,gs_hamk%npw_kp*gs_hamk%nspinor*ndat))
    2117            0 :   ABI_MALLOC(gs1c,(2,gs_hamk%npw_kp*gs_hamk%nspinor*ndat))
    2118            0 :   ABI_MALLOC(gvnlx1,(2,gs_hamk%npw_kp*gs_hamk%nspinor*ndat))
    2119            0 :   ABI_MALLOC(dcg1,(2,npwsp))
    2120              : 
    2121            0 :   if (nucdip_dirs .EQ. 3) then
    2122            0 :     ABI_MALLOC(vectornd_pac_idir,(ngfft4,ngfft5,ngfft6,gs_hamk%nvloc))
    2123              :   end if
    2124              : 
    2125            0 :   gcg1_k = zero
    2126              : 
    2127            0 :   do adir = 1, 3
    2128              : 
    2129            0 :     call rf_hamk%load_k(dkinpw_k=dkinpw(:,adir))
    2130              : 
    2131            0 :     if (nucdip_dirs .EQ. 3) then
    2132            0 :       vectornd_pac_idir(:,:,:,:)=vectornd_pac(:,:,:,:,adir)
    2133            0 :       call rf_hamk%load_spin(isppol, vectornd=vectornd_pac_idir)
    2134              :     end if
    2135              : 
    2136            0 :     do iband = 1, nband_k
    2137              : 
    2138            0 :       cwavef(1:2,1:npwsp)=cg_k(1:2,(iband-1)*npwsp+1:iband*npwsp)
    2139              : 
    2140              :       call pawcprj_get(atindx,cwaveprj,cprj_k,dtset%natom,iband,0,ikpt,0,isppol,dtset%mband,&
    2141            0 :         & mkmem_rbz,dtset%natom,1,nband_k,dtset%nspinor,dtset%nsppol,0)
    2142              : 
    2143              :       call getgh1c(berryopt,cwavef,cwaveprj,gh1c,grad_berry,gs1c,gs_hamk,gvnlx1,adir,ipert,&
    2144              :         & lambda(1),mpi_enreg,ndat,optlocal,optnl,opt_gvnlx1,rf_hamk,sij_opt,&
    2145            0 :         & tim_getgh1c,usevnl)
    2146              : 
    2147            0 :       dcg1=zero
    2148            0 :       do jband = 1, nband_k
    2149            0 :         if (jband .EQ. iband) cycle
    2150            0 :         if(abs(occ_k(jband)).LT.tol8) cycle
    2151            0 :         deltae = eig_k(jband) - eig_k(iband)
    2152              :         ! deltae test seems to work best compared to deltapert test
    2153              :         !if (abs(deltae) .LT. dtset%ggtrcut) cycle
    2154            0 :         cwavef(1:2,1:npwsp)=cg_k(1:2,(jband-1)*npwsp+1:jband*npwsp)
    2155            0 :         hij=cg_zdotc(npwsp,cwavef,gh1c)
    2156            0 :         sij=cg_zdotc(npwsp,cwavef,gs1c)
    2157            0 :         select case (dtset%orbmag)
    2158              :         case ( 3 )
    2159            0 :           lambda(1) = half*(eig_k(jband)+eig_k(iband))
    2160            0 :           corrfac=-one
    2161              :         case ( -3 )
    2162            0 :           lambda(1) = eig_k(iband)
    2163            0 :           corrfac=-one
    2164              :         end select
    2165            0 :         pertr = (hij(1)-lambda(1)*sij(1))/deltae
    2166            0 :         perti = (hij(2)-lambda(1)*sij(2))/deltae
    2167            0 :         pertsize=sqrt(pertr*pertr+perti*perti)
    2168            0 :         if (pertsize .GT. dtset%ggtrcut) cycle
    2169            0 :         dcg1(1,:) = dcg1(1,:) + pertr*cwavef(1,:) - perti*cwavef(2,:)
    2170            0 :         dcg1(2,:) = dcg1(2,:) + pertr*cwavef(2,:) + perti*cwavef(1,:)
    2171              :       end do
    2172              :       gcg1_k(1:2,(iband-1)*npwsp+1:iband*npwsp,adir) =&
    2173            0 :         &cg1_k(1:2,(iband-1)*npwsp+1:iband*npwsp,adir)+corrfac*dcg1(1:2,1:npwsp)
    2174              :     end do
    2175              :   end do
    2176              : 
    2177            0 :   call rf_hamk%free()
    2178            0 :   if(allocated(vectornd_pac_idir)) then
    2179            0 :     ABI_FREE(vectornd_pac_idir)
    2180              :   end if
    2181            0 :   ABI_FREE(cwavef)
    2182            0 :   call pawcprj_free(cwaveprj)
    2183            0 :   ABI_FREE(cwaveprj)
    2184            0 :   ABI_FREE(gh1c)
    2185            0 :   ABI_FREE(gs1c)
    2186            0 :   ABI_FREE(gvnlx1)
    2187            0 :   ABI_FREE(dcg1)
    2188              : 
    2189            0 : end subroutine para_to_diag
    2190              : !!***
    2191              : 
    2192              : !!****f* ABINIT/gauge_treatment
    2193              : !! NAME
    2194              : !! gauge_treatment
    2195              : !!
    2196              : !! FUNCTION
    2197              : !! convert cg1_k wavefunction to requested gauge and/or projection
    2198              : !!
    2199              : !! INPUTS
    2200              : !!  atindx(natom)=index table for atoms (see gstate.f)
    2201              : !!  cg_k(2,mcgk)=ground state wavefunctions at this k point
    2202              : !!  cg1_k(2,mcgk,3)=DDK wavefunctions at this k point, all 3 directions
    2203              : !!  cprj_k(dtset%natom,mcprjk)<type(pawcprj_type)>=cprj for cg_k
    2204              : !!  dimlmn(dtset%natom)=cprj lmn dimensions
    2205              : !!  dtset <type(dataset_type)>=all input variables for this dataset
    2206              : !!  gs_hamk<type(gs_hamiltonian_type)>=ground state Hamiltonian at this k
    2207              : !!  ikpt=current k pt
    2208              : !!  isppol=current spin polarization
    2209              : !!  mcgk=dimension of cg_k
    2210              : !!  mcprjk=dimension of cprj_k
    2211              : !!  mkmem_rbz=kpts in memory
    2212              : !!  mpi_enreg<type(MPI_type)>=information about MPI parallelization
    2213              : !!  nband_k=bands at this kpt
    2214              : !!  npw_k=number of planewaves at this kpt
    2215              : !!  occ_k=band occupations at this kpt
    2216              : !!
    2217              : !! OUTPUT
    2218              : !!  gcg1_k(2,mcgk,3)=cg1_k converted to requested gauge and/or projection
    2219              : !!
    2220              : !! NOTES
    2221              : !!
    2222              : !! SOURCE
    2223              : 
    2224          675 : subroutine gauge_treatment(atindx,cg_k,cg1_k,cprj_k,dimlmn,dkinpw,dtset,eig_k,gcg1_k,gs_hamk,&
    2225              :     & ikpt,isppol,mcgk,mcprjk,mkmem_rbz,mpi_enreg,mpw,nband_k,ngfft4,ngfft5,ngfft6,npw_k,&
    2226          675 :     & nucdip_dirs,occ_k,vectornd_pac)
    2227              : 
    2228              :   !Arguments ------------------------------------
    2229              :   !scalars
    2230              :   integer,intent(in) :: ikpt,isppol,mcgk,mcprjk,mkmem_rbz,mpw,nband_k,ngfft4,ngfft5,ngfft6
    2231              :   integer,intent(in) :: npw_k,nucdip_dirs
    2232              :   type(dataset_type),intent(in) :: dtset
    2233              :   type(gs_hamiltonian_type),intent(inout) :: gs_hamk
    2234              :   type(MPI_type), intent(inout) :: mpi_enreg
    2235              : 
    2236              :   !arrays
    2237              :   integer,intent(in) :: atindx(dtset%natom),dimlmn(dtset%natom)
    2238              :   real(dp),intent(in) :: cg_k(2,mcgk),cg1_k(2,mcgk,3),eig_k(nband_k),dkinpw(mpw,3),occ_k(nband_k)
    2239              :   real(dp),intent(in) :: vectornd_pac(ngfft4,ngfft5,ngfft6,gs_hamk%nvloc,nucdip_dirs)
    2240              :   real(dp),intent(out) :: gcg1_k(2,mcgk,3)
    2241              :   type(pawcprj_type),intent(in) ::  cprj_k(dtset%natom,mcprjk)
    2242              : 
    2243              :   !Local variables -------------------------
    2244              :   !scalars
    2245              : 
    2246              : !--------------------------------------------------------------------
    2247              : 
    2248              :   ! orbmag > 0: cg1_k contains PAW DDK in parallel gauge, which has a ground state part
    2249              :   ! orbmag < 0: cg1_k contains Berry phase DDK, which is projected onto the 
    2250              :   !             conduction space by construction
    2251              : 
    2252          675 :   select case (dtset%orbmag)
    2253              :   case ( -3 )
    2254              :     ! Convert Berry DDK to diagonal gauge
    2255              :     call para_to_diag(atindx,cg_k,cg1_k,cprj_k,dimlmn,dkinpw,dtset,eig_k,gcg1_k,gs_hamk,&
    2256              :       & ikpt,isppol,mcgk,mcprjk,mkmem_rbz,mpi_enreg,mpw,nband_k,ngfft4,ngfft5,ngfft6,npw_k,&
    2257            0 :       & nucdip_dirs,occ_k,vectornd_pac)
    2258              :   case ( -2:-1 )
    2259              :     ! Berry DDK already projected onto conduction space, leave in berry gauge
    2260       168608 :     gcg1_k(1:2,1:mcgk,1:3) = cg1_k(1:2,1:mcgk,1:3)
    2261              :   case ( 3 ) 
    2262              :     ! Convert PAW DDK to diagonal gauge
    2263              :     call para_to_diag(atindx,cg_k,cg1_k,cprj_k,dimlmn,dkinpw,dtset,eig_k,gcg1_k,gs_hamk,&
    2264              :       & ikpt,isppol,mcgk,mcprjk,mkmem_rbz,mpi_enreg,mpw,nband_k,ngfft4,ngfft5,ngfft6,npw_k,&
    2265            0 :       & nucdip_dirs,occ_k,vectornd_pac)
    2266              :   case default
    2267              :     ! project cg1_k onto conduction space by removing ground PAW part; 
    2268              :     ! stay in parallel transport gauge
    2269              :     call make_pcg1(atindx,cg_k,cg1_k,cprj_k,dimlmn,dtset,gs_hamk,&
    2270          675 :       & ikpt,isppol,mcgk,mcprjk,mkmem_rbz,mpi_enreg,nband_k,npw_k,occ_k,gcg1_k)
    2271              :   end select
    2272              : 
    2273          675 : end subroutine gauge_treatment
    2274              : !!***
    2275              : 
    2276              : !!****f* ABINIT/make_pcg1
    2277              : !! NAME
    2278              : !! make_pcg1
    2279              : !!
    2280              : !! FUNCTION
    2281              : !! compute Pc|cg1> from |cg1> and |cg>
    2282              : !!
    2283              : !! INPUTS
    2284              : !!  atindx(natom)=index table for atoms (see gstate.f)
    2285              : !!  cg_k(2,mcgk)=ground state wavefunctions at this k point
    2286              : !!  cg1_k(2,mcgk,3)=DDK wavefunctions at this k point, all 3 directions
    2287              : !!  cprj_k(dtset%natom,mcprjk)<type(pawcprj_type)>=cprj for cg_k
    2288              : !!  dimlmn(dtset%natom)=cprj lmn dimensions
    2289              : !!  dtset <type(dataset_type)>=all input variables for this dataset
    2290              : !!  gs_hamk<type(gs_hamiltonian_type)>=ground state Hamiltonian at this k
    2291              : !!  ikpt=current k pt
    2292              : !!  isppol=current spin polarization
    2293              : !!  mcgk=dimension of cg_k
    2294              : !!  mcprjk=dimension of cprj_k
    2295              : !!  mkmem_rbz=kpts in memory
    2296              : !!  mpi_enreg<type(MPI_type)>=information about MPI parallelization
    2297              : !!  nband_k=bands at this kpt
    2298              : !!  npw_k=number of planewaves at this kpt
    2299              : !!  occ_k=band occupations at this kpt
    2300              : !!
    2301              : !! OUTPUT
    2302              : !!  pcg1_k(2,mcgk,3)=cg1_k projected on conduction space
    2303              : !!
    2304              : !! NOTES
    2305              : !! see Audouze et al PRB 78, 035105 (2008) Eq. 40
    2306              : !!
    2307              : !! SOURCE
    2308              : 
    2309          643 : subroutine make_pcg1(atindx,cg_k,cg1_k,cprj_k,dimlmn,dtset,gs_hamk,&
    2310          643 :     & ikpt,isppol,mcgk,mcprjk,mkmem_rbz,mpi_enreg,nband_k,npw_k,occ_k,pcg1_k)
    2311              : 
    2312              :   !Arguments ------------------------------------
    2313              :   !scalars
    2314              :   integer,intent(in) :: ikpt,isppol,mcgk,mcprjk,mkmem_rbz,nband_k,npw_k
    2315              :   type(dataset_type),intent(in) :: dtset
    2316              :   type(gs_hamiltonian_type),intent(inout) :: gs_hamk
    2317              :   type(MPI_type), intent(inout) :: mpi_enreg
    2318              : 
    2319              :   !arrays
    2320              :   integer,intent(in) :: atindx(dtset%natom),dimlmn(dtset%natom)
    2321              :   real(dp),intent(in) :: cg_k(2,mcgk),cg1_k(2,mcgk,3),occ_k(nband_k)
    2322              :   real(dp),intent(out) :: pcg1_k(2,mcgk,3)
    2323              :   type(pawcprj_type),intent(in) ::  cprj_k(dtset%natom,mcprjk)
    2324              : 
    2325              :   !Local variables -------------------------
    2326              :   !scalars
    2327              :   integer :: adir,choice,cpopt,iband,jband
    2328              :   integer :: ndat,nnlout,npwsp,paw_opt,signs,tim_nonlop
    2329              :   !arrays
    2330              :   real(dp) :: dotp(2),lambda(1)
    2331          643 :   real(dp),allocatable :: cwavef(:,:),enlout(:),svectout(:,:)
    2332          643 :   real(dp),allocatable :: vcg1(:,:),vectout(:,:)
    2333          643 :   type(pawcprj_type),allocatable :: cwaveprj(:,:)
    2334              : 
    2335              : !--------------------------------------------------------------------
    2336              : 
    2337          643 :   choice = 5 ! dS/dk in nonlop
    2338          643 :   cpopt = 4 ! cprj and derivatives already in memory
    2339          643 :   paw_opt = 3
    2340          643 :   signs = 2
    2341          643 :   tim_nonlop = 0
    2342          643 :   lambda = zero
    2343          643 :   nnlout = 0
    2344          643 :   ndat = 1
    2345              : 
    2346          643 :   npwsp = npw_k*dtset%nspinor
    2347              : 
    2348         4626 :   ABI_MALLOC(cwaveprj,(dtset%natom,dtset%nspinor))
    2349          643 :   call pawcprj_alloc(cwaveprj,3,dimlmn)
    2350         1929 :   ABI_MALLOC(cwavef,(2,npwsp))
    2351         1286 :   ABI_MALLOC(vectout,(2,npwsp))
    2352         1286 :   ABI_MALLOC(svectout,(2,npwsp))
    2353         1286 :   ABI_MALLOC(vcg1,(2,npwsp))
    2354              : 
    2355      7824976 :   pcg1_k = zero
    2356              : 
    2357         2572 :   do adir = 1, 3
    2358              : 
    2359        14896 :     do iband = 1, nband_k
    2360              : 
    2361      7834728 :       cwavef(1:2,1:npwsp)=cg_k(1:2,(iband-1)*npwsp+1:iband*npwsp)
    2362              : 
    2363              :       call pawcprj_get(atindx,cwaveprj,cprj_k,dtset%natom,iband,0,ikpt,0,isppol,dtset%mband,&
    2364        12324 :         & mkmem_rbz,dtset%natom,1,nband_k,dtset%nspinor,dtset%nsppol,0)
    2365              : 
    2366              :       ! compute S^1|u_i^0> where S^1 = \partial S/\partial k_adir, the k derivative of S in
    2367              :       ! direction adir
    2368              :       call nonlop(choice,cpopt,cwaveprj,enlout,gs_hamk,adir,lambda,mpi_enreg,ndat,&
    2369        12324 :         & nnlout,paw_opt,signs,svectout,tim_nonlop,cwavef,vectout)
    2370              : 
    2371              :       !! form vcg1 = -1/2 \sum |u_j^0><u_j^0|S^1|u_i^0>, the valence band part of cg1
    2372      7834728 :       vcg1 = zero
    2373        98484 :       do jband = 1, nband_k
    2374        86160 :         if(abs(occ_k(jband)).LT.tol8) cycle
    2375     44085888 :         cwavef(1:2,1:npwsp)=cg_k(1:2,(jband-1)*npwsp+1:jband*npwsp)
    2376        66096 :         dotp=cg_zdotc(npwsp,cwavef,svectout)
    2377     14739360 :         vcg1(1,:) = vcg1(1,:) - half*( dotp(1)*cwavef(1,:) - dotp(2)*cwavef(2,:))
    2378     14771748 :         vcg1(2,:) = vcg1(2,:) - half*( dotp(1)*cwavef(2,:) + dotp(2)*cwavef(1,:))
    2379              :       end do
    2380              : 
    2381              :       ! subtract vcg1 from cg1_k to obtain pcg1, the conduction band part of cg1
    2382              :       pcg1_k(1:2,(iband-1)*npwsp+1:iband*npwsp,adir) =cg1_k(1:2,(iband-1)*npwsp+1:iband*npwsp,adir)-&
    2383      7836657 :         &  vcg1(1:2,1:npwsp)
    2384              : 
    2385              :     end do
    2386              :   end do
    2387              : 
    2388          643 :   ABI_FREE(cwavef)
    2389          643 :   ABI_FREE(vectout)
    2390          643 :   ABI_FREE(vcg1)
    2391          643 :   ABI_FREE(svectout)
    2392          643 :   call pawcprj_free(cwaveprj)
    2393         1926 :   ABI_FREE(cwaveprj)
    2394              : 
    2395          643 : end subroutine make_pcg1
    2396              : !!***
    2397              : 
    2398              : !!****f* ABINIT/lamb_core
    2399              : !! NAME
    2400              : !! lamb_core
    2401              : !!
    2402              : !! FUNCTION
    2403              : !! add core electron contribution to the orbital magnetic moment
    2404              : !!
    2405              : !! INPUTS
    2406              : !!  atindx(dtset%natom)=index table for atoms (see gstate.f)
    2407              : !!  dtset <type(dataset_type)>=all input variables for this dataset
    2408              : !!  pawtab(dtset%ntypat) <type(pawtab_type)>=paw tabulated starting data
    2409              : !!
    2410              : !! OUTPUT
    2411              : !!  omlamb(2,3)=contribution of Lamb shielding to magnetic moment
    2412              : !!
    2413              : !! NOTES
    2414              : !!  lamb shielding of core electrons contributes -m.lambsig to orbital magnetic
    2415              : !!  moment
    2416              : !!
    2417              : !! SOURCE
    2418              : 
    2419           17 : subroutine lamb_core(atindx,dtset,omlamb,pawtab,usepaw)
    2420              : 
    2421              :   !Arguments ------------------------------------
    2422              :   !scalars
    2423              :   integer,intent(in) :: usepaw
    2424              :   type(dataset_type),intent(in) :: dtset
    2425              : 
    2426              :   !arrays
    2427              :   integer,intent(in) :: atindx(dtset%natom)
    2428              :   real(dp),intent(out) :: omlamb(3)
    2429              :   type(pawtab_type),intent(in) :: pawtab(dtset%ntypat)
    2430              : 
    2431              :   !Local variables -------------------------
    2432              :   !scalars
    2433              :   integer :: adir,iat,iatom,itypat
    2434              :   real(dp) :: lambsig
    2435              : 
    2436              : !--------------------------------------------------------------------
    2437              : 
    2438           17 :   omlamb = zero
    2439           47 :   do iat=1,dtset%natom
    2440           30 :     iatom = atindx(iat)
    2441           30 :     itypat = dtset%typat(iat)
    2442              :     ! if user input lambsig specifically in the input file, use it
    2443           30 :     if (abs(dtset%lambsig(itypat)).GT.tol8) then
    2444              :       lambsig=dtset%lambsig(itypat)
    2445              :     ! else if paw use the value read in to pawtab structure (which might well be zero)
    2446           18 :     else if (usepaw .EQ. 1) then
    2447           16 :       lambsig=pawtab(itypat)%lamb_shielding
    2448              :     else 
    2449              :       lambsig = zero
    2450              :     end if
    2451          137 :     do adir = 1, 3
    2452          120 :       omlamb(adir) = omlamb(adir) - lambsig*dtset%nucdipmom(adir,iat)
    2453              :     end do ! end loop over adir
    2454              :   end do ! end loop over iat
    2455              : 
    2456           17 : end subroutine lamb_core
    2457              : !!***
    2458              : 
    2459              : !!****f* ABINIT/nonlop_orbmag_nl
    2460              : !! NAME
    2461              : !! nonlop_orbmag_nl
    2462              : !!
    2463              : !! FUNCTION
    2464              : !! nonlop-like routine for applying the very specific H1-E_nk*S1 operator
    2465              : !! of orbital magnetism
    2466              : !!
    2467              : !! INPUTS
    2468              : !!
    2469              : !! OUTPUT
    2470              : !! |vectout> = (H1-Enk*S1)|vectin>
    2471              : !!
    2472              : !! NOTES
    2473              : !! See ZTG Eq. 42
    2474              : !! computes on-site prefac*\sum_{Rij}<bra|d_bra_dir p_i>aij<d_ket_dir p_j|ket>
    2475              : !! dnlbra = 0 if no derivative, dnlbra = adir,bdir,gdir for derivative in *dir direction
    2476              : !! dnlket = 0 if no derivative, dnlket = adir,bdir,gdir for derivative in *dir direction
    2477              : !!
    2478              : !! SOURCE
    2479              : 
    2480        12708 : subroutine nonlop_orbmag_nl(atindx,cwaveprj,dnlbra,dnlket,dterm,dtset,eignk,gs_hamk,npw_k,&
    2481        12708 :     & pawtab,vectout)
    2482              :   !Arguments ------------------------------------
    2483              :   !scalars
    2484              :   integer,intent(in) :: dnlbra,dnlket,npw_k
    2485              :   real(dp),intent(in) :: eignk
    2486              :   type(gs_hamiltonian_type),intent(inout) :: gs_hamk
    2487              :   type(dataset_type),intent(in) :: dtset
    2488              :   type(dterm_type),intent(in) :: dterm
    2489              :   !arrays
    2490              :   integer,intent(in) :: atindx(dtset%natom)
    2491              :   real(dp),intent(out) :: vectout(2,npw_k*dtset%nspinor)
    2492              :   type(pawcprj_type),intent(in) :: cwaveprj(dtset%natom,dtset%nspinor)
    2493              :   type(pawtab_type),intent(in) :: pawtab(dtset%ntypat)
    2494              : 
    2495              :   !Local variables -------------------------
    2496              :   !scalars
    2497              :   integer :: iat,iatom,il,ilmn,ipw,isp,itypat,jlmn,klmn,npwsp
    2498              :   real(dp) :: wt
    2499              :   complex(dp) :: cpj,dij,dij_cpj,proj_i
    2500              :   ! arrays
    2501              :   complex(dp),dimension(0:3) :: iexpl=(/cone,j_dpc,-cone,-j_dpc/)
    2502        12708 :   complex(dp),allocatable :: dij_data(:,:,:)
    2503              : !--------------------------------------------------------------------
    2504              :   
    2505        12708 :   npwsp = npw_k*dtset%nspinor
    2506        12708 :   wt = four_pi/SQRT(gs_hamk%ucvol)
    2507              :   
    2508        63540 :   ABI_MALLOC(dij_data,(dtset%natom,dterm%lmn2max,dterm%ndij))
    2509      2276364 :   dij_data = dterm%aij - eignk*dterm%qij
    2510              : 
    2511      8003592 :   vectout = zero
    2512        31944 :   do iat = 1, dtset%natom
    2513        19236 :     iatom = atindx(iat)
    2514        19236 :     itypat=dtset%typat(iat)
    2515        57324 :     do isp = 1, dtset%nspinor
    2516       247656 :       do ilmn = 1, pawtab(itypat)%lmn_size
    2517              : 
    2518              :         dij_cpj = czero
    2519      1827360 :         do jlmn = 1, pawtab(itypat)%lmn_size
    2520              :         
    2521      1624320 :           if (dnlket .NE. 0) then
    2522      1624320 :             cpj=CMPLX(cwaveprj(iatom,isp)%dcp(1,dnlket,jlmn),cwaveprj(iatom,isp)%dcp(2,dnlket,jlmn))
    2523              :           else
    2524            0 :             cpj=CMPLX(cwaveprj(iatom,isp)%cp(1,jlmn),cwaveprj(iatom,isp)%cp(2,jlmn))
    2525              :           end if
    2526              : 
    2527      1624320 :           klmn=MATPACK(ilmn,jlmn)
    2528      1624320 :           dij = dij_data(iatom,klmn,isp)
    2529              :           ! see note at top of file near definition of MATPACK macro
    2530      1624320 :           if (ilmn .GT. jlmn) dij = CONJG(dij)
    2531              : 
    2532      1624320 :           dij_cpj = dij_cpj + dij*cpj
    2533              : 
    2534              :           ! in ndij = 4 case, isp 1 delivers up-up, isp 2 delivers down-down
    2535      1827360 :           if (dterm%ndij == 4) then
    2536       786432 :             if (isp == 1) then
    2537       393216 :               dij = dij_data(iatom,klmn,3) ! up-down
    2538              :               ! D^ss'_ij=D^s's_ji^*
    2539       393216 :               if (ilmn .GT. jlmn) dij = CONJG(dij_data(iatom,klmn,4))
    2540       393216 :               if (dnlket .NE. 0) then
    2541       393216 :                 cpj=CMPLX(cwaveprj(iatom,2)%dcp(1,dnlket,jlmn),cwaveprj(iatom,2)%dcp(2,dnlket,jlmn))
    2542              :               else
    2543            0 :                 cpj=CMPLX(cwaveprj(iatom,2)%cp(1,jlmn),cwaveprj(iatom,2)%cp(2,jlmn))
    2544              :               end if
    2545              :             else
    2546       393216 :               dij = dij_data(iatom,klmn,4) ! down-up
    2547              :               ! D^ss'_ij=D^s's_ji^*
    2548       393216 :               if (ilmn .GT. jlmn) dij = CONJG(dij_data(iatom,klmn,3))
    2549       393216 :               if (dnlket .NE. 0) then
    2550       393216 :                 cpj=CMPLX(cwaveprj(iatom,1)%dcp(1,dnlket,jlmn),cwaveprj(iatom,1)%dcp(2,dnlket,jlmn))
    2551              :               else
    2552            0 :                 cpj=CMPLX(cwaveprj(iatom,1)%cp(1,jlmn),cwaveprj(iatom,1)%cp(2,jlmn))
    2553              :               end if
    2554              :             end if
    2555       786432 :             dij_cpj = dij_cpj + dij*cpj
    2556              :           end if
    2557              :  
    2558              :         end do !jlmn
    2559              : 
    2560       203040 :         il = MOD(pawtab(itypat)%indlmn(1,ilmn),4)
    2561     32769444 :         do ipw = 1, npw_k
    2562              :           proj_i = CMPLX(gs_hamk%ffnl_k(ipw,1+dnlbra,ilmn,itypat),0.0)*wt*CONJG(iexpl(il))*dij_cpj*&
    2563     32541024 :             & CMPLX(gs_hamk%ph3d_k(1,ipw,iatom),-gs_hamk%ph3d_k(2,ipw,iatom))
    2564              : 
    2565     32541024 :           vectout(1,npw_k*(isp-1)+ipw) = vectout(1,npw_k*(isp-1)+ipw) + REAL(proj_i)
    2566     32744064 :           vectout(2,npw_k*(isp-1)+ipw) = vectout(2,npw_k*(isp-1)+ipw) + AIMAG(proj_i)
    2567              : 
    2568              :         end do
    2569              : 
    2570              :       end do !ilmn
    2571              :     end do ! isp
    2572              :   end do !iat
    2573              : 
    2574        12708 :   ABI_SFREE(dij_data)
    2575              : 
    2576        12708 : end subroutine nonlop_orbmag_nl
    2577              : !!***
    2578              : 
    2579              : !!!****f* ABINIT/cprj_test
    2580              : !!! NAME
    2581              : !!! cprj_test
    2582              : !!!
    2583              : !!! FUNCTION
    2584              : !!! General application of <bra|p>dij<p|ket> 
    2585              : !!!
    2586              : !!! INPUTS
    2587              : !!!
    2588              : !!! OUTPUT
    2589              : !!! complex(dp) nlme
    2590              : !!!
    2591              : !!! NOTES
    2592              : !!! computes on-site prefac*\sum_{Rij}<bra|d_bra_dir p_i>aij<d_ket_dir p_j|ket>
    2593              : !!! dnlbra = 0 if no derivative, dnlbra = adir,bdir,gdir for derivative in *dir direction
    2594              : !!! dnlket = 0 if no derivative, dnlket = adir,bdir,gdir for derivative in *dir direction
    2595              : !!!
    2596              : !!! SOURCE
    2597              : !
    2598              : !subroutine cprj_test(adir,atindx,cwaveprj,dnlbra,dnlket,dterm,dtset,&
    2599              : !    & eignk,fermie,gs_hamk,npw_k,oterm,prefac,pawtab,vectin,vectout)
    2600              : !  !Arguments ------------------------------------
    2601              : !  !scalars
    2602              : !  integer,intent(in) :: adir,dnlbra,dnlket,npw_k,oterm
    2603              : !  real(dp),intent(in) :: eignk,fermie
    2604              : !  complex(dp),intent(in) :: prefac
    2605              : !  type(gs_hamiltonian_type),intent(inout) :: gs_hamk
    2606              : !  type(dataset_type),intent(in) :: dtset
    2607              : !  type(dterm_type),intent(in) :: dterm
    2608              : !  !arrays
    2609              : !  integer,intent(in) :: atindx(dtset%natom)
    2610              : !  real(dp),intent(in),pointer :: vectin(:,:)
    2611              : !  real(dp),intent(out) :: vectout(2,npw_k)
    2612              : !  type(pawcprj_type),intent(in) :: cwaveprj(dtset%natom,dtset%nspinor)
    2613              : !  type(pawtab_type),intent(in) :: pawtab(dtset%ntypat)
    2614              : !
    2615              : !  !Local variables -------------------------
    2616              : !  !scalars
    2617              : !  integer :: iat,iatom,il,ilmn,ipw,isp,itypat,jlmn,klmn,npwsp
    2618              : !  real(dp) :: wt
    2619              : !  logical :: il_parity
    2620              : !  complex(dp) :: cgfac,my_cpi,cpi,cpj,dij,dij_cpj,phfac,proj_i,scale_fac
    2621              : !  ! arrays
    2622              : !  complex(dp),dimension(0:3) :: iexpl=(/cone,j_dpc,-cone,-j_dpc/)
    2623              : !  complex(dp),allocatable :: dij_data(:,:,:)
    2624              : !!--------------------------------------------------------------------
    2625              : !  
    2626              : !  npwsp = npw_k*dtset%nspinor
    2627              : !  wt = four_pi/SQRT(gs_hamk%ucvol)
    2628              : !  
    2629              : !  ABI_MALLOC(dij_data,(dtset%natom,dterm%lmn2max,dterm%ndij))
    2630              : !  select case (oterm)
    2631              : !  !case (inlr)
    2632              : !  !  dij_data = dterm%LR(:,:,:,adir)
    2633              : !  !case (inbm)
    2634              : !  !  dij_data = dterm%BM(:,:,:,adir)
    2635              : !  case (innl)
    2636              : !    dij_data = dterm%aij - eignk*dterm%qij
    2637              : !  case (incc) 
    2638              : !    dij_data = dterm%aij + (eignk-two*fermie)*dterm%qij
    2639              : !  case (invv1)
    2640              : !    dij_data = (eignk-fermie)*dterm%qij
    2641              : !  case (invv2)
    2642              : !    dij_data = (eignk-fermie)*dterm%qij
    2643              : !  case DEFAULT
    2644              : !    dij_data = czero
    2645              : !  end select
    2646              : !
    2647              : !  !nlme = czero
    2648              : !  vectout = zero
    2649              : !  do iat = 1, dtset%natom
    2650              : !    iatom = atindx(iat)
    2651              : !    itypat=dtset%typat(iat)
    2652              : !    do isp = 1, dtset%nspinor
    2653              : !      do ilmn = 1, pawtab(itypat)%lmn_size
    2654              : !
    2655              : !        if (dnlbra .NE. 0) then
    2656              : !          cpi=CMPLX(cwaveprj(iatom,isp)%dcp(1,dnlbra,ilmn),cwaveprj(iatom,isp)%dcp(2,dnlbra,ilmn))
    2657              : !        else
    2658              : !          cpi=CMPLX(cwaveprj(iatom,isp)%cp(1,ilmn),cwaveprj(iatom,isp)%cp(2,ilmn))
    2659              : !        end if
    2660              : !
    2661              : !        ! this loop reconstructs cpi and dcpi correctly
    2662              : !        !il = MOD(pawtab(itypat)%indlmn(1,ilmn),4)
    2663              : !        !my_cpi = czero
    2664              : !        !do ipw = 1,npw_k
    2665              : !        !  cgfac=CMPLX(vectin(1,ipw),vectin(2,ipw))
    2666              : !        !  phfac=CMPLX(gs_hamk%ph3d_k(1,ipw,iatom),gs_hamk%ph3d_k(2,ipw,iatom))
    2667              : !        !  my_cpi = my_cpi + cgfac*phfac*gs_hamk%ffnl_k(ipw,1+dnlbra,ilmn,itypat)
    2668              : !        !end do
    2669              : !        !my_cpi = my_cpi*four_pi*iexpl(il)/SQRT(gs_hamk%ucvol)
    2670              : !        !write(std_out,'(a,4es16.8)')'JWZ debug cpi, mycpi : ',&
    2671              : !        !  & REAL(cpi),AIMAG(cpi),REAL(my_cpi),AIMAG(my_cpi)
    2672              : !
    2673              : !        ! |p_i> in recip space
    2674              : !        !proj_i = czero
    2675              : !        !il = pawtab(itypat)%indlmn(1,ilmn)
    2676              : !        !do ipw = 1, npw_k
    2677              : !        !  phfac=CMPLX(gs_hamk%ph3d_k(1,ipw,iatom),gs_hamk%ph3d_k(2,ipw,iatom))
    2678              : !        !  proj_i(ipw) = CMPLX(gs_hamk%ffnl_k(ipw,1+dnlbra,ilmn,itypat),0.0)*&
    2679              : !        !    &(j_dpc**il)*four_pi*CONJG(phfac)/SQRT(gs_hamk%ucvol)
    2680              : !        !end do
    2681              : !
    2682              : !        dij_cpj = czero
    2683              : !        do jlmn = 1, pawtab(itypat)%lmn_size
    2684              : !        
    2685              : !          if (dnlket .NE. 0) then
    2686              : !            cpj=CMPLX(cwaveprj(iatom,isp)%dcp(1,dnlket,jlmn),cwaveprj(iatom,isp)%dcp(2,dnlket,jlmn))
    2687              : !          else
    2688              : !            cpj=CMPLX(cwaveprj(iatom,isp)%cp(1,jlmn),cwaveprj(iatom,isp)%cp(2,jlmn))
    2689              : !          end if
    2690              : !
    2691              : !          klmn=MATPACK(ilmn,jlmn)
    2692              : !          if ( oterm == inlr ) then
    2693              : !            dij = CMPLX(dterm%ekb_LR(2*klmn-1,iatom,1,adir),dterm%ekb_LR(2*klmn,iatom,1,adir))
    2694              : !          else if ( oterm == inbm ) then
    2695              : !            dij = CMPLX(dterm%ekb_BM(2*klmn-1,iatom,1,adir),dterm%ekb_BM(2*klmn,iatom,1,adir))
    2696              : !          else 
    2697              : !            dij = dij_data(iatom,klmn,1)
    2698              : !          end if
    2699              : !          ! see note at top of file near definition of MATPACK macro
    2700              : !          if (ilmn .GT. jlmn) dij = CONJG(dij)
    2701              : !
    2702              : !          dij_cpj = dij_cpj + dij*cpj
    2703              : !
    2704              : !        end do !jlmn
    2705              : !
    2706              : !        il = MOD(pawtab(itypat)%indlmn(1,ilmn),4)
    2707              : !        do ipw = 1, npw_k
    2708              : !          proj_i = CMPLX(gs_hamk%ffnl_k(ipw,1+dnlbra,ilmn,itypat),0.0)*wt*CONJG(iexpl(il))*dij_cpj*&
    2709              : !            & CMPLX(gs_hamk%ph3d_k(1,ipw,iatom),-gs_hamk%ph3d_k(2,ipw,iatom))
    2710              : !
    2711              : !          vectout(1,ipw) = vectout(1,ipw) + REAL(proj_i)
    2712              : !          vectout(2,ipw) = vectout(2,ipw) + AIMAG(proj_i)
    2713              : !
    2714              : !        end do
    2715              : !
    2716              : !      end do !ilmn
    2717              : !    end do ! isp
    2718              : !  end do !iat
    2719              : !
    2720              : !  ABI_SFREE(dij_data)
    2721              : !
    2722              : !end subroutine cprj_test
    2723              : !!!***
    2724              : 
    2725              : !!****f* ABINIT/dterm_qij
    2726              : !! NAME
    2727              : !! dterm_qij
    2728              : !!
    2729              : !! FUNCTION
    2730              : !! Transfer pawtab%sij to dterm, as complex, solely for convenience
    2731              : !!
    2732              : !! INPUTS
    2733              : !!  atindx(natom)=index table for atoms (see gstate.f)
    2734              : !!  dtset <type(dataset_type)>=all input variables for this dataset
    2735              : !!  pawtab(dtset%ntypat) <type(pawtab_type)>=paw tabulated starting data
    2736              : !!
    2737              : !! OUTPUT
    2738              : !!
    2739              : !! SIDE EFFECTS
    2740              : !!  dterm <type(dterm_type)> data related to onsite interactions
    2741              : !!
    2742              : !! NOTES
    2743              : !! Transfer pawtab%sij to dterm, as complex, solely for convenience
    2744              : !!
    2745              : !! SOURCE
    2746              : 
    2747           16 : subroutine dterm_qij(atindx,dterm,dtset,pawtab)
    2748              : 
    2749              :   !Arguments ------------------------------------
    2750              :   !scalars
    2751              :   type(dterm_type),intent(inout) :: dterm
    2752              :   type(dataset_type),intent(in) :: dtset
    2753              : 
    2754              :   !arrays
    2755              :   integer,intent(in) :: atindx(dtset%natom)
    2756              :   type(pawtab_type),intent(in) :: pawtab(dtset%ntypat)
    2757              : 
    2758              :   !Local variables -------------------------
    2759              :   !scalars
    2760              :   integer :: iat,iatom,itypat,lmn2_size
    2761              : 
    2762              :   !arrays
    2763              : 
    2764              : !--------------------------------------------------------------------
    2765              : 
    2766         3033 :  dterm%qij = czero
    2767           44 :  do iat = 1, dtset%natom
    2768           28 :    iatom = atindx(iat)
    2769           28 :    itypat = dtset%typat(iat)
    2770           28 :    lmn2_size = pawtab(itypat)%lmn2_size
    2771              :    dterm%qij(iatom,1:lmn2_size,1) = &
    2772         1036 :      & CMPLX(pawtab(itypat)%sij(1:lmn2_size),zero)
    2773           44 :    if (dterm%ndij > 1) then
    2774              :      dterm%qij(iatom,1:lmn2_size,2) = &
    2775          370 :        & CMPLX(pawtab(itypat)%sij(1:lmn2_size),zero)
    2776              :    end if
    2777              :  end do ! iat
    2778              : 
    2779           16 :  dterm%has_qij=2
    2780              : 
    2781           16 : end subroutine dterm_qij
    2782              : !!***
    2783              : 
    2784              : !!****f* ABINIT/dterm_BM
    2785              : !! NAME
    2786              : !! dterm_BM
    2787              : !!
    2788              : !! FUNCTION
    2789              : !! Compute onsite <A0.AN>
    2790              : !!
    2791              : !! INPUTS
    2792              : !!  atindx(natom)=index table for atoms (see gstate.f)
    2793              : !!  dtset <type(dataset_type)>=all input variables for this dataset
    2794              : !!  gntselect((2*my_lmax-1)**2,my_lmax**2*(my_lmax**2+1)/2)=nonzero gaunt integral indices
    2795              : !!  gprimd(3,3)=reciprocal space lattice vectors
    2796              : !!  my_lmax=augmented l_max over all psp
    2797              : !!  pawrad(dtset%ntypat) <type(pawrad_type)>=paw radial mesh and related data
    2798              : !!  pawtab(dtset%ntypat) <type(pawtab_type)>=paw tabulated starting data
    2799              : !!  realgnt((2*my_lmax-1)**2*(my_lmax)**4)=nonzero gaunt integral values
    2800              : !!
    2801              : !! OUTPUT
    2802              : !!
    2803              : !! SIDE EFFECTS
    2804              : !!  dterm <type(dterm_type)> data related to onsite interactions
    2805              : !!
    2806              : !! NOTES
    2807              : !! ZTG23 Eq. 43
    2808              : !! this term is A0.An = \frac{1}{2}(B x r).\alpha^2(m x r) which can be rewritten
    2809              : !! as \frac{\alpha^2}{2} [B.(1-\hat{r}\hat{r}).m]/r .
    2810              : !!
    2811              : !! SOURCE
    2812              : 
    2813           16 : subroutine dterm_BM(atindx,dterm,dtset,gntselect,gprimd,my_lmax,pawrad,pawtab,realgnt)
    2814              : 
    2815              :   !Arguments ------------------------------------
    2816              :   !scalars
    2817              :   integer,intent(in) :: my_lmax
    2818              :   type(dterm_type),intent(inout) :: dterm
    2819              :   type(dataset_type),intent(in) :: dtset
    2820              : 
    2821              :   !arrays
    2822              :   integer,intent(in) :: atindx(dtset%natom)
    2823              :   integer,intent(in) :: gntselect((2*my_lmax-1)**2,my_lmax**2*(my_lmax**2+1)/2)
    2824              :   real(dp),intent(in) :: gprimd(3,3),realgnt((2*my_lmax-1)**2*(my_lmax)**4)
    2825              :   type(pawrad_type),intent(in) :: pawrad(dtset%ntypat)
    2826              :   type(pawtab_type),intent(in) :: pawtab(dtset%ntypat)
    2827              : 
    2828              :   !Local variables -------------------------
    2829              :   !scalars
    2830              :   integer :: adir,iat,iatom,itypat,gs1,gs2
    2831              :   integer :: klmn,klm,kln,mdir,mesh_size,ngnt,pwave_size
    2832              :   real(dp) :: a2,afact,intg
    2833              : 
    2834              :   !arrays
    2835              :   complex(dp) :: dij_cart(3),dij_red(3)
    2836           16 :   real(dp),allocatable :: dyadic(:,:,:),ff(:),radint(:)
    2837              : !--------------------------------------------------------------------
    2838              : 
    2839        11977 :   dterm%ekb_BM = zero
    2840              :   a2 = FineStructureConstant2
    2841              : 
    2842           44 :   do iat = 1, dtset%natom
    2843           64 :     if(.NOT. ANY(ABS(dtset%nucdipmom(:,iat))>tol8) ) cycle
    2844              : 
    2845           16 :     iatom = atindx(iat)
    2846           16 :     itypat = dtset%typat(iat)
    2847              : 
    2848           16 :     mesh_size=pawtab(itypat)%mesh_size
    2849           16 :     pwave_size=size(pawtab(itypat)%phiphj(:,1))
    2850              : 
    2851              :     ! compute angular integrals of S_i (1-rr) S_j
    2852           16 :     gs1=size(gntselect,1)
    2853           16 :     gs2=size(gntselect,2)
    2854           16 :     ngnt=size(realgnt)
    2855           48 :     ABI_MALLOC(dyadic,(3,3,gs2))
    2856           16 :     call make_dyadic(one,one,dyadic,gntselect,gs1,gs2,gs2,ngnt,realgnt)
    2857              : 
    2858              :     ! compute radial integrals of (ui*uj - tilde{ui}tilde{uj})/r
    2859           48 :     ABI_MALLOC(radint,(pawtab(itypat)%ij_size))
    2860           48 :     ABI_MALLOC(ff,(mesh_size))
    2861          176 :     do kln=1,pawtab(itypat)%ij_size
    2862              :       ff(2:pwave_size) = &
    2863              :         & (pawtab(itypat)%phiphj(2:pwave_size,kln)-pawtab(itypat)%tphitphj(2:pwave_size,kln))/&
    2864       220730 :         & (pawrad(itypat)%rad(2:pwave_size))
    2865          160 :       call pawrad_deducer0(ff,mesh_size,pawrad(itypat))
    2866          160 :       call simp_gen(intg,ff,pawrad(itypat))
    2867          176 :       radint(kln)=intg
    2868              :     end do
    2869           16 :     ABI_FREE(ff)
    2870              : 
    2871          592 :     do klmn=1, pawtab(itypat)%lmn2_size
    2872          576 :       klm  = pawtab(itypat)%indklmn(1,klmn)
    2873          576 :       kln  = pawtab(itypat)%indklmn(2,klmn)
    2874              : 
    2875          576 :       dij_cart=zero
    2876         2304 :       do adir = 1, 3 ! B field direction
    2877         7488 :         do mdir = 1, 3 ! mag dipole direction
    2878         5184 :           afact=half*a2*radint(kln)*dyadic(adir,mdir,klm)*dtset%nucdipmom(mdir,iat)
    2879         6912 :           dij_cart(adir)=dij_cart(adir)-CMPLX(afact,zero)
    2880              :         end do
    2881              :       end do
    2882              : 
    2883        14400 :       dij_red = MATMUL(TRANSPOSE(gprimd),dij_cart)
    2884              : 
    2885         2320 :       do adir=1, 3
    2886         1728 :         dterm%ekb_BM(2*klmn-1,iat,1,adir) = REAL(dij_red(adir))
    2887         1728 :         dterm%ekb_BM(2*klmn,iat,1,adir) = AIMAG(dij_red(adir))
    2888         2304 :         if (dterm%ndij > 1) then
    2889          540 :           dterm%ekb_BM(2*klmn-1,iat,2,adir) = dterm%ekb_BM(2*klmn-1,iat,1,adir)
    2890          540 :           dterm%ekb_BM(2*klmn,iat,2,adir) = dterm%ekb_BM(2*klmn,iat,1,adir)
    2891              :         end if
    2892              :       end do
    2893              : 
    2894              :     end do ! end loop over klmn
    2895              : 
    2896           16 :     ABI_FREE(dyadic)
    2897           44 :     ABI_FREE(radint)
    2898              :   end do ! end loop over iatom
    2899              : 
    2900           16 :   dterm%has_BM = 2
    2901              : 
    2902           16 : end subroutine dterm_BM
    2903              : !!***
    2904              : 
    2905              : !!****f* ABINIT/dterm_LR
    2906              : !! NAME
    2907              : !! dterm_LR
    2908              : !!
    2909              : !! FUNCTION
    2910              : !! Compute onsite <L_R/2>
    2911              : !!
    2912              : !! INPUTS
    2913              : !!  atindx(natom)=index table for atoms (see gstate.f)
    2914              : !!  dtset <type(dataset_type)>=all input variables for this dataset
    2915              : !!  gprimd(3,3)=reciprocal space lattice vectors
    2916              : !!  pawrad(dtset%ntypat) <type(pawrad_type)>=paw radial mesh and related data
    2917              : !!  pawtab(dtset%ntypat) <type(pawtab_type)>=paw tabulated starting data
    2918              : !!
    2919              : !! OUTPUT
    2920              : !!
    2921              : !! SIDE EFFECTS
    2922              : !!  dterm <type(dterm_type)> data related to onsite interactions
    2923              : !!
    2924              : !! NOTES
    2925              : !! ZTG23 text after Eq 42, the on-site angular momentum
    2926              : !!
    2927              : !! SOURCE
    2928              : 
    2929           16 : subroutine dterm_LR(atindx,dterm,dtset,gprimd,pawrad,pawtab)
    2930              : 
    2931              :   !Arguments ------------------------------------
    2932              :   !scalars
    2933              :   type(dterm_type),intent(inout) :: dterm
    2934              :   type(dataset_type),intent(in) :: dtset
    2935              : 
    2936              :   !arrays
    2937              :   integer,intent(in) :: atindx(dtset%natom)
    2938              :   real(dp),intent(in) :: gprimd(3,3)
    2939              :   type(pawrad_type),intent(in) :: pawrad(dtset%ntypat)
    2940              :   type(pawtab_type),intent(in) :: pawtab(dtset%ntypat)
    2941              : 
    2942              :   !Local variables -------------------------
    2943              :   !scalars
    2944              :   integer :: adir,iat,iatom,ilmn,il,im,itypat,jlmn,jl,jm
    2945              :   integer :: klmn,kln,mesh_size,pwave_size
    2946              :   real(dp) :: intg
    2947              :   complex(dp) :: orbl_me
    2948              :   !arrays
    2949              :   complex(dp) :: dij_cart(3),dij_red(3)
    2950           16 :   real(dp),allocatable :: ff(:)
    2951              : !--------------------------------------------------------------------
    2952              : 
    2953        11977 :   dterm%ekb_LR = zero
    2954              : 
    2955           44 :   do iat = 1, dtset%natom
    2956           28 :     iatom = atindx(iat)
    2957           28 :     itypat = dtset%typat(iat)
    2958           28 :     mesh_size=pawtab(itypat)%mesh_size
    2959           28 :     pwave_size=size(pawtab(itypat)%phiphj(:,1))
    2960           84 :     ABI_MALLOC(ff,(mesh_size))
    2961         1036 :     do klmn=1, pawtab(itypat)%lmn2_size
    2962              : 
    2963         1008 :       ilmn = pawtab(itypat)%indklmn(7,klmn)
    2964         1008 :       il=pawtab(itypat)%indlmn(1,ilmn)
    2965         1008 :       im=pawtab(itypat)%indlmn(2,ilmn)
    2966              : 
    2967         1008 :       jlmn = pawtab(itypat)%indklmn(8,klmn)
    2968         1008 :       jl=pawtab(itypat)%indlmn(1,jlmn)
    2969         1008 :       jm=pawtab(itypat)%indlmn(2,jlmn)
    2970              : 
    2971         1008 :       if ( il /= jl ) cycle ! <l'm'|L|lm> = 0 if l' /= l
    2972          672 :       if ( il == 0 ) cycle ! <00|L|00> = 0
    2973              : 
    2974          588 :       kln = pawtab(itypat)%indklmn(2,klmn)
    2975       815157 :       ff=0
    2976       814569 :       ff(2:pwave_size) = pawtab(itypat)%phiphj(2:pwave_size,kln)-pawtab(itypat)%tphitphj(2:pwave_size,kln)
    2977          588 :       call pawrad_deducer0(ff,mesh_size,pawrad(itypat))
    2978          588 :       call simp_gen(intg,ff,pawrad(itypat))
    2979              : 
    2980         2352 :       do adir = 1, 3
    2981              :       ! compute <L_dir>/2
    2982         1764 :         call slxyzs(il,im,adir,jl,jm,orbl_me)
    2983         2352 :         dij_cart(adir) = -half*orbl_me*intg
    2984              :       end do ! end loop over adir
    2985              : 
    2986              :       ! convert to crystal frame
    2987        14700 :       dij_red = MATMUL(TRANSPOSE(gprimd),dij_cart)
    2988              : 
    2989         2968 :       do adir = 1, 3
    2990         1764 :         dterm%ekb_LR(2*klmn-1,iat,1,adir) = REAL(dij_red(adir))
    2991         1764 :         dterm%ekb_LR(2*klmn,iat,1,adir) = AIMAG(dij_red(adir))
    2992         2352 :         if (dterm%ndij > 1) then
    2993          630 :           dterm%ekb_LR(2*klmn-1,iat,2,adir) = dterm%ekb_LR(2*klmn-1,iat,1,adir)
    2994          630 :           dterm%ekb_LR(2*klmn,iat,2,adir) = dterm%ekb_LR(2*klmn,iat,1,adir)
    2995              :         end if
    2996              :       end do
    2997              :     end do ! end loop over klmn
    2998           44 :     ABI_FREE(ff)
    2999              :   end do ! end loop over itypat
    3000              : 
    3001           16 :   dterm%has_LR = 2
    3002              : 
    3003           16 : end subroutine dterm_LR
    3004              : !!***
    3005              : 
    3006              : !!****f* ABINIT/orbmag_output
    3007              : !! NAME
    3008              : !! orbmag_output
    3009              : !!
    3010              : !! FUNCTION
    3011              : !! Only printing. This routine outputs orbmag terms to the normal abinit output file
    3012              : !!
    3013              : !! INPUTS
    3014              : !!  dtset <type(dataset_type)>=all input variables for this dataset
    3015              : !!  omlamb(3)=Lamb shielding
    3016              : !!
    3017              : !! OUTPUT
    3018              : !!
    3019              : !! SIDE EFFECTS
    3020              : !!
    3021              : !! SOURCE
    3022              : 
    3023           17 : subroutine orbmag_output(self,dtset,omlamb)
    3024              : 
    3025              :  !Arguments ------------------------------------
    3026              :  !scalars
    3027              :  class(orbmag_mesh_type),intent(inout),target :: self
    3028              :  type(dataset_type),intent(in) :: dtset
    3029              : 
    3030              :  !arrays
    3031              :  real(dp),intent(in) :: omlamb(3)
    3032              : 
    3033              :  !Local variables -------------------------
    3034              :  !scalars
    3035              :  integer :: adir,iband,isppol,iterms
    3036              :  character(len=500) :: message
    3037              : 
    3038              :  !arrays
    3039           17 :  real(dp) :: berry_bb(dtset%mband,3),berry_total(3),orbmag_bb(dtset%mband,3),orbmag_total(3)
    3040              : 
    3041              :  ! ***********************************************************************
    3042              : 
    3043          332 :  orbmag_bb=zero;orbmag_total=zero
    3044          119 :  do iterms = 1,orbmag_nterms
    3045          408 :    orbmag_total(1:3)=orbmag_total(1:3) + self%orbmag_trace(1:3,iterms)
    3046          227 :    do isppol = 1, dtset%nsppol
    3047          762 :      do iband=1, dtset%mband
    3048         2316 :        orbmag_bb(iband,1:3) = orbmag_bb(iband,1:3) + self%orbmag_terms(iband,isppol,1:3,iterms)
    3049              :      end do ! iband
    3050              :    end do ! isppol
    3051              :  end do
    3052              : 
    3053           68 :  orbmag_total=orbmag_total+omlamb
    3054              : 
    3055          332 :  berry_bb=zero;berry_total=zero
    3056           51 :  do iterms = 1,chern_nterms
    3057          136 :    berry_total(1:3)=berry_total(1:3) + self%chern_trace(1:3,iterms)
    3058           87 :    do isppol = 1, dtset%nsppol
    3059          254 :      do iband=1, dtset%mband
    3060          772 :        berry_bb(iband,1:3) = berry_bb(iband,1:3) + self%chern_terms(iband,isppol,1:3,iterms)
    3061              :      end do ! iband
    3062              :    end do ! isppol
    3063              :  end do
    3064              : 
    3065           17 :  write(message,'(a,a,a)')ch10,'====================================================',ch10
    3066           17 :  call wrtout(ab_out,message,'COLL')
    3067              : 
    3068           17 :  write(message,'(a,a)')' Orbital magnetic moment computed with DFPT derivative wavefunctions ',ch10
    3069           17 :  call wrtout(ab_out,message,'COLL')
    3070              : 
    3071           17 :  write(message,'(a)')' Orbital magnetic moment, Cartesian directions : '
    3072           17 :  call wrtout(ab_out,message,'COLL')
    3073           17 :  write(message,'(3es16.8)') (orbmag_total(adir),adir=1,3)
    3074           17 :  call wrtout(ab_out,message,'COLL')
    3075           17 :  write(message,'(a)')ch10
    3076           17 :  call wrtout(ab_out,message,'COLL')
    3077           17 :  write(message,'(a)')' Chern vector, Cartesian directions : '
    3078           17 :  call wrtout(ab_out,message,'COLL')
    3079           17 :  write(message,'(3es16.8)') (berry_total(adir),adir=1,3)
    3080           17 :  call wrtout(ab_out,message,'COLL')
    3081              : 
    3082           17 :  if(abs(dtset%orbmag) .GE. 2) then
    3083           17 :    write(message,'(a)')ch10
    3084           17 :    call wrtout(ab_out,message,'COLL')
    3085           17 :    write(message,'(a)')' Orbital magnetic moment, term-by-term breakdown : '
    3086           17 :    call wrtout(ab_out,message,'COLL')
    3087           68 :    write(message,'(a,3es16.8)') '      rho(1) CC : ',(self%orbmag_trace(adir,incc),adir=1,3)
    3088           17 :    call wrtout(ab_out,message,'COLL')
    3089           68 :    write(message,'(a,3es16.8)') '     rho(1) VV1 : ',(self%orbmag_trace(adir,invv1),adir=1,3)
    3090           17 :    call wrtout(ab_out,message,'COLL')
    3091           68 :    write(message,'(a,3es16.8)') '     rho(1) VV2 : ',(self%orbmag_trace(adir,invv2),adir=1,3)
    3092           17 :    call wrtout(ab_out,message,'COLL')
    3093           68 :    write(message,'(a,3es16.8)') '      rho(0) NL : ',(self%orbmag_trace(adir,innl),adir=1,3)
    3094           17 :    call wrtout(ab_out,message,'COLL')
    3095           68 :    write(message,'(a,3es16.8)') '          <L_R> : ',(self%orbmag_trace(adir,inlr),adir=1,3)
    3096           17 :    call wrtout(ab_out,message,'COLL')
    3097           68 :    write(message,'(a,3es16.8)') '        <A0.An> : ',(self%orbmag_trace(adir,inbm),adir=1,3)
    3098           17 :    call wrtout(ab_out,message,'COLL')
    3099           17 :    write(message,'(a,3es16.8)') '    Lamb (core) : ',(omlamb(adir),adir=1,3)
    3100           17 :    call wrtout(ab_out,message,'COLL')
    3101           17 :    write(message,'(a)')ch10
    3102           17 :    call wrtout(ab_out,message,'COLL')
    3103           17 :    write(message,'(a)')' Chern vector, term-by-term breakdown : '
    3104           17 :    call wrtout(ab_out,message,'COLL')
    3105           68 :    write(message,'(a,3es16.8)') '       Chern CC : ',(self%chern_trace(adir,ibcc),adir=1,3)
    3106           17 :    call wrtout(ab_out,message,'COLL')
    3107           68 :    write(message,'(a,3es16.8)') '      Chern VV1 : ',(self%chern_trace(adir,ibvv1),adir=1,3)
    3108           17 :    call wrtout(ab_out,message,'COLL')
    3109              :  end if
    3110              : 
    3111           17 :  if(abs(dtset%orbmag) .EQ. 4) then
    3112            1 :    write(message,'(a)')ch10
    3113            1 :    call wrtout(ab_out,message,'COLL')
    3114            1 :    write(message,'(a)')' Integrals of densities on real space mesh, should be close to values above : '
    3115            1 :    call wrtout(ab_out,message,'COLL')
    3116            4 :    write(message,'(a,3es16.8)') '      rho(1) CC : ',(self%rmesh_int(adir,incc),adir=1,3)
    3117            1 :    call wrtout(ab_out,message,'COLL')
    3118            4 :    write(message,'(a,3es16.8)') '     rho(1) VV1 : ',(self%rmesh_int(adir,invv1),adir=1,3)
    3119            1 :    call wrtout(ab_out,message,'COLL')
    3120            4 :    write(message,'(a,3es16.8)') '     rho(1) VV2 : ',(self%rmesh_int(adir,invv2),adir=1,3)
    3121            1 :    call wrtout(ab_out,message,'COLL')
    3122            4 :    write(message,'(a,3es16.8)') '      rho(0) NL : ',(self%rmesh_int(adir,innl),adir=1,3)
    3123            1 :    call wrtout(ab_out,message,'COLL')
    3124            4 :    write(message,'(a,3es16.8)') '          <L_R> : ',(self%rmesh_int(adir,inlr),adir=1,3)
    3125            1 :    call wrtout(ab_out,message,'COLL')
    3126            4 :    write(message,'(a,3es16.8)') '        <A0.An> : ',(self%rmesh_int(adir,inbm),adir=1,3)
    3127            1 :    call wrtout(ab_out,message,'COLL')
    3128              :  end if
    3129              : 
    3130              : 
    3131           17 :  write(message,'(a,a,a)')ch10,'====================================================',ch10
    3132           17 :  call wrtout(ab_out,message,'COLL')
    3133              : 
    3134           17 : end subroutine orbmag_output
    3135              : !!***
    3136              : 
    3137              : !!****f* ABINIT/dterm_free
    3138              : !! NAME
    3139              : !! dterm_free
    3140              : !!
    3141              : !! FUNCTION
    3142              : !! free space in dterm_type
    3143              : !!
    3144              : !! SOURCE
    3145              : 
    3146           16 : subroutine dterm_free(self)
    3147              : 
    3148              :   !Arguments ------------------------------------
    3149              :   !scalars
    3150              :   class(dterm_type),intent(inout),target :: self
    3151              : !--------------------------------------------------------------------
    3152              : 
    3153           16 :   ABI_SFREE(self%aij)
    3154           16 :   self%has_aij=0
    3155              : 
    3156           16 :   ABI_SFREE(self%qij)
    3157           16 :   self%has_qij=0
    3158              : 
    3159           16 :   ABI_SFREE(self%ekb_LR)
    3160           16 :   self%has_LR=0
    3161              : 
    3162           16 :   ABI_SFREE(self%ekb_BM)
    3163           16 :   self%has_BM=0
    3164              : 
    3165           16 : end subroutine dterm_free
    3166              : !!***
    3167              : 
    3168              : !!****f* ABINIT/dterm_init
    3169              : !! NAME
    3170              : !! dterm_init
    3171              : !!
    3172              : !! FUNCTION
    3173              : !! allocate space in dterm_type
    3174              : !!
    3175              : !! INPUTS
    3176              : !!  lmnmax=max value of lmn over all psps
    3177              : !!  lmn2max=max value of lmn2 over all psps
    3178              : !!  natom=number of atoms in cell
    3179              : !!  ndij=spin channels in dij
    3180              : !!
    3181              : !! OUTPUT
    3182              : !!
    3183              : !! SIDE EFFECTS
    3184              : !! dterm <type(dterm_type)> data related to onsite interactions
    3185              : !!
    3186              : !! SOURCE
    3187              : 
    3188           16 : subroutine dterm_init(self,lmnmax,lmn2max,natom,ndij)
    3189              : 
    3190              :   !Arguments ------------------------------------
    3191              :   !scalars
    3192              :   class(dterm_type),intent(inout),target :: self
    3193              :   integer,intent(in) :: lmnmax,lmn2max,natom,ndij
    3194              : !--------------------------------------------------------------------
    3195              : 
    3196           16 :   self%lmnmax = lmnmax
    3197           16 :   self%lmn2max = lmn2max
    3198           16 :   self%natom = natom
    3199           16 :   self%ndij = ndij
    3200              : 
    3201           80 :   ABI_REMALLOC(self%aij,(natom,lmn2max,ndij))
    3202           16 :   self%has_aij=1
    3203              : 
    3204           64 :   ABI_REMALLOC(self%qij,(natom,lmn2max,ndij))
    3205           16 :   self%has_qij=1
    3206              : 
    3207           96 :   ABI_REMALLOC(self%ekb_LR,(2*lmn2max,natom,ndij,3))
    3208           16 :   self%has_LR=1
    3209              : 
    3210           64 :   ABI_REMALLOC(self%ekb_BM,(2*lmn2max,natom,ndij,3))
    3211           16 :   self%has_BM=1
    3212              : 
    3213           16 : end subroutine dterm_init
    3214              : !!***
    3215              : 
    3216              : !!****f* ABINIT/orbmag_init
    3217              : !! NAME
    3218              : !! orbmag_init
    3219              : !!
    3220              : !! FUNCTION
    3221              : !! allocate space in orbmag_mesh_type
    3222              : !!
    3223              : !! INPUTS
    3224              : !!  dtset <type(dataset_type)>=all input variables for this dataset
    3225              : !!
    3226              : !! OUTPUT
    3227              : !!
    3228              : !! SIDE EFFECTS
    3229              : !! orbmag_mesh <type(orbmag_mesh_type)> data related to orbmag terms on kpt mesh
    3230              : !!
    3231              : !! SOURCE
    3232              : 
    3233           17 : subroutine orbmag_init(self,dtset)
    3234              : 
    3235              :   !Arguments ------------------------------------
    3236              :   !scalars
    3237              :   class(orbmag_mesh_type),intent(inout),target :: self
    3238              :   type(dataset_type),intent(in) :: dtset
    3239              : !--------------------------------------------------------------------
    3240              : 
    3241           17 :   self%mband = dtset%mband
    3242           17 :   self%nkpt = dtset%nkpt
    3243           17 :   self%nsppol = dtset%nsppol
    3244           17 :   self%natom = dtset%natom
    3245           17 :   self%ntypat = dtset%ntypat
    3246           17 :   self%n4=dtset%ngfft(4)
    3247           17 :   self%n5=dtset%ngfft(5)
    3248           17 :   self%n6=dtset%ngfft(6)
    3249           17 :   self%chern_nterms = chern_nterms
    3250           17 :   self%orbmag_nterms = orbmag_nterms
    3251              : 
    3252           51 :   ABI_REMALLOC(self%lambsig,(self%ntypat))
    3253           51 :   ABI_REMALLOC(self%nucdipmom,(3,self%natom))
    3254          119 :   ABI_REMALLOC(self%cmesh,(self%mband,self%nkpt,self%nsppol,3,chern_nterms))
    3255        30687 :   self%cmesh=zero
    3256          102 :   ABI_REMALLOC(self%chern_terms,(dtset%mband,dtset%nsppol,3,chern_nterms))
    3257          813 :   self%chern_terms=zero
    3258           17 :   ABI_REMALLOC(self%chern_trace,(3,chern_nterms))
    3259          153 :   self%chern_trace=zero
    3260          119 :   ABI_REMALLOC(self%omesh,(self%mband,self%nkpt,self%nsppol,3,orbmag_nterms))
    3261        92027 :   self%omesh=zero
    3262           85 :   ABI_REMALLOC(self%orbmag_terms,(dtset%mband,dtset%nsppol,3,orbmag_nterms))
    3263         2405 :   self%orbmag_terms=zero
    3264           17 :   ABI_REMALLOC(self%orbmag_trace,(3,orbmag_nterms))
    3265          425 :   self%orbmag_trace=zero
    3266           17 :   if (dtset%orbmag .EQ. 4) then
    3267            7 :     ABI_REMALLOC(self%rmesh,(self%n4,self%n5,self%n6,3,orbmag_nterms))
    3268      1677535 :     self%rmesh=zero
    3269            1 :     ABI_REMALLOC(self%rmesh_int,(3,orbmag_nterms))
    3270           25 :     self%rmesh_int=zero
    3271              :   end if
    3272              : 
    3273           17 : end subroutine orbmag_init
    3274              : !!***
    3275              : 
    3276              : !!****f* ABINIT/orbmag_free
    3277              : !! NAME
    3278              : !! orbmag_free
    3279              : !!
    3280              : !! FUNCTION
    3281              : !! free space in orbmag_mesh_type
    3282              : !!
    3283              : !! SIDE EFFECTS
    3284              : !! orbmag_mesh <type(orbmag_mesh_type)> data related to orbmag terms on kpt mesh
    3285              : !!
    3286              : !! SOURCE
    3287              : 
    3288           17 : subroutine orbmag_free(self)
    3289              : 
    3290              :   !Arguments ------------------------------------
    3291              :   !scalars
    3292              :   class(orbmag_mesh_type),intent(inout),target :: self
    3293              : !--------------------------------------------------------------------
    3294              : 
    3295           17 :     ABI_SFREE(self%lambsig)
    3296           17 :     ABI_SFREE(self%nucdipmom)
    3297           17 :     ABI_SFREE(self%cmesh)
    3298           17 :     ABI_SFREE(self%chern_terms)
    3299           17 :     ABI_SFREE(self%chern_trace)
    3300           17 :     ABI_SFREE(self%omesh)
    3301           17 :     ABI_SFREE(self%orbmag_terms)
    3302           17 :     ABI_SFREE(self%orbmag_trace)
    3303           17 :     ABI_SFREE(self%rmesh)
    3304           17 :     ABI_SFREE(self%rmesh_int)
    3305              : 
    3306           17 : end subroutine orbmag_free
    3307              : !!***
    3308              : 
    3309              : !!****f* ABINIT/dterm_aij
    3310              : !! NAME
    3311              : !! dterm_aij
    3312              : !!
    3313              : !! FUNCTION
    3314              : !! transfer paw_ij to dterm%aij in more convenient format
    3315              : !!
    3316              : !! INPUTS
    3317              : !!  atindx(natom)=index table for atoms (see gstate.f)
    3318              : !!  dtset <type(dataset_type)>=all input variables for this dataset
    3319              : !!  paw_ij(dtset%natom) <type(paw_ij_type)>=paw arrays given on (i,j) channels for the GS
    3320              : !!  pawtab(dtset%ntypat) <type(pawtab_type)>=paw tabulated starting data
    3321              : !!
    3322              : !! OUTPUT
    3323              : !!
    3324              : !! SIDE EFFECTS
    3325              : !! dterm <type(dterm_type)> data related to onsite interactions
    3326              : !!
    3327              : !! SOURCE
    3328              : 
    3329           16 : subroutine dterm_aij(atindx,dterm,dtset,paw_ij,pawtab)
    3330              : 
    3331              :   !Arguments ------------------------------------
    3332              :   !scalars
    3333              :   type(dterm_type),intent(inout) :: dterm
    3334              :   type(dataset_type),intent(in) :: dtset
    3335              : 
    3336              :   !arrays
    3337              :   integer,intent(in) :: atindx(dtset%natom)
    3338              :   type(paw_ij_type),intent(inout) :: paw_ij(dtset%natom)
    3339              :   type(pawtab_type),intent(in) :: pawtab(dtset%ntypat)
    3340              : 
    3341              :   !Local variables -------------------------
    3342              :   !scalars
    3343              :   integer :: iat,iatom,idij,itypat,klmn
    3344              :   !arrays
    3345              : !--------------------------------------------------------------------
    3346              : 
    3347         3033 :   dterm%aij = czero
    3348              : 
    3349              :   ! note that paw_ij has atoms ordered by input, while
    3350              :   ! we would like to order by groups of atoms with atindx
    3351           44 :   do iat=1,dtset%natom
    3352           28 :     iatom=atindx(iat)
    3353           28 :     itypat=dtset%typat(iat)
    3354         1052 :     do klmn=1,pawtab(itypat)%lmn2_size
    3355         2980 :       do idij = 1, dterm%ndij
    3356         2952 :         if (paw_ij(iat)%cplex_dij .EQ. 2) then
    3357              :           dterm%aij(iatom,klmn,idij) = &
    3358         1944 :             & CMPLX(paw_ij(iat)%dij(2*klmn-1,idij),paw_ij(iat)%dij(2*klmn,idij))
    3359              :         else
    3360            0 :           dterm%aij(iatom,klmn,idij) = CMPLX(paw_ij(iat)%dij(klmn,idij),zero)
    3361              :         end if
    3362              :       end do ! idij
    3363              :     end do ! klmn
    3364              :   end do ! iat
    3365              : 
    3366           16 :   dterm%has_aij = 2
    3367              : 
    3368           16 : end subroutine dterm_aij
    3369              : 
    3370              : !!***
    3371              : 
    3372              : !!****f* ABINIT/make_d
    3373              : !! NAME
    3374              : !! make_d
    3375              : !!
    3376              : !! FUNCTION
    3377              : !! this is a driver to compute different onsite terms, in convenient (complex) format
    3378              : !!
    3379              : !! INPUTS
    3380              : !!  atindx(natom)=index table for atoms (see gstate.f)
    3381              : !!  dtset <type(dataset_type)>=all input variables for this dataset
    3382              : !!  gprimd(3,3)=reciprocal space lattice vectors
    3383              : !!  paw_ij(dtset%natom) <type(paw_ij_type)>=paw arrays given on (i,j) channels for the GS
    3384              : !!  pawrad(dtset%ntypat) <type(pawrad_type)>=paw radial mesh and related data
    3385              : !!  pawtab(dtset%ntypat) <type(pawtab_type)>=paw tabulated starting data
    3386              : !!  psps <type(pseudopotential_type)>=variables related to pseudopotentials
    3387              : !!
    3388              : !! OUTPUT
    3389              : !!
    3390              : !! SIDE EFFECTS
    3391              : !!  dterm <type(dterm_type)> data related to onsite interactions
    3392              : !!
    3393              : !! SOURCE
    3394              : 
    3395           16 : subroutine make_d(atindx,dterm,dtset,gprimd,paw_ij,pawrad,pawtab,psps)
    3396              : 
    3397              :   !Arguments ------------------------------------
    3398              :   !scalars
    3399              :   type(dterm_type),intent(inout) :: dterm
    3400              :   type(dataset_type),intent(in) :: dtset
    3401              :   type(pseudopotential_type), intent(in) :: psps
    3402              : 
    3403              :   !arrays
    3404              :   integer,intent(in) :: atindx(dtset%natom)
    3405              :   real(dp),intent(in) :: gprimd(3,3)
    3406              :   type(paw_ij_type),intent(inout) :: paw_ij(dtset%natom)
    3407              :   type(pawrad_type),intent(in) :: pawrad(dtset%ntypat)
    3408              :   type(pawtab_type),intent(in) :: pawtab(dtset%ntypat)
    3409              : 
    3410              :   !Local variables -------------------------
    3411              :   !scalars
    3412              :   integer :: my_lmax,ngnt
    3413              : 
    3414              :   !arrays
    3415              :   integer,allocatable :: gntselect(:,:)
    3416              :   real(dp),allocatable :: realgnt(:)
    3417              : !--------------------------------------------------------------------
    3418              : 
    3419              :  ! make Gaunt integrals
    3420           16 :  my_lmax = psps%mpsang + 1
    3421           48 :  ABI_MALLOC(realgnt,((2*my_lmax-1)**2*(my_lmax)**4))
    3422           64 :  ABI_MALLOC(gntselect,((2*my_lmax-1)**2,my_lmax**2*(my_lmax**2+1)/2))
    3423           16 :  call realgaunt(my_lmax,ngnt,gntselect,realgnt)
    3424              : 
    3425              :  ! generate d terms
    3426              : 
    3427              :  ! normal PAW sij overlap, in complex form because it's convenient
    3428           16 :  call dterm_qij(atindx,dterm,dtset,pawtab)
    3429              : 
    3430              :  ! onsite angular momentum expectation values
    3431           16 :  call dterm_LR(atindx,dterm,dtset,gprimd,pawrad,pawtab)
    3432              : 
    3433              :  ! onsite <A_0.A_n> interaction between magnetic field and nuclear dipole
    3434              :  !call dterm_BM(atindx,dterm,dtset,gntselect,gprimd,my_lmax,pawrad,pawtab,realgnt)
    3435           16 :  call dterm_BM(atindx,dterm,dtset,gntselect,gprimd,my_lmax,pawrad,pawtab,realgnt)
    3436              : 
    3437              :  ! transfers paw_ij to dterm%aij because it's convenient
    3438           16 :  call dterm_aij(atindx,dterm,dtset,paw_ij,pawtab)
    3439              : 
    3440           16 :  ABI_FREE(realgnt)
    3441           16 :  ABI_FREE(gntselect)
    3442              : 
    3443           16 : end subroutine make_d
    3444              : !!***
    3445              : 
    3446              : !!****f* ABINIT/me_proj_mesh
    3447              : !! NAME
    3448              : !! me_proj_mesh
    3449              : !!
    3450              : !! FUNCTION
    3451              : !! compute realspace mesh for matrix element
    3452              : !!
    3453              : !! INPUTS
    3454              : !!
    3455              : !! OUTPUT
    3456              : !!
    3457              : !! SIDE EFFECTS
    3458              : !! 
    3459              : !! CHILDREN
    3460              : !!
    3461              : !! SOURCE
    3462              : 
    3463           84 : subroutine me_proj_mesh(bra,fofr,gs_hamk,ket,mpi_enreg,n4,n5,n6,ndat,npw_k,scalar_factor)
    3464              : 
    3465              :   !Arguments ------------------------------------
    3466              :   !scalars
    3467              :   integer,intent(in) :: n4,n5,n6,ndat,npw_k
    3468              :   complex(dp),intent(in) :: scalar_factor
    3469              :   type(gs_hamiltonian_type),intent(inout) :: gs_hamk
    3470              :   type(MPI_type), intent(inout) :: mpi_enreg
    3471              :   !arrays
    3472              :   real(dp),intent(out) :: fofr(2,n4,n5,n6*ndat)
    3473              :   real(dp),intent(in),pointer :: bra(:,:),ket(:,:)
    3474              : 
    3475              :   !Local variables -------------------------
    3476              :   !scalars
    3477              :   integer :: fourwf_cplex,fourwf_option,tim_fourwf
    3478              :   real(dp) :: density_norm,weight_i,weight_r
    3479              :   !arrays
    3480           84 :   real(dp),allocatable :: fbra(:,:,:,:),fket(:,:,:,:),denpot(:,:),fofgout(:,:)
    3481              : 
    3482              : !--------------------------------------------------------------------
    3483              : 
    3484          420 :   ABI_MALLOC(fket,(2,n4,n5,n6*ndat))
    3485          336 :   ABI_MALLOC(fbra,(2,n4,n5,n6*ndat))
    3486           84 :   fourwf_cplex = 1
    3487           84 :   fourwf_option = 0
    3488           84 :   tim_fourwf = 1
    3489              :   call fourwf(fourwf_cplex,denpot,ket,fofgout,fket,gs_hamk%gbound_k,&
    3490              :     & gs_hamk%gbound_k,gs_hamk%istwf_k,gs_hamk%kg_k,gs_hamk%kg_k,&
    3491              :     & gs_hamk%mgfft,mpi_enreg,ndat,gs_hamk%ngfft,npw_k,npw_k,&
    3492           84 :     & n4,n5,n6,fourwf_option,tim_fourwf,weight_r,weight_i)
    3493              :   call fourwf(fourwf_cplex,denpot,bra,fofgout,fbra,gs_hamk%gbound_k,&
    3494              :     & gs_hamk%gbound_k,gs_hamk%istwf_k,gs_hamk%kg_k,gs_hamk%kg_k,&
    3495              :     & gs_hamk%mgfft,mpi_enreg,ndat,gs_hamk%ngfft,npw_k,npw_k,&
    3496           84 :     & n4,n5,n6,fourwf_option,tim_fourwf,weight_r,weight_i)
    3497              : 
    3498              :  ! now form scalar*conj(bra)*ket
    3499              :  fofr(1,:,:,:) =  &
    3500              :    &  REAL(scalar_factor)*( fbra(1,:,:,:)*fket(1,:,:,:)+fbra(2,:,:,:)*fket(2,:,:,:)) - &
    3501      7828464 :    & AIMAG(scalar_factor)*(-fbra(2,:,:,:)*fket(1,:,:,:)+fbra(1,:,:,:)*fket(2,:,:,:))
    3502              :  fofr(2,:,:,:) =  &
    3503              :    & AIMAG(scalar_factor)*( fbra(1,:,:,:)*fket(1,:,:,:)+fbra(2,:,:,:)*fket(2,:,:,:)) + &
    3504      7828464 :    &  REAL(scalar_factor)*(-fbra(2,:,:,:)*fket(1,:,:,:)+fbra(1,:,:,:)*fket(2,:,:,:))
    3505              : 
    3506           84 :   density_norm=gs_hamk%ucvol/gs_hamk%nfft
    3507     23137464 :   fofr = fofr*density_norm
    3508              : 
    3509           84 :   ABI_SFREE(fket)
    3510           84 :   ABI_SFREE(fbra)
    3511              : 
    3512           84 : end subroutine me_proj_mesh
    3513              : !!***
    3514              : 
    3515              : !!****f* ABINIT/local_fermie
    3516              : !! NAME
    3517              : !! local_fermie
    3518              : !!
    3519              : !! FUNCTION
    3520              : !! estimate Fermi energy as max value of all occupied bands/kpts
    3521              : !!
    3522              : !! INPUTS
    3523              : !!  dtset <type(dataset_type)>=all input variables for this dataset
    3524              : !!  eigen0(dtset%mband*dtset%nkpt*dtset%nsppol)=ground state eigenvalues at each band and kpt
    3525              : !!  mpi_enreg<type(MPI_type)>=information about MPI parallelization
    3526              : !!  occ(dtset%mband*dtset%nkpt*dtset%nsppol)=occup number for each band (often 2) at each k point
    3527              : !!
    3528              : !! OUTPUT
    3529              : !!  fermie=maximum energy (real(dp)) found over all occupied input bands
    3530              : !!
    3531              : !! CHILDREN
    3532              : !!
    3533              : !! SOURCE
    3534              : 
    3535           17 : subroutine local_fermie(dtset,ebands_k,fermie,mpi_enreg)
    3536              : 
    3537              :   !Arguments ------------------------------------
    3538              :   !scalars
    3539              :   real(dp),intent(out) :: fermie
    3540              :   type(dataset_type),intent(in) :: dtset
    3541              :   type(ebands_t) :: ebands_k
    3542              :   type(MPI_type), intent(inout) :: mpi_enreg
    3543              : 
    3544              :   !arrays
    3545              : 
    3546              :   !Local variables -------------------------
    3547              :   !scalars
    3548              :   integer :: ierr,ikpt,isppol,me
    3549              :   integer :: nband_k,nn,nproc,spaceComm
    3550              :   real(dp) :: fermie_proc
    3551              : 
    3552              :   !arrays
    3553           17 :   real(dp),allocatable :: eig_k(:),occ_k(:)
    3554              : 
    3555              : !--------------------------------------------------------------------
    3556              : 
    3557           17 :   spaceComm=mpi_enreg%comm_cell
    3558           17 :   nproc=xmpi_comm_size(spaceComm)
    3559           17 :   me = mpi_enreg%me_kpt
    3560              : 
    3561           17 :   fermie_proc = -1.0D99
    3562           35 :   do isppol = 1, dtset%nsppol
    3563          742 :     do ikpt = 1, dtset%nkpt
    3564              : 
    3565          707 :       nband_k=dtset%nband(ikpt+(isppol-1)*dtset%nkpt)
    3566              : 
    3567              :       ! if the current kpt is not on the current processor, cycle
    3568          707 :       if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me)) cycle
    3569              : 
    3570         2121 :       ABI_MALLOC(occ_k,(nband_k))
    3571         5071 :       occ_k(:)=ebands_k%occ(1:nband_k,ikpt,isppol)
    3572              : 
    3573         1414 :       ABI_MALLOC(eig_k,(nband_k))
    3574         5071 :       eig_k(:)=ebands_k%eig(1:nband_k,ikpt,isppol)
    3575              : 
    3576         5071 :       do nn = 1, nband_k
    3577         5071 :         if ( (abs(occ_k(nn)).GT.tol8) .AND. (eig_k(nn).GT.fermie_proc) ) then
    3578          182 :           fermie_proc = eig_k(nn)
    3579              :         end if
    3580              :       end do ! nn
    3581              : 
    3582          707 :       ABI_FREE(occ_k)
    3583          725 :       ABI_FREE(eig_k)
    3584              : 
    3585              :     end do ! end loop over kpts
    3586              :   end do ! end loop over isppol
    3587              : 
    3588           17 :   call xmpi_max(fermie_proc,fermie,spaceComm,ierr)
    3589              : 
    3590           17 : end subroutine local_fermie
    3591              : !!***
    3592              : 
    3593              : !!****f* m_orbmag/orbmag_ncwrite
    3594              : !! NAME
    3595              : !! orbmag_ncwrite
    3596              : !!
    3597              : !! FUNCTION
    3598              : !!  Write orbmag_mesh contributions to netcdf file.
    3599              : !!
    3600              : !! INPUTS
    3601              : !!  crystal<crystal_t>=Object defining the unit cell and its symmetries.
    3602              : !!  dtset<dtset_type>=Dataset type
    3603              : !!  ebands<ebands_t>=Band structure data.
    3604              : !!  hdr<hdr_t>=Abinit header
    3605              : !!  orbmag_mesh<orbmag_mesh_type>=orbmag_mesh data
    3606              : !!  psps <type(pseudopotential_type)>=variables related to pseudopotentials
    3607              : !!  pawtab(ntypat*usepaw) <type(pawtab_type)>=paw tabulated starting data
    3608              : !!  ncid=NC file handle.
    3609              : !!
    3610              : !! OUTPUT
    3611              : !!  Only writing
    3612              : !!
    3613              : !! SOURCE
    3614              : 
    3615           34 : subroutine orbmag_ncwrite(crystal,dtset,ebands,hdr,ncid,orbmag_mesh)
    3616              : 
    3617              : !Arguments ------------------------------------
    3618              : !scalars
    3619              :  integer,intent(in) :: ncid
    3620              :  type(crystal_t),intent(in) :: crystal
    3621              :  type(dataset_type),intent(in) :: dtset
    3622              :  type(ebands_t),intent(in) :: ebands
    3623              :  type(hdr_type),intent(in) :: hdr
    3624              :  type(orbmag_mesh_type),intent(in) :: orbmag_mesh
    3625              : !arrays
    3626              : 
    3627              : !Local variables-------------------------------
    3628              : !scalars
    3629              :  integer :: ncerr,fform
    3630              :  real(dp) :: cpu,wall,gflops
    3631              :  logical :: has_ormesh
    3632              :  character(len=500) :: msg
    3633              : !arrays
    3634              : !*************************************************************************
    3635              : 
    3636           17 :  call cwtime(cpu, wall, gflops, "start")
    3637              : 
    3638           17 :  has_ormesh = (dtset%orbmag .EQ. 4)
    3639              : 
    3640           17 :  fform = fform_from_ext("ORBMAG.nc")
    3641           17 :  ABI_CHECK(fform /= 0, "Cannot find fform associated to ORBMAG.nc")
    3642              : 
    3643              :  ! Write header, crystal structure and band energies.
    3644           17 :  NCF_CHECK(hdr%ncwrite(ncid, fform, nc_define=.True.))
    3645           17 :  NCF_CHECK(crystal%ncwrite(ncid))
    3646           17 :  NCF_CHECK(ebands%ncwrite(ncid))
    3647              : 
    3648              :  !! Add orbmag-mesh-specific quantities
    3649              :  ncerr = nctk_def_dims(ncid, [ &
    3650              :    nctkdim_t("ntypat", dtset%ntypat),&
    3651              :    nctkdim_t("mband", orbmag_mesh%mband),&
    3652              :    nctkdim_t("nkpt", orbmag_mesh%nkpt),&
    3653              :    nctkdim_t("nsppol", orbmag_mesh%nsppol),&
    3654              :    nctkdim_t("chern_nterms", orbmag_mesh%chern_nterms),&
    3655              :    nctkdim_t("orbmag_nterms", orbmag_mesh%orbmag_nterms),&
    3656              :    nctkdim_t("ndir",3),&
    3657          153 :    nctkdim_t("natom",dtset%natom)],defmode=.True.)
    3658           17 :  NCF_CHECK(ncerr)
    3659              : 
    3660              :  !! add orbmag_rmesh_cplex,n4,n5,n6 only if orbmag_rmesh will be output
    3661           17 :  if (has_ormesh) then
    3662              :    ncerr = nctk_def_dims(ncid, [ &
    3663              :      nctkdim_t("n4", orbmag_mesh%n4),&
    3664              :      nctkdim_t("n5", orbmag_mesh%n5),&
    3665            4 :      nctkdim_t("n6", orbmag_mesh%n6)],defmode=.True.)
    3666            1 :    NCF_CHECK(ncerr)
    3667              :  endif
    3668              : 
    3669              :  ncerr = nctk_def_arrays(ncid, [&
    3670              :    nctkarr_t("chern_mesh", "dp", "mband, nkpt, nsppol, ndir, chern_nterms"),&
    3671              :    nctkarr_t("orbmag_mesh", "dp", "mband, nkpt, nsppol, ndir, orbmag_nterms"),&
    3672              :    nctkarr_t("lambsig", "dp", "ntypat"),&
    3673           85 :    nctkarr_t("nucdipmom", "dp", "ndir, natom")])
    3674           17 :  NCF_CHECK(ncerr)
    3675              : 
    3676              :  !! orbmag_rmesh dimensions, only if output
    3677           17 :  if (has_ormesh) then
    3678              :    ncerr = nctk_def_arrays(ncid, [&
    3679              :      nctkarr_t("orbmag_rmesh", "dp", "n4,n5,n6,ndir,orbmag_nterms"),&
    3680            3 :      nctkarr_t("orbmag_rmesh_int","dp","ndir,orbmag_nterms")])
    3681            1 :    NCF_CHECK(ncerr)
    3682              :  endif
    3683              : 
    3684              : 
    3685           17 :  NCF_CHECK(nctk_set_datamode(ncid))
    3686              : 
    3687           17 :  NCF_CHECK(nf90_put_var(ncid, vid("chern_mesh"), orbmag_mesh%cmesh))
    3688           17 :  NCF_CHECK(nf90_put_var(ncid, vid("orbmag_mesh"), orbmag_mesh%omesh))
    3689           17 :  NCF_CHECK(nf90_put_var(ncid, vid("nucdipmom"), orbmag_mesh%nucdipmom))
    3690           17 :  NCF_CHECK(nf90_put_var(ncid, vid("lambsig"), orbmag_mesh%lambsig))
    3691           17 :  if ( has_ormesh ) then
    3692            1 :    NCF_CHECK(nf90_put_var(ncid, vid("orbmag_rmesh"), orbmag_mesh%rmesh))
    3693            1 :    NCF_CHECK(nf90_put_var(ncid, vid("orbmag_rmesh_int"), orbmag_mesh%rmesh_int))
    3694              :  end if
    3695              : 
    3696           17 :  call cwtime(cpu,wall,gflops,"stop")
    3697           17 :  write(msg,'(2(a,f8.2),a)')" orbmag_ncwrite: cpu_time: ",cpu,"[s], walltime: ",wall," [s]"
    3698           17 :  call wrtout(std_out,msg,"PERS")
    3699              : 
    3700              : contains
    3701           70 :  integer function vid(vname)
    3702              :    character(len=*),intent(in) :: vname
    3703           70 :    vid = nctk_idname(ncid, vname)
    3704              :  end function vid
    3705              : 
    3706              : end subroutine orbmag_ncwrite
    3707              : !!***
    3708              : 
    3709            0 : end module m_orbmag
        

Generated by: LCOV version 2.3-1