LCOV - code coverage report
Current view: top level - src/78_effpot - m_slc_primitive_potential.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 65.9 % 396 261
Test Date: 2026-11-10 12:08:57 Functions: 77.8 % 27 21
Branches: 37.6 % 550 207

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_slc_primitive_potential
       2                 :             : !! NAME
       3                 :             : !! m_slc_primitive_potential
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !! This module contains the atomic structures and the spin-lattice coupling terms inside the primitive cell
       7                 :             : !! which can be directly mapped to the netcdf file. It is not for the calculation, but for constructing
       8                 :             : !! the hamiltonian in supercell.
       9                 :             : !!
      10                 :             : !! Datatypes:
      11                 :             : !!  slc_primitive_potential_t
      12                 :             : !!
      13                 :             : !! Subroutines:
      14                 :             : !!
      15                 :             : !! COPYRIGHT
      16                 :             : !! Copyright (C) 2001-2026 ABINIT group (hexu,nehelbig)
      17                 :             : !! This file is distributed under the terms of the
      18                 :             : !! GNU General Public License, see ~abinit/COPYING
      19                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
      20                 :             : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
      21                 :             : !!
      22                 :             : !! SOURCE
      23                 :             : 
      24                 :             : #if defined HAVE_CONFIG_H
      25                 :             : #include "config.h"
      26                 :             : #endif
      27                 :             : #include "abi_common.h"
      28                 :             : 
      29                 :             : module m_slc_primitive_potential
      30                 :             : 
      31                 :             :   use m_nctk
      32                 :             : #if defined HAVE_NETCDF
      33                 :             :   use netcdf
      34                 :             : #endif
      35                 :             :   use m_abicore
      36                 :             :   use defs_basis
      37                 :             :   use m_errors
      38                 :             : 
      39                 :             :   use m_slc_potential
      40                 :             :   use m_spmat_ndcoo
      41                 :             : 
      42                 :             :   use m_abstract_potential, only: abstract_potential_t
      43                 :             :   use m_dynamic_array, only: int2d_array_type
      44                 :             :   use m_mpi_scheduler, only: init_mpi_info
      45                 :             :   use m_multibinit_cell, only: mbcell_t, mbsupercell_t
      46                 :             :   use m_multibinit_dataset, only: multibinit_dtset_type
      47                 :             :   use m_primitive_potential, only: primitive_potential_t
      48                 :             : 
      49                 :             :   use m_supercell_maker, only: supercell_maker_t
      50                 :             :   use m_xmpi
      51                 :             : 
      52                 :             :   implicit none
      53                 :             : 
      54                 :             :   type, public, extends(primitive_potential_t) :: slc_primitive_potential_t
      55                 :             :      integer :: natom, nspin        ! on every mpi node
      56                 :             :      logical :: has_bilin=.False.   ! bilinear coupling term, i.e. liu
      57                 :             :      logical :: has_linquad=.False. ! spin first then lattice, i.e. niuv
      58                 :             :      logical :: has_quadlin=.False. ! spin first then lattice, i.e. oiju
      59                 :             :      logical :: has_biquad=.False.  ! biquadratic coupling term, i.e. tijuv
      60                 :             : 
      61                 :             :      !four possible coupling terms, bilinear, quadratic-linear, linear-quadratic, and biquadratic
      62                 :             :      !all the following are only on master node
      63                 :             :      type(ndcoo_mat_t) :: liu           ! parameter values
      64                 :             :      type(ndcoo_mat_t) :: niuv          ! parameter values
      65                 :             :      type(ndcoo_mat_t) :: oiju          ! parameter values
      66                 :             :      type(ndcoo_mat_t) :: tijuv         ! parameter values
      67                 :             :      !R vector of i index is always zero
      68                 :             :      type(int2d_array_type) :: lRulist  ! R vector for u index of liu
      69                 :             :      type(int2d_array_type) :: nRulist  ! R vector for u index of niuv
      70                 :             :      type(int2d_array_type) :: nRvlist  ! R vector for v index of niuv
      71                 :             :      type(int2d_array_type) :: oRjlist  ! R vector for j index of oiju
      72                 :             :      type(int2d_array_type) :: oRulist  ! R vector for u index of oiju
      73                 :             :      type(int2d_array_type) :: tRjlist  ! R vector for j index of tijuv
      74                 :             :      type(int2d_array_type) :: tRulist  ! R vector for u index of tijuv
      75                 :             :      type(int2d_array_type) :: tRvlist  ! R vector for v index of tijuv
      76                 :             : 
      77                 :             :    contains
      78                 :             :      procedure:: initialize
      79                 :             :      procedure:: finalize
      80                 :             :      procedure :: set_liu
      81                 :             :      procedure :: set_liu_1term
      82                 :             :      procedure :: set_niuv
      83                 :             :      procedure :: set_niuv_1term
      84                 :             :      procedure :: set_oiju
      85                 :             :      procedure :: set_oiju_1term
      86                 :             :      procedure :: set_tijuv
      87                 :             :      procedure :: set_tijuv_1term
      88                 :             :      procedure :: load_from_files
      89                 :             :      procedure :: read_netcdf
      90                 :             :      procedure :: read_liu
      91                 :             :      procedure :: read_niuv
      92                 :             :      procedure :: read_oiju
      93                 :             :      procedure :: read_tijuv
      94                 :             :      procedure :: fill_supercell
      95                 :             :      procedure :: fill_liu
      96                 :             :      procedure :: fill_niuv
      97                 :             :      procedure :: fill_oiju
      98                 :             :      procedure :: fill_tijuv
      99                 :             :      procedure :: set_liu_sc
     100                 :             :      procedure :: set_niuv_sc
     101                 :             :      procedure :: set_oiju_sc
     102                 :             :      procedure :: set_tijuv_sc
     103                 :             :   end type slc_primitive_potential_t
     104                 :             : 
     105                 :             : contains
     106                 :             : 
     107                 :           2 :   subroutine initialize(self, primcell)
     108                 :             :     class(slc_primitive_potential_t), intent(inout) :: self
     109                 :             :     type(mbcell_t), target, intent(inout) :: primcell
     110                 :             :     !integer, intent(in) :: nspin
     111                 :           2 :     self%primcell=>primcell
     112                 :           2 :     self%label="SLC_primitive_potential"
     113                 :           2 :     self%has_spin=.True.
     114                 :           2 :     self%has_displacement=.True.
     115                 :           2 :     self%has_strain=.False.
     116                 :           2 :     self%has_lwf=.False.
     117                 :           2 :   end subroutine initialize
     118                 :             : 
     119                 :             : 
     120                 :           2 :   subroutine finalize(self)
     121                 :             :     class(slc_primitive_potential_t), intent(inout) :: self
     122                 :           2 :     call self%oiju%finalize()
     123                 :           2 :     call self%oRjlist%finalize()
     124                 :           2 :     call self%oRulist%finalize()
     125                 :           2 :     call self%tijuv%finalize()
     126                 :           2 :     call self%tRjlist%finalize()
     127                 :           2 :     call self%tRulist%finalize()
     128                 :           2 :     call self%tRvlist%finalize()
     129                 :           2 :     nullify(self%primcell)
     130                 :           2 :     self%nspin=0
     131                 :           2 :     self%natom=0
     132                 :           2 :     self%label="Destroyed SLC_primitive_potential"
     133                 :           2 :     call self%primitive_potential_t%finalize()
     134                 :           2 :   end subroutine finalize
     135                 :             : 
     136                 :           2 :   subroutine load_from_files(self, params, fnames)
     137                 :             :     class(slc_primitive_potential_t), intent(inout) :: self
     138                 :             :     type(multibinit_dtset_type), intent(in) :: params
     139                 :             :     character(len=fnlen), intent(in) :: fnames(:)
     140                 :             :     character(len=fnlen) :: ncdf_fname
     141                 :             :     character(len=500) :: message
     142                 :             :     integer :: ii
     143                 :             :     ABI_UNUSED(fnames)
     144         [ +  - ]:           2 :     if (xmpi_comm_rank(xmpi_world)==0) then
     145                 :           2 :        ncdf_fname=params%slc_pot_fname
     146         [ +  + ]:         164 :        write(message,'(a,(81a, 80a),3a)') ch10,('=',ii=1,80),ch10,ch10,&
     147         [ +  - ]:         166 :             &     '- Reading spin-lattice coupling terms from ', trim(ncdf_fname)
     148                 :           2 :        call wrtout(ab_out,message,'COLL')
     149                 :           2 :        call wrtout(std_out,message,'COLL')
     150                 :             :     endif
     151         [ +  - ]:           2 :     call self%read_netcdf(trim(ncdf_fname)//char(0))
     152                 :             : 
     153                 :           2 :     ABI_UNUSED_A(params)
     154                 :           2 :   end subroutine load_from_files
     155                 :             : 
     156                 :             :   !-----------------------------------
     157                 :             :   ! reading parameters from ncdf file
     158                 :             :   !-----------------------------------
     159                 :           2 :   subroutine read_netcdf(self, ncdf_fname)
     160                 :             :     class(slc_primitive_potential_t), intent(inout) :: self
     161                 :             :     character (len = *),              intent(in)    :: ncdf_fname
     162                 :             : 
     163                 :             :     integer:: ncid, ncerr, comm
     164                 :             : 
     165                 :             : #if defined HAVE_NETCDF
     166                 :             : 
     167                 :           2 :     comm = xmpi_world
     168                 :             : 
     169                 :           2 :     ncerr = nctk_open_read(ncid, ncdf_fname, comm)
     170                 :             : 
     171                 :             :     ! read primcell info
     172                 :           2 :     ncerr=nctk_get_dim(ncid, "natom", self%natom)
     173                 :           2 :     ncerr=nctk_get_dim(ncid, "nspin", self%nspin)
     174                 :             : 
     175                 :             :     ! read different coupling terms if they are present in the file
     176                 :           2 :     call self%read_liu(ncid)
     177                 :           2 :     call self%read_niuv(ncid)
     178                 :           2 :     call self%read_oiju(ncid)
     179                 :           2 :     call self%read_tijuv(ncid)
     180                 :             : 
     181                 :           2 :     ncerr = nf90_close(ncid)
     182         [ -  + ]:           2 :     if(ncerr /= NF90_NOERR) then
     183                 :           0 :       write(std_out,'(A25)') 'Could not close netcdf file'
     184                 :             :     endif
     185                 :             : #else
     186                 :             :     ABI_ERROR("Multibint should be installed with netcdf enabled to run this.")
     187                 :             : 
     188                 :             : #endif
     189                 :             : 
     190                 :           2 :   end subroutine read_netcdf
     191                 :             : 
     192                 :             :   !---------------------------------------
     193                 :             :   ! reading liu parameters from ncdf file
     194                 :             :   ! TODO: test
     195                 :             :   !---------------------------------------
     196                 :           2 :   subroutine read_liu(self, ncid)
     197                 :             :     class(slc_primitive_potential_t), intent(inout) :: self
     198                 :             :     integer,                          intent(in)    :: ncid
     199                 :             : 
     200                 :             :     integer :: ncerr, dimid, ndata, varid
     201                 :           2 :     integer, allocatable :: ilist(:), ulist(:,:)
     202                 :           2 :     real(dp), allocatable :: vallist(:)
     203                 :             : #if defined HAVE_NETCDF
     204                 :             : 
     205                 :           2 :     ncerr = nf90_inq_dimid(ncid, "spin_lattice_Liu_number_of_entries", dimid)
     206         [ +  - ]:           2 :     if(ncerr /= NF90_NOERR) then
     207                 :           2 :       ndata = 0
     208                 :             :     else
     209                 :           0 :       self%has_bilin=.True.
     210                 :           0 :       ncerr = nctk_get_dim(ncid, "spin_lattice_Liu_number_of_entries", ndata)
     211   [ #  #  #  #  :           0 :       ABI_MALLOC(ilist, (ndata))
          #  #  #  #  #  
                #  #  # ]
     212   [ #  #  #  #  :           0 :       ABI_MALLOC(ulist, (4,ndata))
          #  #  #  #  #  
                #  #  # ]
     213   [ #  #  #  #  :           0 :       ABI_MALLOC(vallist, (ndata))
          #  #  #  #  #  
                #  #  # ]
     214                 :             : 
     215                 :           0 :       varid = nctk_idname(ncid, "spin_lattice_Liu_ilist")
     216                 :           0 :       ncerr = nf90_get_var(ncid, varid, ilist)
     217                 :           0 :       call netcdf_check(ncerr, "when reading Liu_ilist")
     218                 :             : 
     219                 :           0 :       varid = nctk_idname(ncid, "spin_lattice_Liu_ulist")
     220                 :           0 :       ncerr = nf90_get_var(ncid, varid, ulist)
     221                 :           0 :       call netcdf_check(ncerr, "when reading Liu_ulist")
     222                 :             : 
     223                 :           0 :       varid = nctk_idname(ncid, "spin_lattice_Liu_valuelist")
     224                 :           0 :       ncerr = nf90_get_var(ncid, varid, vallist)
     225                 :           0 :       call netcdf_check(ncerr, "when reading Liu_valuelist")
     226                 :             : 
     227                 :             :       !change units from eV to Ha and Ang to Bohr
     228         [ #  # ]:           0 :       vallist(:) = vallist(:)*eV_Ha*Bohr_Ang
     229                 :             : 
     230                 :             :       !fill the sparse matrix for liu parameters
     231                 :           0 :       call self%set_liu(ndata, ilist, ulist, vallist)
     232                 :             : 
     233         [ #  # ]:           0 :       ABI_SFREE(ilist)
     234         [ #  # ]:           0 :       ABI_SFREE(ulist)
     235         [ #  # ]:           0 :       ABI_SFREE(vallist)
     236                 :             :     endif
     237                 :             : 
     238                 :           2 :     write(std_out,'(A8,I10,A11)') 'L_iu:  ', ndata, 'terms read'
     239                 :             : #else
     240                 :             :     ABI_ERROR("Multibinit should be installed with netcdf.")
     241                 :             : #endif
     242                 :             : 
     243   [ -  +  -  +  :           2 :   end subroutine read_liu
                   -  + ]
     244                 :             : 
     245                 :             :   !----------------------------------------
     246                 :             :   ! reading niuv parameters from ncdf file
     247                 :             :   ! TODO: test
     248                 :             :   !----------------------------------------
     249                 :           2 :   subroutine read_niuv(self, ncid)
     250                 :             :     class(slc_primitive_potential_t), intent(inout) :: self
     251                 :             :     integer,                          intent(in)    :: ncid
     252                 :             : 
     253                 :             :     integer :: ncerr, dimid, ndata, varid
     254                 :           2 :     integer, allocatable :: ilist(:), ulist(:,:), vlist(:,:)
     255                 :           2 :     real(dp), allocatable :: vallist(:)
     256                 :             : #if defined HAVE_NETCDF
     257                 :           2 :     ncerr = nf90_inq_dimid(ncid, "spin_lattice_Niuv_number_of_entries", dimid)
     258         [ +  - ]:           2 :     if(ncerr /= NF90_NOERR) then
     259                 :           2 :       ndata = 0
     260                 :             :     else
     261                 :           0 :       self%has_linquad=.True.
     262                 :           0 :       ncerr = nctk_get_dim(ncid, "spin_lattice_Niuv_number_of_entries", ndata)
     263   [ #  #  #  #  :           0 :       ABI_MALLOC(ilist, (ndata))
          #  #  #  #  #  
                #  #  # ]
     264   [ #  #  #  #  :           0 :       ABI_MALLOC(ulist, (4,ndata))
          #  #  #  #  #  
                #  #  # ]
     265   [ #  #  #  #  :           0 :       ABI_MALLOC(vlist, (4,ndata))
             #  #  #  # ]
     266   [ #  #  #  #  :           0 :       ABI_MALLOC(vallist, (ndata))
          #  #  #  #  #  
                #  #  # ]
     267                 :             : 
     268                 :           0 :       varid = nctk_idname(ncid, "spin_lattice_Niuv_ilist")
     269                 :           0 :       ncerr = nf90_get_var(ncid, varid, ilist)
     270                 :           0 :       call netcdf_check(ncerr, "when reading Niuv_ilist")
     271                 :             : 
     272                 :           0 :       varid = nctk_idname(ncid, "spin_lattice_Niuv_ulist")
     273                 :           0 :       ncerr = nf90_get_var(ncid, varid, ulist)
     274                 :           0 :       call netcdf_check(ncerr, "when reading Niuv_ulist")
     275                 :             : 
     276                 :           0 :       varid = nctk_idname(ncid, "spin_lattice_Niuv_vlist")
     277                 :           0 :       ncerr = nf90_get_var(ncid, varid, ulist)
     278                 :           0 :       call netcdf_check(ncerr, "when reading Niuv_vlist")
     279                 :             : 
     280                 :           0 :       varid = nctk_idname(ncid, "spin_lattice_Niuv_valuelist")
     281                 :           0 :       ncerr = nf90_get_var(ncid, varid, vallist)
     282                 :           0 :       call netcdf_check(ncerr, "when reading Niuv_valuelist")
     283                 :             : 
     284                 :             :       !change units from eV to Ha and Ang to Bohr
     285         [ #  # ]:           0 :       vallist(:) = vallist(:)*eV_Ha*(Bohr_Ang*Bohr_Ang)
     286                 :             : 
     287                 :             :       !fill the sparse matrix for liu parameters
     288                 :           0 :       call self%set_niuv(ndata, ilist, ulist, vlist, vallist)
     289                 :             : 
     290         [ #  # ]:           0 :       ABI_SFREE(ilist)
     291         [ #  # ]:           0 :       ABI_SFREE(ulist)
     292         [ #  # ]:           0 :       ABI_SFREE(vlist)
     293         [ #  # ]:           0 :       ABI_SFREE(vallist)
     294                 :             :     endif
     295                 :             : 
     296                 :           2 :     write(std_out,'(A8,I10,A11)') 'N_iuv: ', ndata, 'terms read'
     297                 :             : #else
     298                 :             :     ABI_ERROR("Multibinit should be installed with netcdf")
     299                 :             : #endif
     300                 :             : 
     301   [ -  +  -  +  :           2 :   end subroutine read_niuv
                   -  + ]
     302                 :             : 
     303                 :             :   !---------------------------------------
     304                 :             :   ! reading oiju parameters from ncdf file
     305                 :             :   !---------------------------------------
     306                 :           2 :   subroutine read_oiju(self, ncid)
     307                 :             :     class(slc_primitive_potential_t), intent(inout) :: self
     308                 :             :     integer,                          intent(in)    :: ncid
     309                 :             : 
     310                 :             :     integer :: ncerr, dimid, ndata, varid
     311                 :           2 :     integer, allocatable :: ilist(:), jlist(:,:), ulist(:,:)
     312                 :           2 :     real(dp), allocatable :: vallist(:)
     313                 :             : 
     314                 :             : #if defined HAVE_NETCDF
     315                 :           2 :     ncerr = nf90_inq_dimid(ncid, "spin_lattice_Oiju_number_of_entries", dimid)
     316         [ -  + ]:           2 :     if(ncerr /= NF90_NOERR) then
     317                 :           0 :       write(std_out,'(A20)') 'No O_iju term found'
     318                 :             :     else
     319                 :           2 :       self%has_quadlin=.True.
     320                 :           2 :       ncerr = nctk_get_dim(ncid, "spin_lattice_Oiju_number_of_entries", ndata)
     321   [ -  +  +  -  :           6 :       ABI_MALLOC(ilist, (ndata))
          +  -  +  -  -  
                +  -  + ]
     322   [ -  +  +  -  :           6 :       ABI_MALLOC(jlist, (4,ndata))
          +  -  +  -  -  
                +  -  + ]
     323   [ -  +  +  -  :           4 :       ABI_MALLOC(ulist, (4,ndata))
             -  +  -  + ]
     324   [ -  +  +  -  :           6 :       ABI_MALLOC(vallist, (ndata))
          +  -  +  -  -  
                +  -  + ]
     325                 :             : 
     326                 :           2 :       varid = nctk_idname(ncid, "spin_lattice_Oiju_ilist")
     327                 :           2 :       ncerr = nf90_get_var(ncid, varid, ilist)
     328                 :           2 :       call netcdf_check(ncerr, "when reading Oiju_ilist")
     329                 :             : 
     330                 :           2 :       varid = nctk_idname(ncid, "spin_lattice_Oiju_jlist")
     331                 :           2 :       ncerr = nf90_get_var(ncid, varid, jlist)
     332                 :           2 :       call netcdf_check(ncerr, "when reading Oiju_jlist")
     333                 :             : 
     334                 :           2 :       varid = nctk_idname(ncid, "spin_lattice_Oiju_ulist")
     335                 :           2 :       ncerr = nf90_get_var(ncid, varid, ulist)
     336                 :           2 :       call netcdf_check(ncerr, "when reading Oiju_ulist")
     337                 :             : 
     338                 :           2 :       varid = nctk_idname(ncid, "spin_lattice_Oiju_valuelist")
     339                 :           2 :       ncerr = nf90_get_var(ncid, varid, vallist)
     340                 :           2 :       call netcdf_check(ncerr, "when reading spin_lattice_Oiju_valuelist")
     341                 :             : 
     342                 :           2 :       write(std_out,'(A8,I10,A11)') 'O_iju: ', ndata, 'terms read'
     343                 :             : 
     344                 :             :       !change units from eV to Ha and Ang to Bohr
     345         [ +  + ]:        4826 :       vallist(:) = vallist(:)*eV_Ha*Bohr_Ang
     346                 :             : 
     347                 :             :       !fill the sparse matrix for oiju parameters
     348                 :           2 :       call self%set_oiju(ndata, ilist, jlist, ulist, vallist)
     349                 :             : 
     350         [ +  - ]:           2 :       ABI_SFREE(ilist)
     351         [ +  - ]:           2 :       ABI_SFREE(jlist)
     352         [ +  - ]:           2 :       ABI_SFREE(ulist)
     353         [ +  - ]:           2 :       ABI_SFREE(vallist)
     354                 :             :     endif
     355                 :             : #else
     356                 :             :     ABI_ERROR('Multibinit should be install with netcdf to run this.')
     357                 :             : #endif
     358                 :             : 
     359   [ -  +  -  +  :           2 :   end subroutine read_oiju
             -  +  -  + ]
     360                 :             : 
     361                 :             :   !-----------------------------------------
     362                 :             :   ! reading tijuv parameters from ncdf file
     363                 :             :   !-----------------------------------------
     364                 :           2 :   subroutine read_tijuv(self, ncid)
     365                 :             :     class(slc_primitive_potential_t), intent(inout) :: self
     366                 :             :     integer,                          intent(in)    :: ncid
     367                 :             : 
     368                 :             :     integer :: ncerr, dimid, ndata, varid
     369                 :           2 :     integer, allocatable :: ilist(:), jlist(:,:), ulist(:,:), vlist(:,:)
     370                 :           2 :     real(dp), allocatable :: vallist(:)
     371                 :             : 
     372                 :             : #if defined HAVE_NETCDF
     373                 :           2 :     ncerr = nf90_inq_dimid(ncid, "spin_lattice_Tijuv_number_of_entries", dimid)
     374         [ +  - ]:           2 :     if(ncerr /= NF90_NOERR) then
     375                 :             :       ndata = 0
     376                 :             :     else
     377                 :           2 :       self%has_biquad=.True.
     378                 :           2 :       ncerr = nctk_get_dim(ncid, "spin_lattice_Tijuv_number_of_entries", ndata)
     379   [ -  +  +  -  :           6 :       ABI_MALLOC(ilist, (ndata))
          +  -  +  -  -  
                +  -  + ]
     380   [ -  +  +  -  :           6 :       ABI_MALLOC(jlist, (4, ndata))
          +  -  +  -  -  
                +  -  + ]
     381   [ -  +  +  -  :           4 :       ABI_MALLOC(ulist, (4, ndata))
             -  +  -  + ]
     382   [ -  +  +  -  :           4 :       ABI_MALLOC(vlist, (4, ndata))
             -  +  -  + ]
     383   [ -  +  +  -  :           6 :       ABI_MALLOC(vallist, (ndata))
          +  -  +  -  -  
                +  -  + ]
     384                 :             : 
     385                 :           2 :       varid = nctk_idname(ncid, "spin_lattice_Tijuv_ilist")
     386                 :           2 :       ncerr = nf90_get_var(ncid, varid, ilist)
     387                 :           2 :       call netcdf_check(ncerr, "when reading Tijuv_ilist")
     388                 :             : 
     389                 :           2 :       varid = nctk_idname(ncid, "spin_lattice_Tijuv_jlist")
     390                 :           2 :       ncerr = nf90_get_var(ncid, varid, jlist)
     391                 :           2 :       call netcdf_check(ncerr, "when reading Tijuv_jlist")
     392                 :             : 
     393                 :           2 :       varid = nctk_idname(ncid, "spin_lattice_Tijuv_ulist")
     394                 :           2 :       ncerr = nf90_get_var(ncid, varid, ulist)
     395                 :           2 :       call netcdf_check(ncerr, "when reading Tijuv_ulist")
     396                 :             : 
     397                 :           2 :       varid = nctk_idname(ncid, "spin_lattice_Tijuv_vlist")
     398                 :           2 :       ncerr = nf90_get_var(ncid, varid, vlist)
     399                 :           2 :       call netcdf_check(ncerr, "when reading Tijuv_vlist")
     400                 :             : 
     401                 :           2 :       varid = nctk_idname(ncid, "spin_lattice_Tijuv_valuelist")
     402                 :           2 :       ncerr = nf90_get_var(ncid, varid, vallist)
     403                 :           2 :       call netcdf_check(ncerr, "when reading Tijuv_valuelist")
     404                 :             : 
     405                 :           2 :       write(std_out,'(A8,I10,A11)') 'T_ijuv:', ndata, 'terms read'
     406                 :             : 
     407                 :             :       !change units from eV to Ha and Ang to Bohr
     408         [ +  + ]:         650 :       vallist(:) = vallist(:)*eV_Ha*(Bohr_Ang*Bohr_Ang)
     409                 :             : 
     410                 :             :       !fill the sparse matrix for tijuv parameters
     411                 :           2 :       call self%set_tijuv(ndata, ilist, jlist, ulist, vlist, vallist)
     412                 :             : 
     413         [ +  - ]:           2 :       ABI_SFREE(ilist)
     414         [ +  - ]:           2 :       ABI_SFREE(jlist)
     415         [ +  - ]:           2 :       ABI_SFREE(ulist)
     416         [ +  - ]:           2 :       ABI_SFREE(vlist)
     417         [ +  - ]:           2 :       ABI_SFREE(vallist)
     418                 :             :     endif
     419                 :             : 
     420                 :             : #else
     421                 :             :     ABI_ERROR('Multibinit should be install with netcdf to run this.')
     422                 :             : #endif
     423                 :             : 
     424                 :             : 
     425   [ -  +  -  +  :           2 :   end subroutine read_tijuv
          -  +  -  +  -  
                      + ]
     426                 :             : 
     427                 :             :   !---------------------------------------
     428                 :             :   ! store liu parameters in sparse matrix
     429                 :             :   ! TODO: test
     430                 :             :   !---------------------------------------
     431                 :           0 :   subroutine set_liu(self, nn, ilist, ulist, vallist)
     432                 :             : 
     433                 :             :     class(slc_primitive_potential_t), intent(inout) :: self
     434                 :             :     integer,                          intent(inout) :: nn
     435                 :             :     integer,                          intent(in)    :: ilist(nn)
     436                 :             :     integer,                          intent(in)    :: ulist(4,nn)
     437                 :             :     real(dp),                         intent(in)    :: vallist(nn)
     438                 :             : 
     439                 :             :     integer :: idx
     440                 :             : 
     441         [ #  # ]:           0 :     call self%liu%initialize(mshape=[-1, self%nspin*3, self%natom*3])
     442                 :             : 
     443         [ #  # ]:           0 :     if (xmpi_comm_rank(xmpi_world)==0) then
     444         [ #  # ]:           0 :       do idx=1, nn
     445                 :           0 :         call self%set_liu_1term(ilist(idx), ulist(1,idx), ulist(2:4,idx), vallist(idx))
     446                 :             :       end do
     447                 :             :     endif
     448                 :           0 :   end subroutine set_liu
     449                 :             : 
     450                 :             :   !------------------------------------
     451                 :             :   ! add one entry to sparse liu matrix
     452                 :             :   ! TODO: test
     453                 :             :   !------------------------------------
     454                 :           0 :   subroutine set_liu_1term(self, ii, uu, Ru, val)
     455                 :             :     class(slc_primitive_potential_t), intent(inout) :: self
     456                 :             :     integer,                          intent(in)    :: ii
     457                 :             :     integer,                          intent(in)    :: uu
     458                 :             :     integer,                          intent(in)    :: Ru(3)
     459                 :             :     real(dp),                         intent(in)    :: val
     460                 :             : 
     461                 :             :     integer :: indRu
     462                 :             : 
     463                 :           0 :     call self%lRulist%push_unique(Ru, position=indRu)
     464                 :             : 
     465         [ #  # ]:           0 :     call self%liu%add_entry(ind=[indRu, ii, uu], val=val)
     466                 :             : 
     467                 :           0 :   end subroutine set_liu_1term
     468                 :             : 
     469                 :             :   !----------------------------------------
     470                 :             :   ! store niuv parameters in sparse matrix
     471                 :             :   ! TODO: test
     472                 :             :   !----------------------------------------
     473                 :           0 :   subroutine set_niuv(self, nn, ilist, ulist, vlist, vallist)
     474                 :             : 
     475                 :             :     class(slc_primitive_potential_t), intent(inout) :: self
     476                 :             :     integer,                          intent(inout) :: nn
     477                 :             :     integer,                          intent(in)    :: ilist(nn)
     478                 :             :     integer,                          intent(in)    :: ulist(4,nn)
     479                 :             :     integer,                          intent(in)    :: vlist(4,nn)
     480                 :             :     real(dp),                         intent(in)    :: vallist(nn)
     481                 :             : 
     482                 :             :     integer :: idx
     483                 :             : 
     484         [ #  # ]:           0 :     call self%niuv%initialize(mshape=[-1, -1, self%nspin*3, self%natom*3, self%natom*3])
     485                 :             : 
     486         [ #  # ]:           0 :     if (xmpi_comm_rank(xmpi_world)==0) then
     487         [ #  # ]:           0 :       do idx=1, nn
     488                 :           0 :         call self%set_niuv_1term(ilist(idx), ulist(1,idx), vlist(1,idx), ulist(2:4,idx), vlist(2:4,idx), vallist(idx))
     489                 :             :       end do
     490                 :             :     endif
     491                 :             : 
     492                 :           0 :   end subroutine set_niuv
     493                 :             : 
     494                 :             :   !-------------------------------------
     495                 :             :   ! add one entry to sparse niuv matrix
     496                 :             :   !-------------------------------------
     497                 :           0 :   subroutine set_niuv_1term(self, ii, uu, vv, Ru, Rv, val)
     498                 :             :     class(slc_primitive_potential_t), intent(inout) :: self
     499                 :             :     integer,                          intent(in)    :: ii
     500                 :             :     integer,                          intent(in)    :: uu
     501                 :             :     integer,                          intent(in)    :: vv
     502                 :             :     integer,                          intent(in)    :: Ru(3)
     503                 :             :     integer,                          intent(in)    :: Rv(3)
     504                 :             :     real(dp),                         intent(in)    :: val
     505                 :             : 
     506                 :             :     integer :: indRu, indRv
     507                 :             : 
     508                 :           0 :     call self%nRulist%push_unique(Ru, position=indRu)
     509                 :           0 :     call self%nRvlist%push_unique(Rv, position=indRv)
     510                 :             : 
     511         [ #  # ]:           0 :     call self%niuv%add_entry(ind=[indRu, indRv, ii, uu, vv], val=val)
     512                 :             : 
     513                 :           0 :   end subroutine set_niuv_1term
     514                 :             : 
     515                 :             : 
     516                 :             :   !----------------------------------------
     517                 :             :   ! store oiju parameters in sparse matrix
     518                 :             :   ! TODO: test
     519                 :             :   !----------------------------------------
     520                 :           2 :   subroutine set_oiju(self, nn, ilist, jlist, ulist, vallist)
     521                 :             : 
     522                 :             :     class(slc_primitive_potential_t), intent(inout) :: self
     523                 :             :     integer,                          intent(inout) :: nn
     524                 :             :     integer,                          intent(in)    :: ilist(nn)
     525                 :             :     integer,                          intent(in)    :: jlist(4,nn)
     526                 :             :     integer,                          intent(in)    :: ulist(4,nn)
     527                 :             :     real(dp),                         intent(in)    :: vallist(nn)
     528                 :             : 
     529                 :             :     integer :: idx
     530                 :             : 
     531         [ +  + ]:          12 :     call self%oiju%initialize(mshape=[-1, -1, self%nspin*3, self%nspin*3, self%natom*3])
     532                 :             : 
     533         [ +  - ]:           2 :     if (xmpi_comm_rank(xmpi_world)==0) then
     534         [ +  + ]:        4826 :       do idx=1, nn
     535                 :        4826 :         call self%set_oiju_1term(ilist(idx), jlist(1,idx), ulist(1,idx), jlist(2:4,idx), ulist(2:4,idx), vallist(idx))
     536                 :             :       end do
     537                 :             :     endif
     538                 :             : 
     539                 :           2 :     call self%oiju%sum_duplicates()
     540                 :           2 :   end subroutine set_oiju
     541                 :             : 
     542                 :             :   !-------------------------------------
     543                 :             :   ! add one entry to sparse oiju matrix
     544                 :             :   ! TODO: test
     545                 :             :   !-------------------------------------
     546                 :        4824 :   subroutine set_oiju_1term(self, ii, jj, uu, Rj, Ru, val)
     547                 :             :     class(slc_primitive_potential_t), intent(inout) :: self
     548                 :             :     integer,                          intent(in)    :: ii
     549                 :             :     integer,                          intent(in)    :: jj
     550                 :             :     integer,                          intent(in)    :: uu
     551                 :             :     integer,                          intent(in)    :: Rj(3)
     552                 :             :     integer,                          intent(in)    :: Ru(3)
     553                 :             :     real(dp),                         intent(in)    :: val
     554                 :             : 
     555                 :             :     integer :: indRj, indRu
     556                 :             : 
     557                 :        4824 :     call self%oRjlist%push_unique(Rj, position=indRj)
     558                 :        4824 :     call self%oRulist%push_unique(Ru, position=indRu)
     559                 :             : 
     560         [ +  + ]:       28944 :     call self%oiju%add_entry(ind=[indRj, indRu, ii, jj, uu], val=val)
     561                 :             : 
     562                 :        4824 :   end subroutine set_oiju_1term
     563                 :             : 
     564                 :             :   !----------------------------------------
     565                 :             :   ! store tijuv parameters in sparse matrix
     566                 :             :   !----------------------------------------
     567                 :           2 :   subroutine set_tijuv(self, nn, ilist, jlist, ulist, vlist, vallist)
     568                 :             : 
     569                 :             :     class(slc_primitive_potential_t), intent(inout) :: self
     570                 :             :     integer,                          intent(inout) :: nn
     571                 :             :     integer,                          intent(in)    :: ilist(nn)
     572                 :             :     integer,                          intent(in)    :: jlist(4, nn)
     573                 :             :     integer,                          intent(in)    :: ulist(4, nn)
     574                 :             :     integer,                          intent(in)    :: vlist(4, nn)
     575                 :             :     real(dp),                         intent(in)    :: vallist(nn)
     576                 :             : 
     577                 :             :     integer :: idx
     578                 :             : 
     579         [ +  + ]:          16 :     call self%tijuv%initialize(mshape=[-1, -1, -1, self%nspin*3, self%nspin*3, self%natom*3, self%natom*3])
     580                 :             : 
     581         [ +  - ]:           2 :     if (xmpi_comm_rank(xmpi_world)==0) then
     582         [ +  + ]:         650 :       do idx=1, nn
     583                 :             :         call self%set_tijuv_1term(ilist(idx), jlist(1, idx), ulist(1, idx), vlist(1, idx), &
     584                 :         650 :                                 & jlist(2:4,idx), ulist(2:4,idx), vlist(2:4,idx), vallist(idx))
     585                 :             :       end do
     586                 :             :     endif
     587                 :             : 
     588                 :           2 :     call self%tijuv%sum_duplicates()
     589                 :             : 
     590                 :           2 :   end subroutine set_tijuv
     591                 :             : 
     592                 :             :   !-------------------------------------
     593                 :             :   ! add one entry to sparse tijuv matrix
     594                 :             :   !-------------------------------------
     595                 :         648 :   subroutine set_tijuv_1term(self, ii, jj, uu, vv, Rj, Ru, Rv, val)
     596                 :             :     class(slc_primitive_potential_t), intent(inout) :: self
     597                 :             :     integer,                          intent(in)    :: ii
     598                 :             :     integer,                          intent(in)    :: jj
     599                 :             :     integer,                          intent(in)    :: uu
     600                 :             :     integer,                          intent(in)    :: vv
     601                 :             :     integer,                          intent(in)    :: Rj(3)
     602                 :             :     integer,                          intent(in)    :: Ru(3)
     603                 :             :     integer,                          intent(in)    :: Rv(3)
     604                 :             :     real(dp),                         intent(in)    :: val
     605                 :             : 
     606                 :             :     integer :: indRj, indRu, indRv
     607                 :             : 
     608                 :         648 :     call self%tRjlist%push_unique(Rj, position=indRj)
     609                 :         648 :     call self%tRulist%push_unique(Ru, position=indRu)
     610                 :         648 :     call self%tRvlist%push_unique(Rv, position=indRv)
     611                 :             : 
     612         [ +  + ]:        5184 :     call self%tijuv%add_entry(ind=[indRj, indRu, indRv, ii, jj, uu, vv], val=val)
     613                 :             : 
     614                 :         648 :   end subroutine set_tijuv_1term
     615                 :             : 
     616                 :             : 
     617                 :             :   !-----------------------------------------------------------------
     618                 :             :   ! transfer parameter information from primitive cell to supercell
     619                 :             :   ! TODO: test
     620                 :             :   !-----------------------------------------------------------------
     621                 :           2 :   subroutine fill_supercell(self, scmaker, params, scpot, supercell)
     622                 :             :     class(slc_primitive_potential_t) , intent(inout) :: self
     623                 :             :     type(supercell_maker_t),           intent(inout) :: scmaker
     624                 :             :     type(multibinit_dtset_type),       intent(inout) :: params
     625                 :             :     class(abstract_potential_t), pointer, intent(inout) :: scpot
     626                 :             :     type(mbsupercell_t), target :: supercell
     627                 :             : 
     628                 :             :     integer :: nspin, sc_nspin, natom, sc_natom
     629                 :             :     integer :: master, my_rank, comm, nproc, ierr
     630                 :             :     logical :: iam_master
     631                 :             : 
     632                 :           2 :     call init_mpi_info(master, iam_master, my_rank, comm, nproc)
     633                 :             : 
     634                 :           2 :     nspin=self%nspin
     635                 :           2 :     natom=self%natom
     636                 :           2 :     sc_nspin=nspin * scmaker%ncells
     637                 :           2 :     sc_natom=natom * scmaker%ncells
     638                 :             : 
     639                 :           2 :     call xmpi_bcast(sc_nspin, master, comm, ierr)
     640                 :           2 :     call xmpi_bcast(sc_natom, master, comm, ierr)
     641         [ -  + ]:           2 :     ABI_MALLOC_TYPE_SCALAR(slc_potential_t, scpot)
     642                 :             : 
     643                 :             :     select type(scpot) ! use select type because properties only defined for slc_potential are used
     644                 :             :     type is (slc_potential_t)
     645                 :           2 :       call scpot%initialize(sc_nspin, sc_natom)
     646                 :           2 :       call scpot%set_supercell(supercell)
     647                 :           2 :       call scpot%set_params(params)
     648                 :             :       ! fill different coupling terms
     649         [ +  - ]:           4 :       if (iam_master) then
     650                 :           2 :         call self%fill_liu(scpot, scmaker)
     651                 :           2 :         call self%fill_oiju(scpot, scmaker)
     652                 :           2 :         call self%fill_niuv(scpot, scmaker)
     653                 :           2 :         call self%fill_tijuv(scpot, scmaker)
     654                 :             : 
     655                 :             :         !Write information which terms are used
     656                 :           2 :         write(std_out,'(A55)') 'Using the following terms for the spin-lattice coupling'
     657         [ -  + ]:           2 :         if(scpot%has_bilin)   write(std_out,'(A19)') 'Bilinear term: Liu'
     658         [ +  - ]:           2 :         if(scpot%has_quadlin) write(std_out,'(A28)') 'Quadratic-linear term: Oiju'
     659         [ -  + ]:           2 :         if(scpot%has_linquad) write(std_out,'(A28)') 'Linear-quadratic term: Niuv'
     660         [ +  + ]:           2 :         if(scpot%has_biquad)  write(std_out,'(A24)') 'Biquadratic term: Tijuv'
     661                 :             :       endif
     662                 :             :     end select
     663                 :           2 :   end subroutine fill_supercell
     664                 :             : 
     665                 :             :   !--------------------------------------------------------
     666                 :             :   ! Check for each term if it is needed in the calculation
     667                 :             :   ! and present in the ncdf input then put into supercell
     668                 :             :   !--------------------------------------------------------
     669                 :           2 :   subroutine fill_liu(self, scpot, scmaker)
     670                 :             :     class(slc_primitive_potential_t) , intent(inout) :: self
     671                 :             :     type(supercell_maker_t),           intent(inout) :: scmaker
     672                 :             :     class(slc_potential_t),            intent(inout) :: scpot
     673                 :             : 
     674         [ -  + ]:           2 :     if(scpot%has_bilin) then
     675         [ #  # ]:           0 :       if(self%has_bilin) then !did we actually find this in the netcdf file
     676                 :           0 :         call self%liu%sum_duplicates()
     677                 :           0 :         call self%set_liu_sc(scpot, scmaker)
     678                 :             :       else
     679                 :           0 :         ABI_ERROR("No parameters for bilinear coupling available. Check your input and parameter files.")
     680                 :           0 :         scpot%has_bilin = .False.
     681                 :             :       endif
     682                 :             :     endif
     683                 :           2 :   end subroutine fill_liu
     684                 :             : 
     685                 :           2 :   subroutine fill_niuv(self, scpot, scmaker)
     686                 :             :     class(slc_primitive_potential_t) , intent(inout) :: self
     687                 :             :     type(supercell_maker_t),           intent(inout) :: scmaker
     688                 :             :     class(slc_potential_t),            intent(inout) :: scpot
     689                 :             : 
     690         [ -  + ]:           2 :     if(scpot%has_linquad) then
     691         [ #  # ]:           0 :       if(self%has_linquad) then
     692                 :           0 :         call self%niuv%sum_duplicates()
     693                 :           0 :         call self%set_niuv_sc(scpot, scmaker)
     694                 :             :       else
     695                 :           0 :         ABI_ERROR("No parameters for linear-quadratic coupling available. Check your input and parameter files.")
     696                 :           0 :         scpot%has_linquad = .False.
     697                 :             :       endif
     698                 :             :     endif
     699                 :           2 :   end subroutine fill_niuv
     700                 :             : 
     701                 :           2 :   subroutine fill_oiju(self, scpot, scmaker)
     702                 :             :     class(slc_primitive_potential_t) , intent(inout) :: self
     703                 :             :     type(supercell_maker_t),           intent(inout) :: scmaker
     704                 :             :     class(slc_potential_t),            intent(inout) :: scpot
     705                 :             : 
     706         [ +  - ]:           2 :     if(scpot%has_quadlin) then
     707         [ +  - ]:           2 :       if(self%has_quadlin) then
     708                 :           2 :         call self%oiju%sum_duplicates()
     709                 :           2 :         call self%set_oiju_sc(scpot, scmaker)
     710                 :             :        else
     711                 :           0 :          ABI_ERROR("No parameters for quadratic-linear coupling available. Check your input and parameter files.")
     712                 :           0 :          scpot%has_quadlin = .False.
     713                 :             :        endif
     714                 :             :      endif
     715                 :           2 :   end subroutine fill_oiju
     716                 :             : 
     717                 :           2 :   subroutine fill_tijuv(self, scpot, scmaker)
     718                 :             :     class(slc_primitive_potential_t) , intent(inout) :: self
     719                 :             :     type(supercell_maker_t),           intent(inout) :: scmaker
     720                 :             :     class(slc_potential_t),            intent(inout) :: scpot
     721                 :             : 
     722         [ +  + ]:           2 :     if(scpot%has_biquad) then
     723         [ +  - ]:           1 :       if(self%has_biquad) then
     724                 :           1 :         call self%tijuv%sum_duplicates()
     725                 :           1 :         call self%set_tijuv_sc(scpot, scmaker)
     726                 :             :       else
     727                 :           0 :         ABI_ERROR("No parameters for biquadratic coupling available. Check your input and parameter files.")
     728                 :           0 :         scpot%has_biquad = .False.
     729                 :             :       endif
     730                 :             :     endif
     731                 :           2 :   end subroutine fill_tijuv
     732                 :             : 
     733                 :             :   !------------------------------
     734                 :             :   ! fill liu terms in supercell
     735                 :             :   ! TODO: test
     736                 :             :   !------------------------------
     737                 :           0 :   subroutine set_liu_sc(self, scpot, scmaker)
     738                 :             :     class(slc_primitive_potential_t), intent(inout) :: self
     739                 :             :     type(slc_potential_t),            intent(inout) :: scpot
     740                 :             :     type(supercell_maker_t),          intent(inout) :: scmaker
     741                 :             : 
     742                 :             :     integer :: icell, Ru_prim(3), liu_ind(3), iRu, i_prim, u_prim, inz
     743                 :             :     integer :: ngroup
     744                 :           0 :     integer, allocatable :: i_sc(:), u_sc(:), Ru_sc(:,:)
     745                 :           0 :     integer, allocatable :: i1list(:), ise(:)
     746                 :           0 :     real(dp) :: val_sc(scmaker%ncells)
     747                 :             : 
     748                 :             :     integer :: master, my_rank, comm, nproc
     749                 :             :     logical :: iam_master
     750                 :             : 
     751                 :           0 :     call init_mpi_info(master, iam_master, my_rank, comm, nproc)
     752                 :             : 
     753         [ #  # ]:           0 :     if(iam_master) then
     754         [ #  # ]:           0 :       call scpot%liu_sc%initialize(mshape=[self%nspin*3, self%natom*3])
     755                 :             :     endif
     756                 :             : 
     757         [ #  # ]:           0 :     do inz=1, self%liu%nnz
     758                 :           0 :       liu_ind=self%liu%get_ind_inz(inz)
     759                 :           0 :       iRu=liu_ind(1)
     760                 :           0 :       i_prim=liu_ind(2)
     761                 :           0 :       u_prim=liu_ind(3)
     762         [ #  # ]:           0 :       Ru_prim=self%lRulist%data(:,iRu)
     763                 :           0 :       call scmaker%trans_i(nbasis=self%nspin*3, i=i_prim, i_sc=i_sc)
     764                 :           0 :       call scmaker%trans_j_and_Rj(nbasis=self%natom*3, j=u_prim, Rj=Ru_prim, j_sc=u_sc, Rj_sc=Ru_sc)
     765         [ #  # ]:           0 :       val_sc(:)= self%liu%val%data(inz)
     766         [ #  # ]:           0 :       do icell=1, scmaker%ncells
     767                 :           0 :         call scpot%add_liu_term(i_sc(icell), u_sc(icell), val_sc(icell))
     768                 :             :       end do
     769         [ #  # ]:           0 :       ABI_SFREE(i_sc)
     770         [ #  # ]:           0 :       ABI_SFREE(u_sc)
     771         [ #  # ]:           0 :       ABI_SFREE(Ru_sc)
     772                 :             :     end do
     773                 :             : 
     774                 :           0 :     call scpot%liu_sc%group_by_1dim(ngroup, i1list, ise)
     775         [ #  # ]:           0 :     ABI_SFREE(i1list)
     776         [ #  # ]:           0 :     ABI_SFREE(ise)
     777                 :             : 
     778   [ #  #  #  #  :           0 :   end subroutine set_liu_sc
          #  #  #  #  #  
                      # ]
     779                 :             : 
     780                 :             :   !------------------------------
     781                 :             :   ! fill niuv terms in supercell
     782                 :             :   ! TODO: test
     783                 :             :   !------------------------------
     784                 :           0 :   subroutine set_niuv_sc(self, scpot, scmaker)
     785                 :             :     class(slc_primitive_potential_t), intent(inout) :: self
     786                 :             :     type(slc_potential_t),            intent(inout) :: scpot
     787                 :             :     type(supercell_maker_t),          intent(inout) :: scmaker
     788                 :             : 
     789                 :             :     integer :: icell, Ru_prim(3), Rv_prim(3), niuv_ind(5), iRu, iRv, i_prim, u_prim, v_prim, inz
     790                 :             :     integer :: ngroup
     791                 :           0 :     integer, allocatable :: i_sc(:), u_sc(:), v_sc(:), Ru_sc(:,:), Rv_sc(:,:)
     792                 :           0 :     integer, allocatable :: i1list(:), ise(:)
     793                 :           0 :     real(dp) :: val_sc(scmaker%ncells)
     794                 :             : 
     795                 :             :     integer :: master, my_rank, comm, nproc
     796                 :             :     logical :: iam_master
     797                 :             : 
     798                 :           0 :     call init_mpi_info(master, iam_master, my_rank, comm, nproc)
     799                 :             : 
     800         [ #  # ]:           0 :     if(iam_master) then
     801         [ #  # ]:           0 :       call scpot%niuv_sc%initialize(mshape=[self%nspin*3, self%natom*3, self%natom*3])
     802                 :             :     endif
     803                 :             : 
     804         [ #  # ]:           0 :     do inz=1, self%niuv%nnz
     805                 :           0 :       niuv_ind=self%niuv%get_ind_inz(inz)
     806                 :           0 :       iRu=niuv_ind(1)
     807                 :           0 :       iRv=niuv_ind(2)
     808                 :           0 :       i_prim=niuv_ind(3)
     809                 :           0 :       u_prim=niuv_ind(4)
     810                 :           0 :       v_prim=niuv_ind(5)
     811         [ #  # ]:           0 :       Ru_prim=self%nRulist%data(:,iRu)
     812         [ #  # ]:           0 :       Rv_prim=self%nRvlist%data(:,iRv)
     813                 :           0 :       call scmaker%trans_i(nbasis=self%nspin*3, i=i_prim, i_sc=i_sc)
     814                 :           0 :       call scmaker%trans_j_and_Rj(nbasis=self%natom*3, j=u_prim, Rj=Ru_prim, j_sc=u_sc, Rj_sc=Ru_sc)
     815                 :           0 :       call scmaker%trans_j_and_Rj(nbasis=self%natom*3, j=v_prim, Rj=Rv_prim, j_sc=v_sc, Rj_sc=Rv_sc)
     816         [ #  # ]:           0 :       val_sc(:)= self%niuv%val%data(inz)
     817                 :           0 :       do icell=1, scmaker%ncells
     818                 :             :         !call scpot%add_niuv_term(i_sc(icell), u_sc(icell), v_sc(icell), val_sc(icell))
     819                 :             :       end do
     820         [ #  # ]:           0 :       ABI_SFREE(i_sc)
     821         [ #  # ]:           0 :       ABI_SFREE(u_sc)
     822         [ #  # ]:           0 :       ABI_SFREE(v_sc)
     823         [ #  # ]:           0 :       ABI_SFREE(Ru_sc)
     824         [ #  # ]:           0 :       ABI_SFREE(Rv_sc)
     825                 :             :     end do
     826                 :             : 
     827                 :           0 :     call scpot%niuv_sc%group_by_1dim(ngroup, i1list, ise)
     828         [ #  # ]:           0 :     ABI_SFREE(i1list)
     829         [ #  # ]:           0 :     ABI_SFREE(ise)
     830                 :             : 
     831   [ #  #  #  #  :           0 :   end subroutine set_niuv_sc
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     832                 :             : 
     833                 :             : 
     834                 :             :   !------------------------------
     835                 :             :   ! fill oiju terms in supercell
     836                 :             :   ! TODO: test
     837                 :             :   !------------------------------
     838                 :           2 :   subroutine set_oiju_sc(self, scpot, scmaker)
     839                 :             :     class(slc_primitive_potential_t), intent(inout) :: self
     840                 :             :     class(slc_potential_t),            intent(inout) :: scpot
     841                 :             :     type(supercell_maker_t),          intent(inout) :: scmaker
     842                 :             : 
     843                 :             :     integer :: icell, Rj_prim(3), Ru_prim(3), oiju_ind(5), iRj, iRu, i_prim, j_prim, u_prim, inz
     844                 :             :     integer :: ngroup
     845                 :           2 :     integer, allocatable :: i_sc(:), j_sc(:), u_sc(:), Rj_sc(:, :), Ru_sc(:,:)
     846                 :           2 :     integer, allocatable :: i1list(:), ise(:)
     847                 :           4 :     real(dp) :: val_sc(scmaker%ncells)
     848                 :             : 
     849                 :             :     integer :: master, my_rank, comm, nproc
     850                 :             :     logical :: iam_master
     851                 :             : 
     852                 :           2 :     call init_mpi_info(master, iam_master, my_rank, comm, nproc)
     853                 :             : 
     854         [ +  - ]:           2 :     if(iam_master) then
     855         [ +  + ]:           8 :       call scpot%oiju_sc%initialize(mshape=[self%nspin*3, self%nspin*3, self%natom*3])
     856                 :             :     endif
     857                 :             : 
     858         [ +  + ]:        4826 :     do inz=1, self%oiju%nnz
     859                 :        4824 :       oiju_ind=self%oiju%get_ind_inz(inz)
     860                 :        4824 :       iRj=oiju_ind(1)
     861                 :        4824 :       iRu=oiju_ind(2)
     862                 :        4824 :       i_prim=oiju_ind(3)
     863                 :        4824 :       j_prim=oiju_ind(4)
     864                 :        4824 :       u_prim=oiju_ind(5)
     865         [ +  + ]:       19296 :       Rj_prim=self%oRjlist%data(:,iRj)
     866         [ +  + ]:       19296 :       Ru_prim=self%oRulist%data(:,iRu)
     867                 :        4824 :       call scmaker%trans_i(nbasis=self%nspin*3, i=i_prim, i_sc=i_sc)
     868                 :        4824 :       call scmaker%trans_j_and_Rj(nbasis=self%nspin*3, j=j_prim, Rj=Rj_prim, j_sc=j_sc, Rj_sc=Rj_sc)
     869                 :        4824 :       call scmaker%trans_j_and_Rj(nbasis=self%natom*3, j=u_prim, Rj=Ru_prim, j_sc=u_sc, Rj_sc=Ru_sc)
     870         [ +  + ]:     1046808 :       val_sc(:)= self%oiju%val%data(inz)
     871         [ +  + ]:     1046808 :       do icell=1, scmaker%ncells
     872                 :     1046808 :         call scpot%add_oiju_term(i_sc(icell), j_sc(icell), u_sc(icell), val_sc(icell))
     873                 :             :       end do
     874         [ +  - ]:        4824 :       ABI_SFREE(i_sc)
     875         [ +  - ]:        4824 :       ABI_SFREE(j_sc)
     876         [ +  - ]:        4824 :       ABI_SFREE(u_sc)
     877         [ +  - ]:        4824 :       ABI_SFREE(Rj_sc)
     878         [ +  - ]:        4826 :       ABI_SFREE(Ru_sc)
     879                 :             :     end do
     880                 :             : 
     881                 :           2 :     call scpot%oiju_sc%group_by_1dim(ngroup, i1list, ise)
     882         [ +  - ]:           2 :     ABI_SFREE(i1list)
     883         [ +  - ]:           2 :     ABI_SFREE(ise)
     884                 :             : 
     885   [ -  +  -  +  :           2 :   end subroutine set_oiju_sc
          -  +  -  +  -  
             +  -  +  -  
                      + ]
     886                 :             : 
     887                 :           1 :   subroutine set_tijuv_sc(self, scpot, scmaker)
     888                 :             :     class(slc_primitive_potential_t), intent(inout) :: self
     889                 :             :     type(slc_potential_t),            intent(inout) :: scpot
     890                 :             :     type(supercell_maker_t),          intent(inout) :: scmaker
     891                 :             : 
     892                 :             :     integer :: icell, Rj(3), Ru(3), Rv(3), tijuv_ind(7), iRj, iRu, iRv, ii, ij, iu, iv, inz
     893                 :           1 :     integer, allocatable :: i_sc(:), j_sc(:), u_sc(:), v_sc(:), Rj_sc(:, :), Ru_sc(:,:), Rv_sc(:,:)
     894                 :           2 :     real(dp) :: val_sc(scmaker%ncells)
     895                 :             : 
     896                 :             :     integer :: master, my_rank, comm, nproc
     897                 :             :     logical :: iam_master
     898                 :             : 
     899                 :           1 :     call init_mpi_info(master, iam_master, my_rank, comm, nproc)
     900                 :             : 
     901         [ +  - ]:           1 :     if(iam_master) then
     902         [ +  + ]:           5 :       call scpot%tijuv_sc%initialize(mshape=[self%nspin*3, self%nspin*3, self%natom*3, self%natom*3])
     903         [ +  + ]:           5 :       call scpot%tuvij_sc%initialize(mshape=[self%natom*3, self%natom*3, self%nspin*3, self%nspin*3])
     904                 :             :     endif
     905                 :             : 
     906         [ +  + ]:         325 :     do inz=1, self%tijuv%nnz
     907                 :         324 :       tijuv_ind=self%tijuv%get_ind_inz(inz)
     908                 :         324 :       iRj=tijuv_ind(1)
     909                 :         324 :       iRu=tijuv_ind(2)
     910                 :         324 :       iRv=tijuv_ind(3)
     911                 :         324 :       ii=tijuv_ind(4)
     912                 :         324 :       ij=tijuv_ind(5)
     913                 :         324 :       iu=tijuv_ind(6)
     914                 :         324 :       iv=tijuv_ind(7)
     915         [ +  + ]:        1296 :       Rj=self%tRjlist%data(:,iRj)
     916         [ +  + ]:        1296 :       Ru=self%tRulist%data(:,iRu)
     917         [ +  + ]:        1296 :       Rv=self%tRvlist%data(:,iRv)
     918                 :         324 :       call scmaker%trans_i(nbasis=self%nspin*3, i=ii, i_sc=i_sc)
     919                 :         324 :       call scmaker%trans_j_and_Rj(nbasis=self%nspin*3, j=ij, Rj=Rj, j_sc=j_sc, Rj_sc=Rj_sc)
     920                 :         324 :       call scmaker%trans_j_and_Rj(nbasis=self%natom*3, j=iu, Rj=Ru, j_sc=u_sc, Rj_sc=Ru_sc)
     921                 :         324 :       call scmaker%trans_j_and_Rj(nbasis=self%natom*3, j=iv, Rj=Rv, j_sc=v_sc, Rj_sc=Rv_sc)
     922         [ +  + ]:       70308 :       val_sc(:)= self%tijuv%val%data(inz)
     923         [ +  + ]:       70308 :       do icell=1, scmaker%ncells
     924                 :       70308 :         call scpot%add_tijuv_term(i_sc(icell), j_sc(icell), u_sc(icell), v_sc(icell), val_sc(icell))
     925                 :             :       end do
     926         [ +  - ]:         324 :       ABI_SFREE(i_sc)
     927         [ +  - ]:         324 :       ABI_SFREE(j_sc)
     928         [ +  - ]:         324 :       ABI_SFREE(u_sc)
     929         [ +  - ]:         324 :       ABI_SFREE(v_sc)
     930         [ +  - ]:         324 :       ABI_SFREE(Rj_sc)
     931         [ +  - ]:         324 :       ABI_SFREE(Ru_sc)
     932         [ +  - ]:         325 :       ABI_SFREE(Rv_sc)
     933                 :             :     end do
     934                 :             : 
     935                 :           1 :     call scpot%tijuv_sc%group_by_pair()
     936                 :           1 :     call scpot%tuvij_sc%group_by_pair()
     937                 :             : 
     938   [ -  +  -  +  :           1 :   end subroutine set_tijuv_sc
          -  +  -  +  -  
             +  -  +  -  
                      + ]
     939                 :             : 
     940                 :             :   !!***
     941   [ +  +  -  +  :           8 : end module m_slc_primitive_potential
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                   -  + ]
        

Generated by: LCOV version 2.3-1