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-09-19 15:24:51 Functions: 62.1 % 29 18

            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