Branch data Line data Source code
1 : : !!****m* ABINIT/m_spin_potential
2 : : !! NAME
3 : : !! m_spin_potential
4 : : !!
5 : : !! FUNCTION
6 : : !! This module contains the spin hamiltonian, and the methods for
7 : : !! calculating effective magnetic field (torque), dS/dt, and total_energy
8 : : !!
9 : : !!
10 : : !! Datatypes:
11 : : !!
12 : : !! * spin_potential_t
13 : : !!
14 : : !! Subroutines:
15 : : !!
16 : : !! * spin_potential_t_initialize
17 : : !! * spin_potential_t_finalize
18 : : !! * spin_potential_t_total_Heff : calculate total Heff (no Langevin term)
19 : : !! * spin_potential_t_Heff_to_dSdt:
20 : : !! * spin_potential_t_get_dSdt : dSdt, Langevin term is an input.
21 : : !! * spin_potential_t_get_Langevin_Heff
22 : :
23 : : !!
24 : : !!
25 : : !! COPYRIGHT
26 : : !! Copyright (C) 2001-2026 ABINIT group (TO, hexu)
27 : : !! This file is distributed under the terms of the
28 : : !! GNU General Public License, see ~abinit/COPYING
29 : : !! or http://www.gnu.org/copyleft/gpl.txt .
30 : : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
31 : : !!
32 : : !! SOURCE
33 : :
34 : : #if defined HAVE_CONFIG_H
35 : : #include "config.h"
36 : : #endif
37 : : #include "abi_common.h"
38 : : module m_spin_potential
39 : : use defs_basis
40 : : use m_errors
41 : : use m_abicore
42 : : use m_xmpi
43 : : use m_mpi_scheduler, only: mb_mpi_info_t, init_mpi_info, mpi_scheduler_t
44 : : use m_multibinit_dataset, only: multibinit_dtset_type
45 : : use m_multibinit_cell, only: mbcell_t, mbsupercell_t
46 : : use m_spmat_coo, only: coo_mat_t
47 : : use m_spmat_lil, only: lil_mat_t
48 : : use m_spmat_csr, only : CSR_mat_t
49 : : use m_spmat_convert, only : spmat_convert
50 : : use m_abstract_potential, only : abstract_potential_t
51 : : use m_hashtable_strval, only: hash_table_t
52 : : implicit none
53 : : !!***
54 : : private
55 : :
56 : : type, public, extends(abstract_potential_t) :: spin_potential_t
57 : : integer :: nspin=0
58 : : logical :: has_external_hfield, has_dipdip
59 : : real(dp) :: eref !energy of reference spin state
60 : :
61 : : ! Array or scalar?
62 : : real(dp), allocatable :: external_hfield(:,:)
63 : :
64 : : ! Exchange/DMI/dipdip stored like COO sparse matrix form.
65 : : type(lil_mat_t) :: coeff_coo
66 : : logical :: csr_mat_ready= .False.
67 : : logical :: has_onsite = .False.
68 : : type(CSR_mat_t) :: bilinear_csr_mat
69 : : ! 3, 3, ninit
70 : :
71 : : ! vector for calculating effective field
72 : : real(dp), allocatable :: Htmp(:, :)
73 : : real(dp), allocatable :: ms(:)
74 : : real(dp), allocatable :: onsite_bilinear_term(:, :, :)
75 : : type(mb_mpi_info_t) :: mpiinfo
76 : : type(mpi_scheduler_t) :: mps
77 : : CONTAINS
78 : : procedure :: initialize
79 : : procedure :: finalize
80 : : procedure :: set_params
81 : : procedure :: set_supercell
82 : : procedure :: get_Heff => spin_potential_t_total_Heff
83 : : procedure :: set_external_hfield
84 : : procedure :: calc_bilinear_term_Heff
85 : : procedure :: calc_external_Heff
86 : : procedure :: calculate => spin_potential_t_calculate
87 : : !procedure :: get_energy => spin_potential_t_get_energy
88 : : procedure :: get_delta_E => spin_potential_t_get_delta_E
89 : : procedure :: add_bilinear_term
90 : : procedure :: add_bilinear_term_spin_block
91 : : procedure :: set_bilinear_term
92 : : procedure, private :: prepare_csr_matrix
93 : : procedure :: set_terms
94 : : end type spin_potential_t
95 : :
96 : : contains
97 : :
98 : 2 : subroutine initialize(self, nspin)
99 : : !Arguments ------------------------------------
100 : : !scalars
101 : : class(spin_potential_t), intent(inout) :: self
102 : : integer :: nspin
103 : :
104 : : integer :: master, my_rank, comm, nproc, ierr
105 : : logical :: iam_master
106 : 2 : call init_mpi_info(master, iam_master, my_rank, comm, nproc)
107 : 2 : call self%mps%initialize(ntasks=nspin, master=master, comm=comm)
108 : 2 : self%label="SpinPotential"
109 : 2 : self%has_spin=.True.
110 : 2 : self%has_displacement=.False.
111 : 2 : self%has_strain=.False.
112 : 2 : self%is_null=.False.
113 : 2 : self%nspin=nspin
114 : 2 : call xmpi_bcast(self%nspin, master, comm, ierr)
115 [ - + + - : 6 : ABI_MALLOC( self%ms, (self%nspin))
+ - + - -
+ - + -
+ ]
116 [ + - ]: 2 : if(iam_master) then
117 [ + + ]: 6 : call self%coeff_coo%initialize([self%nspin*3, self%nspin*3])
118 : : endif
119 [ - + + - : 6 : ABI_MALLOC(self%external_hfield, (3,self%nspin))
+ - + - -
+ - + -
+ ]
120 [ + + + + ]: 1730 : self%external_hfield=0.0_dp
121 [ - + + - : 4 : ABI_MALLOC( self%Htmp, (3, self%nspin))
- + - + -
+ ]
122 [ + + + + ]: 1730 : self%Htmp(:,:)=0.0_dp
123 : :
124 : 2 : self%has_external_hfield=.False.
125 : 2 : self%has_dipdip=.False.
126 [ - + + - : 6 : ABI_MALLOC(self%onsite_bilinear_term, (3, 3, self%nspin))
+ - + - -
+ - + -
+ ]
127 [ + + + + : 5618 : self%onsite_bilinear_term = 0.0_dp
+ + ]
128 : 2 : end subroutine initialize
129 : :
130 : 8 : subroutine set_supercell(self, supercell)
131 : : class(spin_potential_t), intent(inout) :: self
132 : : type(mbsupercell_t), target, intent(inout) :: supercell
133 : : integer :: master, my_rank, comm, nproc, ierr
134 : : logical :: iam_master
135 : 4 : call init_mpi_info(master, iam_master, my_rank, comm, nproc)
136 : :
137 : 4 : self%supercell=>supercell
138 [ + + ]: 868 : self%ms(:)=supercell%spin%ms(:)
139 : 4 : call xmpi_bcast(self%ms, master, comm, ierr)
140 : 4 : end subroutine set_supercell
141 : :
142 : 0 : subroutine set_terms(self, &
143 [ # # # # : 0 : & external_hfield, &
# # ]
144 [ # # # # : 0 : & bilinear_i, bilinear_j, bilinear_val)
# # # # #
# # # # #
# # # # ]
145 : :
146 : : !Arguments ------------------------------------
147 : : !scalars
148 : : !arrays
149 : : class(spin_potential_t), intent(inout) :: self
150 : :
151 : : ! Terms.
152 : : real(dp), optional, intent(in) :: external_hfield(:,:)
153 : : integer, optional, intent(in) :: bilinear_i(:), bilinear_j(:)
154 : : real(dp), optional,intent(in) :: bilinear_val(:)
155 : :
156 : : !Local variables-------------------------------
157 : : ! *************************************************************************
158 : :
159 : :
160 [ # # ]: 0 : if(present(external_hfield)) then
161 : 0 : call self%set_external_hfield( external_hfield)
162 : : end if
163 : :
164 [ # # # # ]: 0 : if ( present(bilinear_i) .and. present( bilinear_j) .and. present(bilinear_val) ) then
165 : 0 : call self%set_bilinear_term(bilinear_i, bilinear_j, bilinear_val)
166 : : endif
167 : :
168 : 0 : end subroutine set_terms
169 : :
170 : : !-------------------------------------------------------------------!
171 : : !set_params :
172 : : !-------------------------------------------------------------------!
173 : 2 : subroutine set_params(self, params)
174 : : class(spin_potential_t), intent(inout) :: self
175 : : type(multibinit_dtset_type), intent(inout) :: params
176 : 4 : real(dp) :: tmp(3, self%nspin)
177 : : integer :: i
178 : : integer :: master, my_rank, comm, nproc
179 : : logical :: iam_master
180 : 2 : call init_mpi_info(master, iam_master, my_rank, comm, nproc)
181 [ + - ]: 2 : if(iam_master) then
182 [ + + ]: 434 : do i=1, self%nspin
183 [ + + ]: 1730 : tmp(:, i)=params%spin_mag_field(:)
184 : : end do
185 : : endif
186 : 2 : call self%set_external_hfield(tmp)
187 : 2 : end subroutine set_params
188 : :
189 : :
190 [ - + ]: 2 : subroutine set_external_hfield(self, external_hfield)
191 : : class(spin_potential_t), intent(inout) :: self
192 : : real(dp), intent(in) :: external_hfield(:,:)
193 : : integer :: master, my_rank, comm, nproc, ierr
194 : : logical :: iam_master
195 : 2 : call init_mpi_info(master, iam_master, my_rank, comm, nproc)
196 : 2 : self%has_external_hfield = .true.
197 [ + - + - : 1732 : self%external_hfield = external_hfield
- + - - +
+ + + ]
198 : 2 : call xmpi_bcast(self%has_external_hfield, master, comm, ierr)
199 : 2 : call xmpi_bcast(self%external_hfield, master, comm, ierr)
200 : 2 : end subroutine set_external_hfield
201 : :
202 [ - + ]: 4006 : subroutine calc_external_Heff(self, Heff)
203 : : class(spin_potential_t), intent(inout) :: self
204 : : real(dp), intent(out) :: Heff(:,:)
205 : : integer :: i
206 [ + + ]: 869302 : do i= self%mps%istart, self%mps%iend
207 [ + + ]: 3465190 : Heff(:, i)= self%external_hfield(:, i)
208 : : end do
209 : 4006 : end subroutine calc_external_Heff
210 : :
211 : 33696 : subroutine add_bilinear_term(self, i,j, val)
212 : : class(spin_potential_t), intent(inout) :: self
213 : : integer, intent(in) :: i, j
214 : : real(dp), intent(in) :: val
215 : : integer :: master, my_rank, comm, nproc
216 : : logical :: iam_master
217 : 33696 : call init_mpi_info(master, iam_master, my_rank, comm, nproc)
218 [ + - ]: 33696 : if(iam_master) then
219 [ + + ]: 101088 : call self%coeff_coo%add_entry(ind=[i,j],val=val)
220 : : endif
221 : 33696 : end subroutine add_bilinear_term
222 : :
223 [ # # # # : 0 : subroutine set_bilinear_term(self, ilist,jlist, vallist)
# # ]
224 : : class(spin_potential_t), intent(inout) :: self
225 : : integer, intent(in) :: ilist(:), jlist(:)
226 : : real(dp), intent(in) :: vallist(:)
227 : : integer :: i
228 : : integer :: master, my_rank, comm, nproc
229 : : logical :: iam_master
230 : 0 : call init_mpi_info(master, iam_master, my_rank, comm, nproc)
231 : :
232 [ # # ]: 0 : if (iam_master) then
233 [ # # ]: 0 : do i = 1, size(ilist)
234 [ # # ]: 0 : call self%coeff_coo%add_entry(ind=[ilist(i),jlist(i)],val=vallist(i))
235 : : end do
236 : : endif
237 : 0 : end subroutine set_bilinear_term
238 : :
239 : :
240 [ # # ]: 0 : subroutine add_bilinear_term_spin_block(self, ispin, jspin, val)
241 : :
242 : : class(spin_potential_t), intent(inout) :: self
243 : : integer, intent(in) :: ispin, jspin
244 : : real(dp), intent(in) :: val(:,:)
245 : : integer :: ia, ib
246 : :
247 : : integer :: master, my_rank, comm, nproc
248 : : logical :: iam_master
249 : 0 : call init_mpi_info(master, iam_master, my_rank, comm, nproc)
250 : :
251 [ # # ]: 0 : if(iam_master) then
252 [ # # ]: 0 : do ia = 1, 3, 1
253 [ # # ]: 0 : do ib=1, 3, 1
254 : : call self%coeff_coo%add_entry([(ispin-1)*3+ia, &
255 [ # # ]: 0 : (jspin-1)*3+ib], val=val(ia,ib))
256 : : end do
257 : : end do
258 [ # # ]: 0 : if(ispin==jspin) then
259 : 0 : self%has_onsite = .True.
260 [ # # # # ]: 0 : self%onsite_bilinear_term(:, :, ispin) = val(:, :)
261 : : end if
262 : : endif
263 : 0 : end subroutine add_bilinear_term_spin_block
264 : :
265 : 4006 : subroutine prepare_csr_matrix(self)
266 : : class(spin_potential_t), intent(inout) :: self
267 : : integer :: master, my_rank, comm, nproc, ierr
268 : : logical :: iam_master
269 : : integer :: ispin
270 : :
271 [ + + ]: 4006 : if (.not. self%csr_mat_ready) then
272 : 2 : call init_mpi_info(master, iam_master, my_rank, comm, nproc)
273 [ + - ]: 2 : if(iam_master) then
274 : 2 : call spmat_convert(self%coeff_coo, self%bilinear_csr_mat)
275 : : endif
276 : 2 : call self%coeff_coo%finalize()
277 : 2 : call self%bilinear_csr_mat%sync(master=master, comm=comm, nblock=1)
278 : 2 : self%csr_mat_ready=.True.
279 : 2 : call xmpi_bcast(self%csr_mat_ready, master, comm, ierr)
280 : : ! also broadcast the onsite terms.
281 [ + + ]: 434 : do ispin=1, self%nspin
282 : 434 : call self%bilinear_csr_mat%get_block(ispin*3-2, ispin*3-2, 3, 3, self%onsite_bilinear_term(:, :, ispin))
283 : : !print *, "ispin:", ispin
284 : : !print *, "oniste", self%onsite_bilinear_term(:, :, ispin)
285 : : end do
286 : 2 : self%has_onsite=.True.
287 : :
288 : 2 : call xmpi_bcast(self%has_onsite, master, comm, ierr)
289 : 2 : call xmpi_bcast(self%onsite_bilinear_term, master, comm, ierr)
290 : : endif
291 : 4006 : end subroutine prepare_csr_matrix
292 : :
293 : :
294 [ - + ]: 4006 : subroutine calc_bilinear_term_Heff(self, S, Heff)
295 : : class(spin_potential_t), intent(inout) :: self
296 : : real(dp), intent(inout) :: S(:,:)
297 : : real(dp), intent(out) :: Heff(3,self%nspin)
298 : : integer :: i
299 : : !call self%bilinear_csr_mat%mv(S ,Heff)
300 : 4006 : call self%prepare_csr_matrix()
301 [ - + - - : 4006 : call self%bilinear_csr_mat%mv_mpi(x=S ,b=Heff, bcastx=.False., syncb=.False.)
- - - - -
+ - - -
- ]
302 [ + + ]: 869302 : do i= self%mps%istart, self%mps%iend
303 [ + + ]: 3465190 : Heff(:, i)=Heff(:,i)/self%ms(i)*2.0_dp
304 : : end do
305 : 4006 : end subroutine calc_bilinear_term_Heff
306 : :
307 [ + - + - : 8008 : subroutine spin_potential_t_calculate(self, displacement, strain, spin, lwf, &
- + ]
308 [ + + + - : 8008 : force, stress, bfield, lwf_force, energy, energy_table)
- + ]
309 : : class(spin_potential_t), intent(inout) :: self
310 : : real(dp), optional, intent(inout) :: displacement(:,:), strain(:,:), spin(:,:), lwf(:)
311 : : real(dp), optional, intent(inout) :: force(:,:), stress(:,:), bfield(:,:), lwf_force(:), energy
312 : : type(hash_table_t),optional, intent(inout) :: energy_table
313 : : real(dp) :: etmp
314 : : ! if present in input
315 : : ! calculate if required
316 : :
317 [ + + ]: 8008 : if (present(bfield) ) then
318 [ - + - - : 4004 : call self%get_Heff(spin, bfield, etmp)
- - - - -
+ - - - -
- - - + -
- - - - +
- - - - ]
319 : :
320 : : ! subtract enery of reference spin configuration
321 : 4004 : etmp = etmp - self%eref
322 : :
323 : : ! only update energy when bfield is asked for.
324 [ + - ]: 4004 : if ( present(energy)) then
325 : 4004 : energy=energy+etmp
326 : : end if
327 [ + - ]: 4004 : if (present(energy_table)) then
328 : 4004 : call energy_table%put(self%label, etmp)
329 : : end if
330 : : end if
331 : :
332 : :
333 : 8008 : ABI_UNUSED_A(self)
334 : 8008 : ABI_UNUSED_A(displacement)
335 : 8008 : ABI_UNUSED_A(strain)
336 : 8008 : ABI_UNUSED_A(spin)
337 : 8008 : ABI_UNUSED_A(lwf)
338 : 8008 : ABI_UNUSED_A(force)
339 : 8008 : ABI_UNUSED_A(stress)
340 : 8008 : ABI_UNUSED_A(bfield)
341 : 8008 : ABI_UNUSED_A(lwf_force)
342 : 8008 : ABI_UNUSED_A(energy)
343 : 8008 : end subroutine spin_potential_t_calculate
344 : :
345 : :
346 : 4006 : subroutine spin_potential_t_total_Heff(self,S, Heff, energy)
347 : : class(spin_potential_t), intent(inout) :: self
348 : : real(dp), intent(inout):: S(3,self%nspin)
349 : : real(dp), intent(inout):: Heff(3,self%nspin)
350 : : real(dp), intent(inout) :: energy
351 : : real(dp) :: etmp
352 : : integer :: i, j
353 : : integer :: master, my_rank, comm, nproc, ierr
354 : : logical :: iam_master
355 : 4006 : call init_mpi_info(master, iam_master, my_rank, comm, nproc)
356 : :
357 [ + + + + ]: 3465190 : self%Htmp(:,:)=0.0_dp
358 : 4006 : etmp=0.0_dp
359 : :
360 : :
361 : : ! calculate energy from bilinear terms (all the above ones)
362 : 4006 : call self%calc_bilinear_term_Heff(S,self%Htmp)
363 [ + + ]: 869302 : do i= self%mps%istart, self%mps%iend
364 [ + + ]: 3461184 : Heff(:,i)=Heff(:,i)+self%Htmp(:,i)
365 [ + + ]: 3465190 : do j=1, 3
366 : 3461184 : etmp=etmp-(self%Htmp(j, i)*S(j,i)*self%ms(i))*0.5_dp
367 : : end do
368 : : enddo
369 : : if(iam_master) then
370 : : if (self%has_dipdip) then
371 : : continue
372 : : ! TODO implement dipdip and add it
373 : : endif
374 : : endif
375 : :
376 : : ! linear terms
377 [ + - ]: 4006 : if (self%has_external_hfield) then
378 [ + + + + ]: 3465190 : self%Htmp(:,:)= 0.0_dp
379 : 4006 : call self%calc_external_Heff(self%Htmp)
380 [ + + ]: 869302 : do i= self%mps%istart, self%mps%iend
381 [ + + ]: 3461184 : Heff(:,i)=Heff(:,i)+self%Htmp(:,i)
382 [ + + ]: 3465190 : do j=1, 3
383 : 3461184 : etmp=etmp-(self%Htmp(j, i)*S(j,i)*self%ms(i))
384 : : end do
385 : : enddo
386 : : endif
387 : :
388 : 4006 : call xmpi_sum_master(etmp, 0, xmpi_world, ierr )
389 : : ! NOTE: here energy is not added to input energy.
390 : 4006 : energy=etmp
391 : :
392 : 4006 : end subroutine spin_potential_t_total_Heff
393 : :
394 : : ! subroutine spin_potential_t_get_energy(self, S, energy)
395 : : ! class(spin_potential_t), intent(inout) :: self
396 : : ! real(dp), intent(inout):: S(3,self%nspin)
397 : : ! real(dp), intent(inout) :: energy
398 : : ! integer :: i, j
399 : : ! integer :: master, my_rank, comm, nproc, ierr
400 : : ! logical :: iam_master
401 : : ! call init_mpi_info(master, iam_master, my_rank, comm, nproc)
402 : : !
403 : : !
404 : : ! if (.not. self%csr_mat_ready) then
405 : : ! call spmat_convert(self%coeff_coo, self%bilinear_csr_mat)
406 : : ! call self%bilinear_csr_mat%sync()
407 : : ! self%csr_mat_ready=.True.
408 : : ! endif
409 : : ! call self%bilinear_csr_mat%mv_mpi(S ,self%Htmp)
410 : : ! if(iam_master) then
411 : : ! energy=energy - sum(sum(self%Htmp* S, dim=1))
412 : : ! endif
413 : : ! if(iam_master) then
414 : : ! if (self%has_external_hfield) then
415 : : ! call self%calc_external_Heff(self%Htmp)
416 : : ! do i=1, self%nspin
417 : : ! do j=1, 3
418 : : ! energy= energy- self%Htmp(j, i)*S(j, i)*self%ms(i)
419 : : ! end do
420 : : ! end do
421 : : ! endif
422 : : ! end if
423 : : ! end subroutine spin_potential_t_get_energy
424 : :
425 : :
426 [ # # # # ]: 0 : subroutine spin_potential_t_get_delta_E(self, S, ispin, Snew, deltaE)
427 : : class(spin_potential_t), intent(inout) :: self
428 : : real(dp), intent(inout):: S(:,:), Snew(:)
429 : : integer, intent(in) :: ispin
430 : : real(dp), intent(inout) ::deltaE
431 : : !real(dp) :: Eold, Enew
432 : : real(dp) :: tmp(3), dS(3)
433 : :
434 : : ! naive implementation, for test only
435 : : !real(dp) :: Stmp(3,self%nspin), Enew, Eold
436 : : !call self%get_Heff(S, self%Htmp, Eold)
437 : : !call self%bilinear_csr_mat%mv(S, self%Htmp)
438 : : !Eold=-sum(sum(self%Htmp(:,:)*S(:,:), dim=1))
439 : :
440 : : !Stmp(:,:)=S(:,:)
441 : : !Stmp(:, ispin)= Snew(:)
442 : : !call self%get_Heff(Stmp, self%Htmp, Enew)
443 : : !deltaE=Enew-Eold
444 : : !print *, "naive deltaE", deltaE
445 : :
446 : : ! more efficient one
447 [ # # ]: 0 : dS(:)=Snew(:)-S(:, ispin)
448 : : !S(:, ispin)= S(:, ispin)+ dS
449 : :
450 : 0 : deltaE=0.0_dp
451 : :
452 : 0 : call self%prepare_csr_matrix()
453 [ # # # # : 0 : call self%bilinear_csr_mat%mv_select_row(3, [3*ispin-2, 3*ispin-1, 3*ispin], S, tmp)
# # # # #
# # # ]
454 [ # # ]: 0 : deltaE=deltaE-dot_product(tmp, dS ) *2.0
455 [ # # ]: 0 : if (self%has_onsite) then
456 [ # # # # : 0 : tmp=matmul(self%onsite_bilinear_term(:, :, ispin), dS)
# # # # ]
457 [ # # ]: 0 : deltaE = deltaE - dot_product(tmp, dS)
458 : : !print *, "dS K dS:", dot_product(tmp, dS)
459 : : end if
460 : : !print *, "smart deltaE", deltaE
461 : : !S(:, ispin)=S(:,ispin)-dS
462 : : !print *, "diff for ispin:", ispin, Enew-Eold-deltaE
463 : :
464 : :
465 [ # # ]: 0 : if(self%has_external_hfield) then
466 [ # # ]: 0 : deltaE=deltaE - dot_product(self%external_hfield(:, ispin), dS)*self%ms(ispin)
467 : : end if
468 : 0 : end subroutine spin_potential_t_get_delta_E
469 : :
470 : :
471 : 2 : subroutine finalize(self)
472 : : class(spin_potential_t), intent(inout):: self
473 [ + - ]: 2 : if (allocated(self%ms)) then
474 : 2 : ABI_FREE(self%ms)
475 : : end if
476 : :
477 [ + - ]: 2 : ABI_SFREE(self%onsite_bilinear_term)
478 : :
479 [ + - ]: 2 : if (allocated(self%Htmp)) then
480 : 2 : ABI_FREE(self%Htmp)
481 : : endif
482 : :
483 [ + - ]: 2 : if (allocated(self%external_hfield)) then
484 : 2 : ABI_FREE(self%external_hfield)
485 : : endif
486 : :
487 : 2 : call self%bilinear_csr_mat%finalize()
488 [ - + ]: 2 : if (.not. self%csr_mat_ready) then
489 : 0 : call self%coeff_coo%finalize()
490 : : end if
491 : :
492 : 2 : call self%mps%finalize()
493 : :
494 : 2 : end subroutine finalize
495 : :
496 [ + + - + : 6 : end module m_spin_potential
+ + - + +
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + ]
|