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
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
|