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
|