LCOV - code coverage report
Current view: top level - src/78_effpot - m_multibinit_cell.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 91.3 % 184 168
Test Date: 2026-11-09 11:14:24 Functions: 62.1 % 29 18
Branches: 52.9 % 378 200

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_multibinit_cell
       2                 :             : !! NAME
       3                 :             : !! m_multibinit_cell
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !! This module define the m_unitcell type, which defines an atomic structure, with spin, lwf, electron
       7                 :             : !!
       8                 :             : !! Datatypes:
       9                 :             : !!
      10                 :             : !!
      11                 :             : !! Subroutines:
      12                 :             : !!
      13                 :             : !! COPYRIGHT !! Copyright (C) 2001-2026 ABINIT group (hexu) !! This file is distributed under the terms of the
      14                 :             : !! GNU General Public License, see ~abinit/COPYING
      15                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
      16                 :             : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
      17                 :             : !!
      18                 :             : !! SOURCE
      19                 :             : 
      20                 :             : 
      21                 :             : #if defined HAVE_CONFIG_H
      22                 :             : #include "config.h"
      23                 :             : #endif
      24                 :             : #include "abi_common.h"
      25                 :             : 
      26                 :             : 
      27                 :             : module m_multibinit_cell
      28                 :             :   use defs_basis
      29                 :             :   use m_abicore
      30                 :             :   use m_errors
      31                 :             :   use m_xmpi
      32                 :             :   use m_mpi_scheduler, only: init_mpi_info
      33                 :             :   !use m_multibinit_supercell, only: mb_supercell_t
      34                 :             :   use m_supercell_maker , only: supercell_maker_t
      35                 :             :   use m_multibinit_dataset, only : multibinit_dtset_type
      36                 :             :   use m_crystal, only : crystal_t
      37                 :             : 
      38                 :             :   use m_spmat_spvec, only: sp_real_vec
      39                 :             :   use m_lattice_lwf_map, only: lwf_latt_coeff_t
      40                 :             :   implicit none
      41                 :             : 
      42                 :             : !!***
      43                 :             :   private
      44                 :             :   !----------------------------------------------------------------------
      45                 :             :   !> @brief  lattice cell type
      46                 :             :   !> NOTE: This is used as an example for how to build new potentials.
      47                 :             :   !> it is used with the lattice_harmonic_potentail.
      48                 :             :   !> It has contains the zion, masses, xcart, and cell info
      49                 :             :   ! TODO: use crystal_t or add it as another lattice type.
      50                 :             :   !----------------------------------------------------------------------
      51                 :             :   type, public ::mbcell_lattice_t
      52                 :             :      integer:: natom = 0
      53                 :             :      integer, allocatable  :: zion(:)
      54                 :             :      real(dp), allocatable :: masses(:), xcart(:,:)
      55                 :             :      integer, allocatable :: ilatt_prim(:)
      56                 :             :      integer, allocatable :: rvec(:,:)
      57                 :             :      real(dp) :: cell(3,3)
      58                 :             :    contains
      59                 :             :      procedure :: initialize => latt_initialize
      60                 :             :      procedure :: finalize => latt_finalize
      61                 :             :      procedure :: fill_supercell=>latt_fill_supercell
      62                 :             :      procedure :: from_unitcell => latt_from_unitcell
      63                 :             :   end type mbcell_lattice_t
      64                 :             : 
      65                 :             :   !----------------------------------------------------------------------
      66                 :             :   !> @brief spin cell type
      67                 :             :   !----------------------------------------------------------------------
      68                 :             :   type, public :: mbcell_spin_t
      69                 :             :      integer :: nspin = 0  ! number of spin
      70                 :             :      real(dp) :: rprimd(3,3)   ! cell parameters
      71                 :             :      real(dp), allocatable :: ms(:)   ! magnetic moments  array(nspin)
      72                 :             :      real(dp), allocatable :: Sref(:,:)   ! spin orientation of reference structure, array(3,nspin)
      73                 :             :      real(dp) :: ref_qpoint(3)   ! q point to construct reference spin structure
      74                 :             :      real(dp) :: ref_rotate_axis(3)   ! rotation axis to construct reference spin structure
      75                 :             :      real(dp), allocatable :: gyro_ratio(:) ! gyromagnetic ratio array(nspin)
      76                 :             :      real(dp), allocatable :: gilbert_damping(:) ! damping factor defined for each spin
      77                 :             :      real(dp), allocatable :: spin_positions(:,:) ! positions of spin (cartesian)
      78                 :             :      integer, allocatable ::  ispin_prim(:) ! index of primitive cell
      79                 :             :      integer, allocatable ::  rvec(:,:) ! R cell vectors for each spin (for supercell)
      80                 :             :    contains
      81                 :             :      procedure :: initialize => spin_initialize
      82                 :             :      procedure :: set => spin_set
      83                 :             :      procedure :: finalize => spin_finalize
      84                 :             :      procedure :: fill_supercell=>spin_fill_supercell
      85                 :             :      procedure :: from_unitcell=>spin_from_unitcell
      86                 :             :   end type mbcell_spin_t
      87                 :             : 
      88                 :             :   !----------------------------------------------------------------------
      89                 :             :   !> @brief lattice wannier function cell type
      90                 :             :   !----------------------------------------------------------------------
      91                 :             :   type, public :: mbcell_lwf_t
      92                 :             :      integer :: nlwf =0 ! number of lattice wannier functions
      93                 :             :      integer, allocatable ::  ilwf_prim(:) ! index of primitive cell
      94                 :             :      integer, allocatable ::  rvec(:,:) ! R cell vectors for each spin (for supercell)
      95                 :             :      real(dp), allocatable :: lwf_masses(:)
      96                 :             :      type(lwf_latt_coeff_t) :: lwf_latt_coeffs
      97                 :             :    contains
      98                 :             :      Procedure :: initialize => lwf_initialize
      99                 :             :      procedure :: finalize => lwf_finalize
     100                 :             :      procedure :: fill_supercell => lwf_fill_supercell
     101                 :             :      procedure :: from_unitcell => lwf_from_unitcell
     102                 :             :   end type mbcell_lwf_t
     103                 :             : 
     104                 :             :   !----------------------------------------------------------------------
     105                 :             :   !> @brief cell type
     106                 :             :   !> NOTE: to add a new kind of cell, add a subtype here and a tag.
     107                 :             :   !----------------------------------------------------------------------
     108                 :             :   type ,public :: mbcell_t
     109                 :             :      logical :: has_lattice=.False.
     110                 :             :      logical :: has_spin=.False.
     111                 :             :      logical :: has_lwf=.False.
     112                 :             :      logical :: has_electron=.False.
     113                 :             :      type(mbcell_lattice_t) :: lattice
     114                 :             :      type(mbcell_spin_t) :: spin
     115                 :             :      type(mbcell_lwf_t) :: lwf
     116                 :             :    contains
     117                 :             :      procedure :: initialize
     118                 :             :      procedure :: finalize
     119                 :             :      procedure :: set_lattice   ! intialize the lattice
     120                 :             :      procedure :: set_spin      ! initilzie the spin
     121                 :             :      procedure :: set_lwf
     122                 :             :      procedure :: fill_supercell  ! fill supercell.
     123                 :             :      !procedure :: from_unitcell
     124                 :             :   end type mbcell_t
     125                 :             : 
     126                 :             :   !----------------------------------------------------------------------
     127                 :             :   !> @brief supercell type, which is unitcell plus some supercell information
     128                 :             :   !> NOTE: to add a new kind of cell, add a subtype here and a tag.
     129                 :             :   !----------------------------------------------------------------------
     130                 :             :   type, public, extends(mbcell_t):: mbsupercell_t
     131                 :             :      integer :: sc_matrix(3,3)   ! supercell matrix
     132                 :             :      integer :: ncell            ! number of cells in supercell !NH: this already exists in supercell_maker!
     133                 :             :      type(supercell_maker_t), pointer :: supercell_maker  ! pointer to a helper class object
     134                 :             :      class(mbcell_t), pointer :: unitcell  ! pointer to the unitcell which the supercell is built from
     135                 :             :    contains
     136                 :             :      procedure :: from_unitcell
     137                 :             :   end type mbsupercell_t
     138                 :             : 
     139                 :             : contains
     140                 :             : 
     141                 :             :   !============================  mb_cell_t========================================
     142                 :             : 
     143                 :             :   !----------------------------------------------------------------------
     144                 :             :   !> @brief intialize mb_cell_t
     145                 :             :   !----------------------------------------------------------------------
     146                 :          12 :   subroutine initialize(self)
     147                 :             :     class(mbcell_t), intent(inout) :: self
     148                 :          12 :     ABI_UNUSED_A(self)
     149                 :          12 :   end subroutine initialize
     150                 :             : 
     151                 :             :   !----------------------------------------------------------------------
     152                 :             :   !> @brief set the lattice subtype information
     153                 :             :   !>
     154                 :             :   !> @param[in]  natom: number of atoms
     155                 :             :   !> @param[in]  cell:  cell parameter matrix (3,3)
     156                 :             :   !> @param[in]  xcart: cartesion coordinates
     157                 :             :   !> @param[in]  masses: masses
     158                 :             :   !> @param[in]  zion: atomic numbers
     159                 :             :   !----------------------------------------------------------------------
     160   [ -  +  -  +  :           6 :   subroutine set_lattice(self, natom, cell, xcart, masses, zion)
                   -  + ]
     161                 :             :     class(mbcell_t), intent(inout) :: self
     162                 :             :     integer, intent(in) :: natom, zion(:)
     163                 :             :     real(dp), intent(in) :: cell(3,3), xcart(:,:), masses(:)
     164         [ +  - ]:           6 :     if (.not. self%has_lattice) then
     165                 :           6 :         self%has_lattice=.True.
     166                 :             :         call self%lattice%initialize(natom=natom, cell=cell, &
     167                 :           6 :             &xcart=xcart, masses=masses, zion=zion)
     168                 :             :     endif
     169                 :           6 :   end subroutine set_lattice
     170                 :             : 
     171                 :             : 
     172                 :             :   !----------------------------------------------------------------------
     173                 :             :   !> @brief initialize spin sub type
     174                 :             :   !>
     175                 :             :   !> @param[in] nspin: number of spin
     176                 :             :   !> @param[in] ms: magnetic moments
     177                 :             :   !> @param[in] rprimd:  cell pareters
     178                 :             :   !> @param[in] spin_positions:  the cartesion coordinates of spins
     179                 :             :   !> @param[in] gyro_ratio: gyromagnetic ratio fro each spin
     180                 :             :   !> @param[in] gilbert_damping: damping factor for each spin
     181                 :             :   !> @param[in] rvec: R vectors for cell in supercell
     182                 :             :   !> @param[in] ispin_prim:  id in primitive cell for each spin
     183                 :             :   !----------------------------------------------------------------------
     184                 :           2 :   subroutine set_spin(self,nspin, ms, rprimd, spin_positions, gyro_ratio, gilbert_damping, rvec,  ispin_prim, &
     185                 :             :        & Sref, ref_qpoint, ref_rotate_axis)
     186                 :             :     class(mbcell_t),  intent(inout):: self
     187                 :             :     integer,          intent(in)   :: nspin
     188                 :             :     real(dp),         intent(in)   :: ms(nspin), rprimd(3,3), spin_positions(3, nspin), gyro_ratio(nspin), gilbert_damping(nspin)
     189                 :             :     real(dp), optional, intent(in) :: Sref(3, nspin), ref_qpoint(3), ref_rotate_axis(3)
     190                 :             :     integer,  optional, intent(in) :: rvec(3, nspin), ispin_prim(nspin)
     191                 :           2 :     self%has_spin=.True.
     192                 :           2 :     call self%spin%initialize(nspin)
     193                 :             :     call self%spin%set(nspin, ms, rprimd, spin_positions, gyro_ratio, gilbert_damping, rvec, ispin_prim, &
     194                 :           2 :          & Sref, ref_qpoint=ref_qpoint, ref_rotate_axis=ref_rotate_axis)
     195                 :           2 :   end subroutine set_spin
     196                 :             : 
     197                 :             :   !----------------------------------------------------------------------
     198                 :             :   !> @brief initialize LWF sub type
     199                 :             :   !----------------------------------------------------------------------
     200                 :           1 :   subroutine set_lwf(self, nlwf)
     201                 :             :     class(mbcell_t) , intent(inout):: self
     202                 :             :     integer, intent(in) :: nlwf
     203                 :           1 :     self%has_lwf=.True.
     204                 :           1 :     call self%lwf%initialize(nlwf)
     205                 :           1 :   end subroutine set_lwf
     206                 :             : 
     207                 :             :   !----------------------------------------------------------------------
     208                 :             :   !> @brief read cell from a file, which is not used in Multibinit
     209                 :             :   !> since all the primitive potentials are read by the primitive_cell potential reader
     210                 :             :   !> They have a pointer to the mbcell_t before reading potentials.
     211                 :             :   !>
     212                 :             :   !> @param[in]  parasm: input parameters
     213                 :             :   !> @param[in]  fnames: the names in files file
     214                 :             :   !----------------------------------------------------------------------
     215                 :             :   subroutine read_from_file(self, params, fnames)
     216                 :             :     class(mbcell_t), intent(inout) :: self
     217                 :             :     type(multibinit_dtset_type), intent(in) :: params
     218                 :             :     character(len=fnlen), intent(in) :: fnames(17)
     219                 :             : 
     220                 :             :     ABI_UNUSED_A(self)
     221                 :             :     ABI_UNUSED_A(params)
     222                 :             :     ABI_UNUSED_A(fnames)
     223                 :             :   end subroutine read_from_file
     224                 :             : 
     225                 :             : 
     226                 :             :   !----------------------------------------------------------------------
     227                 :             :   !> @brief finalize
     228                 :             :   !>
     229                 :             :   !----------------------------------------------------------------------
     230                 :          12 :   subroutine finalize(self)
     231                 :             :     class(mbcell_t), intent(inout) :: self
     232                 :          12 :     call self%lattice%finalize()
     233                 :          12 :     call self%spin%finalize()
     234                 :          12 :     call self%lwf%finalize()
     235                 :          12 :   end subroutine finalize
     236                 :             : 
     237                 :             :   !----------------------------------------------------------------------
     238                 :             :   !> @brief fill the cell supercell
     239                 :             :   !>
     240                 :             :   !> @param[in]  sc_maker: the helper to build supercells
     241                 :             :   !> @param[out]supercell; the supercell to be built
     242                 :             :   !----------------------------------------------------------------------
     243                 :           6 :   subroutine fill_supercell(self, sc_maker, supercell)
     244                 :             :     class(mbcell_t), target, intent(inout) :: self
     245                 :             :     type(supercell_maker_t), target, intent(inout) :: sc_maker
     246                 :             :     class(mbsupercell_t), intent(inout) :: supercell
     247                 :           6 :     call supercell%initialize()
     248                 :           6 :     supercell%ncell=sc_maker%ncells
     249   [ +  +  +  + ]:          78 :     supercell%sc_matrix=sc_maker%scmat
     250                 :           6 :     supercell%has_lattice = self%has_lattice
     251                 :           6 :     supercell%has_spin = self%has_spin
     252                 :           6 :     supercell%has_lwf =self%has_lwf
     253                 :           6 :     supercell%supercell_maker => sc_maker
     254                 :           6 :     supercell%unitcell => self
     255         [ +  - ]:           6 :     if (self%has_lattice) then
     256                 :           6 :        call self%lattice%fill_supercell(sc_maker, supercell%lattice)
     257                 :             :     endif
     258                 :             : 
     259         [ +  + ]:           6 :     if (self%has_spin) then
     260                 :           2 :        call self%spin%fill_supercell(sc_maker, supercell%spin)
     261                 :             :     endif
     262                 :             : 
     263         [ +  + ]:           6 :     if (self%has_lwf) then
     264                 :           1 :        call self%lwf%fill_supercell(sc_maker, supercell%lwf)
     265                 :             :     endif
     266                 :             : 
     267                 :           6 :   end subroutine fill_supercell
     268                 :             : 
     269                 :             : 
     270                 :             : !=================== Supercell =====================================
     271                 :             :   subroutine supercell_initialize(self)
     272                 :             :     class(mbsupercell_t), intent(inout) :: self
     273                 :             :     call self%mbcell_t%initialize()
     274                 :             :   end subroutine supercell_initialize
     275                 :             : 
     276                 :             :   !----------------------------------------------------------------------
     277                 :             :   !> @brief build from unitcell
     278                 :             :   !> @param[in]  sc_maker
     279                 :             :   !> @param[in] unitcell
     280                 :             :   !----------------------------------------------------------------------
     281                 :           6 :   subroutine from_unitcell(self, sc_maker, unitcell)
     282                 :             :     class(mbsupercell_t), intent(inout) :: self
     283                 :             :     type(supercell_maker_t),  intent(inout) :: sc_maker
     284                 :             :     class(mbcell_t), intent(inout) :: unitcell
     285                 :           6 :     call unitcell%fill_supercell(sc_maker, self)
     286                 :           6 :   end subroutine from_unitcell
     287                 :             : 
     288                 :             :   !----------------------------------------------------------------------
     289                 :             :   !> @brief finalize supercell
     290                 :             :   !----------------------------------------------------------------------
     291                 :             :   subroutine supercell_finalize(self)
     292                 :             :     class(mbsupercell_t), intent(inout) :: self
     293                 :             :     call self%mbcell_t%finalize()
     294                 :             :     nullify(self%supercell_maker)
     295                 :             :     nullify(self%unitcell)
     296                 :             :   end subroutine supercell_finalize
     297                 :             : 
     298                 :             : !================================Lattice====================================
     299                 :             : 
     300                 :             :   !----------------------------------------------------------------------
     301                 :             :   !> @brief initalize the lattice type
     302                 :             :   !>
     303                 :             :   !> @param[in]  natom: number of atoms
     304                 :             :   !> @param[in]  cell:  cell matrix
     305                 :             :   !> @param[in]  xcart:  cartesion
     306                 :             :   !> @param[in]  masses: masses of atoms
     307                 :             :   !> @param[in]  zion: zion of atoms
     308                 :             :   !----------------------------------------------------------------------
     309   [ -  +  -  +  :          12 :   subroutine latt_initialize(self, natom, cell, xcart, masses, zion)
                   -  + ]
     310                 :             :     class(mbcell_lattice_t), intent(inout) :: self
     311                 :             :     integer, intent(in) :: natom, zion(:)
     312                 :             :     real(dp), intent(in) :: cell(3,3), xcart(:,:), masses(:)
     313                 :          12 :     self%natom=natom
     314   [ -  +  +  -  :          36 :     ABI_MALLOC(self%zion, (natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     315   [ -  +  +  -  :          36 :     ABI_MALLOC(self%xcart, (3, natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     316   [ -  +  +  -  :          36 :     ABI_MALLOC(self%masses, (natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     317                 :             : 
     318         [ +  + ]:        7755 :     self%zion(:) = zion(:)
     319   [ +  +  +  + ]:         156 :     self%cell(:,:) =cell(:,:)
     320   [ +  +  +  + ]:       30984 :     self%xcart(:,:) = xcart(:,:)
     321         [ +  + ]:        7755 :     self%masses(:) = masses(:)
     322                 :          12 :   end subroutine latt_initialize
     323                 :             : 
     324                 :             : 
     325                 :             : !----------------------------------------------------------------------
     326                 :             :   !> @brief finalize lattice
     327                 :             :   !----------------------------------------------------------------------
     328                 :          12 :   subroutine latt_finalize(self)
     329                 :             :     class(mbcell_lattice_t) :: self
     330                 :          12 :     self%natom=0
     331         [ +  - ]:          12 :     ABI_SFREE(self%xcart)
     332         [ +  - ]:          12 :     ABI_SFREE(self%masses)
     333         [ +  - ]:          12 :     ABI_SFREE(self%zion)
     334                 :          12 :   end subroutine latt_finalize
     335                 :             : 
     336                 :             : 
     337                 :             :   !-------------------------------------------------------------------!
     338                 :             :   ! latt_fill_supercell: make a lattice supercell from primitive cell
     339                 :             :   ! Inputs:
     340                 :             :   !> sc_maker: supercell maker
     341                 :             :   ! Output:
     342                 :             :   !> supercell: supercell
     343                 :             :   !-------------------------------------------------------------------!
     344                 :           6 :   subroutine latt_fill_supercell(self, sc_maker, supercell)
     345                 :             :     class(mbcell_lattice_t), intent(inout):: self
     346                 :             :     type(supercell_maker_t), intent(inout):: sc_maker
     347                 :             :     type(mbcell_lattice_t), intent(inout):: supercell
     348                 :             : 
     349                 :             :     real(dp) :: sc_cell(3,3)
     350                 :           6 :     real(dp), allocatable :: sc_xcart(:,:)
     351                 :           6 :     real(dp), allocatable :: sc_masses(:)
     352                 :           6 :     integer, allocatable :: sc_zion(:)
     353                 :             : 
     354                 :           6 :     sc_cell(:,:) = sc_maker%sc_cell(self%cell)
     355                 :             : 
     356                 :             :     ! the trans_xcart and repeat does the allocation
     357                 :           6 :     call sc_maker%trans_xcart(self%cell, self%xcart, sc_xcart)
     358                 :           6 :     call sc_maker%repeat(self%masses, sc_masses)
     359                 :           6 :     call sc_maker%repeat(self%zion, sc_zion)
     360                 :           6 :     call supercell%initialize(natom=self%natom*sc_maker%ncells, cell=sc_cell, xcart= sc_xcart, masses=sc_masses, zion=sc_zion)
     361                 :             : 
     362         [ +  - ]:           6 :     ABI_SFREE(sc_xcart)
     363         [ +  - ]:           6 :     ABI_SFREE(sc_masses)
     364         [ +  - ]:           6 :     ABI_SFREE(sc_zion)
     365   [ -  +  -  +  :           6 :   end subroutine latt_fill_supercell
                   -  + ]
     366                 :             : 
     367                 :             : 
     368                 :             :   !-------------------------------------------------------------------!
     369                 :             :   !latt_from_unitcell: build lattice supercell from primitive cell
     370                 :             :   ! same as above, only the order of argument differs.
     371                 :             :   !-------------------------------------------------------------------!
     372                 :           0 :   subroutine latt_from_unitcell(self, sc_maker, unitcell)
     373                 :             :     class(mbcell_lattice_t), intent(inout):: self
     374                 :             :     type(supercell_maker_t), intent(inout):: sc_maker
     375                 :             :     type(mbcell_lattice_t), intent(inout):: unitcell
     376                 :           0 :     call unitcell%fill_supercell(sc_maker, self)
     377                 :           0 :   end subroutine latt_from_unitcell
     378                 :             : 
     379                 :             :   !========================= SPIN =================================
     380                 :             : 
     381                 :             : 
     382                 :             :   !----------------------------------------------------------------------
     383                 :             :   !> @brief initialize spin
     384                 :             :   !> @param[in]  nspin: number of spin
     385                 :             :   !----------------------------------------------------------------------
     386                 :           4 :   Subroutine spin_initialize(self, nspin)
     387                 :             :     class(mbcell_spin_t) , intent(inout):: self
     388                 :             :     integer, intent(in) :: nspin
     389                 :             :     integer :: master, my_rank, comm, nproc, ierr
     390                 :             :     logical :: iam_master
     391                 :           4 :     call init_mpi_info(master, iam_master, my_rank, comm, nproc)
     392                 :           4 :     self%nspin=nspin
     393                 :           4 :     call xmpi_bcast(self%nspin, master, comm, ierr)
     394   [ -  +  +  -  :          12 :     ABI_MALLOC(self%spin_positions, (3, self%nspin))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     395   [ -  +  +  -  :          12 :     ABI_MALLOC(self%ms, (self%nspin))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     396   [ -  +  +  -  :           8 :     ABI_MALLOC(self%Sref, (3, self%nspin))
          -  +  -  +  -  
                      + ]
     397   [ -  +  +  -  :           8 :     ABI_MALLOC(self%gyro_ratio, (self%nspin))
          -  +  -  +  -  
                      + ]
     398   [ -  +  +  -  :           8 :     ABI_MALLOC(self%gilbert_damping, (self%nspin))
          -  +  -  +  -  
                      + ]
     399   [ -  +  +  -  :          12 :     ABI_MALLOC(self%rvec,(3, self%nspin) )
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     400   [ -  +  +  -  :          12 :     ABI_MALLOC(self%ispin_prim,(self%nspin) )
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     401                 :           4 :   end subroutine spin_initialize
     402                 :             : 
     403                 :             : 
     404                 :             :   !----------------------------------------------------------------------
     405                 :             :   !> @brief initialize spin sub type
     406                 :             :   !>
     407                 :             :   !> @param[in]  nspin: number of spin
     408                 :             :   !> @param[in] ms: magnetic moments
     409                 :             :   !> @param[in] rprimd:  cell pareters
     410                 :             :   !> @param[in] spin_positions:  the cartesion coordinates of spins
     411                 :             :   !> @param[in] gyro_ratio: gyromagnetic ratio fro each spin
     412                 :             :   !> @param[in] gilbert_damping: damping factor for each spin
     413                 :             :   !> @param[in] rvec: R vectors for cell in supercell
     414                 :             :   !> @param[in] ispin_prim:  id in primitive cell for each spin
     415                 :             :   !----------------------------------------------------------------------
     416                 :          16 :   subroutine spin_set(self, nspin, ms, rprimd, spin_positions, gyro_ratio, gilbert_damping, &
     417                 :           2 :        & rvec, ispin_prim, Sref, ref_qpoint, ref_rotate_axis)
     418                 :             :     class(mbcell_spin_t) , intent(inout):: self
     419                 :             :     integer, intent(in) :: nspin
     420                 :             :     real(dp), intent(in) :: ms(nspin), rprimd(3,3), &
     421                 :             :          &spin_positions(3, nspin), gyro_ratio(nspin), gilbert_damping(nspin)
     422                 :             :     integer, optional, intent(in) :: rvec(3, nspin), ispin_prim(nspin)
     423                 :             :     real(dp), optional, intent(in) :: Sref(3, nspin), ref_qpoint(3), ref_rotate_axis(3)
     424                 :             : 
     425                 :             :     integer :: i
     426                 :             :     integer :: master, my_rank, comm, nproc, ierr
     427                 :             :     logical :: iam_master
     428                 :             : 
     429                 :           2 :     call init_mpi_info(master, iam_master, my_rank, comm, nproc)
     430         [ +  - ]:           2 :     if (iam_master) then
     431         [ +  + ]:           4 :        self%ms(:) = ms(:)
     432   [ +  +  +  + ]:          26 :        self%rprimd(:,:) = rprimd(:,:)
     433   [ +  +  +  + ]:          10 :        self%spin_positions(:,:)=spin_positions(:,:)
     434         [ +  + ]:           4 :        self%gyro_ratio(:)=gyro_ratio(:)
     435         [ +  + ]:           4 :        self%gilbert_damping(:)=gilbert_damping(:)
     436         [ -  + ]:           2 :        if (present(rvec)) then
     437   [ #  #  #  # ]:           0 :           self%rvec(:,:)=rvec(:,:)
     438                 :             :        else
     439   [ +  +  +  + ]:          10 :           self%rvec(:,:)=0
     440                 :             :        end if
     441         [ +  - ]:           2 :        if (present(ispin_prim)) then
     442         [ #  # ]:           0 :           self%ispin_prim(:)=ispin_prim
     443                 :             :        else
     444         [ +  + ]:           4 :           do i =1 , nspin
     445                 :           4 :              self%ispin_prim(i)=i
     446                 :             :           end do
     447                 :             :        end if
     448                 :             : 
     449         [ +  - ]:           2 :        if (present(Sref)) then
     450   [ +  +  +  + ]:          10 :           self%Sref(:,:) = Sref
     451                 :             :        else
     452                 :           0 :           ABI_WARNING("No reference spin structure specified, using ferromagnetic along z-axis")
     453                 :             : 
     454         [ #  # ]:           0 :           self%Sref(1,:) = 0.0_dp
     455         [ #  # ]:           0 :           self%Sref(2,:) = 0.0_dp
     456         [ #  # ]:           0 :           self%Sref(3,:) = 1.0_dp
     457                 :             :        end if
     458                 :             : 
     459         [ +  - ]:           2 :        if (present(ref_qpoint)) then
     460         [ +  + ]:           8 :           self%ref_qpoint(:) = ref_qpoint
     461                 :             :        else
     462         [ #  # ]:           0 :           self%ref_qpoint(:)=[0.0_dp, 0.0_dp, 0.0_dp]
     463                 :             :        end if
     464                 :             : 
     465         [ +  - ]:           2 :        if (present(ref_rotate_axis)) then
     466         [ +  + ]:           8 :           self%ref_rotate_axis(:) = ref_rotate_axis
     467                 :             :        else
     468         [ #  # ]:           0 :           self%ref_rotate_axis(:)=[1.0_dp, 0.0_dp, 0.0_dp]
     469                 :             :        end if
     470                 :             : 
     471                 :             :     endif
     472                 :             : 
     473                 :           2 :     call xmpi_bcast(self%spin_positions, master, comm, ierr)
     474                 :           2 :     call xmpi_bcast(self%rprimd, master, comm, ierr)
     475                 :           2 :     call xmpi_bcast(self%ms, master, comm, ierr)
     476                 :           2 :     call xmpi_bcast(self%Sref, master, comm, ierr)
     477                 :           2 :     call xmpi_bcast(self%gyro_ratio, master, comm, ierr)
     478                 :           2 :     call xmpi_bcast(self%gilbert_damping, master, comm, ierr)
     479                 :           2 :     call xmpi_bcast(self%rvec, master, comm, ierr)
     480                 :           2 :     call xmpi_bcast(self%ispin_prim, master, comm, ierr)
     481                 :           2 :     call xmpi_bcast(self%ref_qpoint, master, comm, ierr)
     482                 :           2 :     call xmpi_bcast(self%ref_rotate_axis, master, comm, ierr)
     483   [ -  +  -  +  :           2 :   end Subroutine spin_set
                   +  - ]
     484                 :             : 
     485                 :             : 
     486                 :          12 :   subroutine spin_finalize(self)
     487                 :             :     class(mbcell_spin_t) :: self
     488                 :          12 :     self%nspin=0
     489         [ +  + ]:          12 :     ABI_SFREE(self%ms)
     490         [ +  + ]:          12 :     ABI_SFREE(self%Sref)
     491         [ +  + ]:          12 :     ABI_SFREE(self%spin_positions)
     492         [ +  + ]:          12 :     ABI_SFREE(self%gyro_ratio)
     493         [ +  + ]:          12 :     ABI_SFREE(self%gilbert_damping)
     494         [ +  + ]:          12 :     ABI_SFREE(self%ispin_prim)
     495         [ +  + ]:          12 :     ABI_SFREE(self%rvec)
     496                 :          12 :   end subroutine spin_finalize
     497                 :             : 
     498                 :          16 :   subroutine spin_fill_supercell(self, sc_maker, supercell)
     499                 :             :     class(mbcell_spin_t),intent(inout) :: self
     500                 :             :     type(supercell_maker_t), intent(inout):: sc_maker
     501                 :             :     type(mbcell_spin_t), intent(inout) :: supercell
     502                 :             :     integer :: i, nspin
     503                 :             :     integer :: master, my_rank, comm, nproc, ierr
     504                 :             :     logical :: iam_master
     505                 :           2 :     call init_mpi_info(master, iam_master, my_rank, comm, nproc)
     506                 :             : 
     507                 :           2 :     nspin=sc_maker%ncells*self%nspin
     508                 :           2 :     call supercell%initialize(nspin=nspin)
     509                 :             : 
     510         [ +  - ]:           2 :     if(iam_master) then
     511                 :           2 :        call sc_maker%repeat(self%ms, supercell%ms)
     512                 :           2 :        call sc_maker%repeat(self%gyro_ratio, supercell%gyro_ratio)
     513                 :           2 :        call sc_maker%repeat(self%gilbert_damping, supercell%gilbert_damping)
     514   [ +  -  +  +  :           8 :        call sc_maker%repeat([(i ,i=1, self%nspin)], supercell%ispin_prim)
             +  -  +  + ]
     515   [ +  +  +  + ]:          26 :        supercell%rprimd(:,:)=sc_maker%sc_cell(self%rprimd)
     516                 :             : 
     517                 :           2 :        call sc_maker%trans_xcart(self%rprimd, self%spin_positions, supercell%spin_positions)
     518                 :           2 :        call sc_maker%rvec_for_each(self%nspin, supercell%rvec)
     519                 :             :        call sc_maker%generate_spin_wave_vectorlist( A=self%Sref, kpoint=self%ref_qpoint, &
     520                 :           2 :             & axis=self%ref_rotate_axis, A_sc=supercell%Sref)
     521         [ +  + ]:           8 :        supercell%ref_qpoint(:)=[0.0_dp, 0.0_dp, 0.0_dp]   ! Qpoint is gamma in supercell
     522         [ +  + ]:           8 :        supercell%ref_rotate_axis= self%ref_rotate_axis
     523                 :             :     end if
     524                 :           2 :     call xmpi_bcast(supercell%nspin, master, comm, ierr)
     525                 :           2 :     call xmpi_bcast(supercell%ms, master, comm, ierr)
     526                 :           2 :     call xmpi_bcast(supercell%gyro_ratio, master, comm, ierr)
     527                 :           2 :     call xmpi_bcast(supercell%gilbert_damping, master, comm, ierr)
     528                 :           2 :     call xmpi_bcast(supercell%ispin_prim, master, comm, ierr)
     529                 :           2 :     call xmpi_bcast(supercell%spin_positions, master, comm, ierr)
     530                 :           2 :     call xmpi_bcast(supercell%rvec, master, comm, ierr)
     531                 :           2 :     call xmpi_bcast(supercell%rprimd, master, comm, ierr)
     532                 :           2 :   end subroutine spin_fill_supercell
     533                 :             : 
     534                 :             :   !----------------------------------------------------------------------
     535                 :             :   !> @brief read from netcdf
     536                 :             :   !>
     537                 :             :   !> @build from a unitcell
     538                 :             :   !----------------------------------------------------------------------
     539                 :           0 :   subroutine spin_from_unitcell(self, sc_maker, unitcell)
     540                 :             :     class(mbcell_spin_t),intent(inout) :: self
     541                 :             :     type(supercell_maker_t), intent(inout):: sc_maker
     542                 :             :     type(mbcell_spin_t), intent(inout) :: unitcell
     543                 :           0 :     call unitcell%fill_supercell(sc_maker, self)
     544                 :           0 :   end subroutine spin_from_unitcell
     545                 :             : 
     546                 :             : 
     547                 :             :   !========================= LWF =================================
     548                 :           1 :   Subroutine lwf_initialize(self, nlwf)
     549                 :             :     class(mbcell_lwf_t), intent(inout) :: self
     550                 :             :     integer, intent(in) :: nlwf
     551                 :           1 :     self%nlwf=nlwf
     552   [ -  +  +  -  :           3 :     ABI_MALLOC(self%ilwf_prim, (nlwf))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     553   [ -  +  +  -  :           3 :     ABI_MALLOC(self%rvec, (3, nlwf))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     554   [ -  +  +  -  :           3 :     ABI_MALLOC(self%lwf_masses, (nlwf))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     555                 :             :     !ABI_MALLOC(self%lwf_latt_coeffs, (self%nlwf))
     556                 :             :     !call self%lwf_latt_coeffs%initialize(self%nlwf, wlf)
     557                 :             :     ! lwf_latt_coeffs is only initialized in primitive potential
     558                 :           1 :   end subroutine lwf_initialize
     559                 :             : 
     560                 :          12 :   subroutine lwf_finalize(self)
     561                 :             :     class(mbcell_lwf_t), intent(inout) :: self
     562                 :          12 :     self%nlwf=0
     563         [ +  + ]:          12 :     ABI_SFREE(self%ilwf_prim)
     564         [ +  + ]:          12 :     ABI_SFREE(self%rvec)
     565         [ +  + ]:          12 :     ABI_SFREE(self%lwf_masses)
     566                 :          12 :     call self%lwf_latt_coeffs%finalize()
     567                 :          12 :   end subroutine lwf_finalize
     568                 :             : 
     569                 :           1 :   subroutine lwf_fill_supercell(self, sc_maker,supercell)
     570                 :             :     class(mbcell_lwf_t) :: self
     571                 :             :     type(supercell_maker_t):: sc_maker
     572                 :             :     type(mbcell_lwf_t) :: supercell
     573                 :           1 :     call supercell%from_unitcell(sc_maker, self)
     574                 :           0 :   end subroutine lwf_fill_supercell
     575                 :             : 
     576                 :           1 :   subroutine lwf_from_unitcell(self, sc_maker, unitcell)
     577                 :             :     class(mbcell_lwf_t) :: self
     578                 :             :     type(supercell_maker_t):: sc_maker
     579                 :             :     type(mbcell_lwf_t) :: unitcell
     580                 :             :     integer :: i
     581                 :           1 :     self%nlwf=sc_maker%ncells*unitcell%nlwf
     582   [ +  -  +  +  :           6 :     call sc_maker%repeat([(i ,i=1, unitcell%nlwf)], self%ilwf_prim)
             +  -  +  + ]
     583                 :           1 :     call sc_maker%rvec_for_each(unitcell%nlwf, self%rvec)
     584                 :           1 :     call sc_maker%repeat_real1d(unitcell%lwf_masses, self%lwf_masses)
     585                 :           1 :   end subroutine lwf_from_unitcell
     586                 :             : 
     587   [ #  #  #  #  :           0 : end module m_multibinit_cell
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
        

Generated by: LCOV version 2.3-1