LCOV - code coverage report
Current view: top level - src/78_effpot - m_spin_mover.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 38.6 % 474 183
Test Date: 2026-11-09 11:14:24 Functions: 52.6 % 19 10
Branches: 22.9 % 905 207

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_spin_mover
       2                 :             : !! NAME
       3                 :             : !! m_spin_mover
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !! This module contains the spin mover, which controls how the spin
       7                 :             : !!
       8                 :             : !!
       9                 :             : !! Datatypes:
      10                 :             : !!
      11                 :             : !! * spin_mover_t
      12                 :             : !!
      13                 :             : !! Subroutines:
      14                 :             : !!
      15                 :             : !! * spin_mover_t_initialize
      16                 :             : !! * spin_mover_t_run_one_step
      17                 :             : !! * spin_mover_t_run_time
      18                 :             : !! * TODO: update this when F2003 documentation format decided.
      19                 :             : !!
      20                 :             : !!
      21                 :             : !! COPYRIGHT
      22                 :             : !! Copyright (C) 2001-2026 ABINIT group (hexu)
      23                 :             : !! This file is distributed under the terms of the
      24                 :             : !! GNU General Public License, see ~abinit/COPYING
      25                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
      26                 :             : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
      27                 :             : !!
      28                 :             : !! SOURCE
      29                 :             : 
      30                 :             : 
      31                 :             : #if defined HAVE_CONFIG_H
      32                 :             : #include "config.h"
      33                 :             : #endif
      34                 :             : 
      35                 :             : #include "abi_common.h"
      36                 :             : 
      37                 :             : 
      38                 :             : module m_spin_mover
      39                 :             : 
      40                 :             :   use defs_basis
      41                 :             :   use m_nctk
      42                 :             : #if defined HAVE_NETCDF
      43                 :             :   use netcdf
      44                 :             : #endif
      45                 :             :   use m_errors
      46                 :             :   use m_abicore
      47                 :             :   use m_xmpi
      48                 :             :   use m_io_tools, only : get_unit, open_file, close_unit
      49                 :             :   use m_mpi_scheduler, only: mpi_scheduler_t, init_mpi_info
      50                 :             :   use m_mathfuncs, only : cross
      51                 :             :   use m_spin_observables , only : spin_observable_t
      52                 :             :   use m_spin_potential, only:  spin_potential_t
      53                 :             :   use m_spin_hist, only: spin_hist_t
      54                 :             :   use m_spin_ncfile, only: spin_ncfile_t
      55                 :             :   use m_multibinit_dataset, only: multibinit_dtset_type
      56                 :             :   use m_multibinit_cell, only: mbcell_t, mbsupercell_t
      57                 :             :   use m_random_xoroshiro128plus, only: set_seed, rand_normal_array, rng_t
      58                 :             :   use m_abstract_potential, only: abstract_potential_t
      59                 :             :   use m_abstract_mover, only: abstract_mover_t
      60                 :             :   use m_spin_mc_mover, only : spin_mc_t
      61                 :             :   use m_hashtable_strval, only: hash_table_t
      62                 :             :   implicit none
      63                 :             :   private
      64                 :             :   !!***
      65                 :             : 
      66                 :             : 
      67                 :             :   !!****t* m_spin_mover/spin_mover_t
      68                 :             :   !! NAME
      69                 :             :   !! spin_mover_t
      70                 :             :   !!
      71                 :             :   !! FUNCTION
      72                 :             :   !! this type contains the parameters for the spin mover.
      73                 :             :   !!
      74                 :             :   !! It contains:
      75                 :             :   !! dt: time step
      76                 :             :   !! total_time
      77                 :             :   !! temperature.
      78                 :             :   !! nspin number of magnetic atoms
      79                 :             :   !! SOURCE
      80                 :             : 
      81                 :             : 
      82                 :             :   type, public, extends(abstract_mover_t) :: spin_mover_t
      83                 :             :      integer :: nspin, method=0
      84                 :             :      real(dp), allocatable :: gyro_ratio(:), damping(:), gamma_L(:), H_lang_coeff(:), ms(:), Stmp(:,:), Stmp2(:,:)
      85                 :             :      real(dp), allocatable :: Heff_tmp(:,:), Htmp(:,:), Hrotate(:,:), H_lang(:,:), buffer(:,:)
      86                 :             :      real(dp) :: init_qpoint(3), init_rotate_axis(3) ! qpoint and rotation axis to set up initial spin configuration
      87                 :             :      real(dp) :: init_orientation(3) ! spin orientation in primitive cell which is then rotated
      88                 :             :      type(spin_hist_t) :: hist
      89                 :             :      logical :: gamma_l_calculated
      90                 :             :      type(spin_mc_t) :: spin_mc
      91                 :             :      type(mpi_scheduler_t) :: mps
      92                 :             :      type(spin_observable_t) :: spin_ob
      93                 :             :      type(spin_ncfile_t) :: spin_ncfile
      94                 :             :      type(multibinit_dtset_type), pointer :: params
      95                 :             :    CONTAINS
      96                 :             :      procedure :: initialize
      97                 :             :      procedure :: finalize
      98                 :             :      procedure :: set_initial_state
      99                 :             :      procedure :: read_hist_spin_state
     100                 :             :      procedure, private :: run_one_step_DM => spin_mover_t_run_one_step_DM
     101                 :             :      procedure, private :: run_one_step_HeunP => spin_mover_t_run_one_step_HeunP
     102                 :             :      procedure, private :: run_one_step_dummy=> spin_mover_t_run_one_step_dummy
     103                 :             :      procedure, private :: run_one_step_MC=> spin_mover_t_run_one_step_MC
     104                 :             :      procedure :: run_one_step => spin_mover_t_run_one_step
     105                 :             :      procedure :: run_time => spin_mover_t_run_time
     106                 :             :      procedure :: run_MvT
     107                 :             :      procedure :: set_temperature
     108                 :             :      procedure, private :: prepare_ncfile
     109                 :             :      procedure, private ::get_Langevin_Heff
     110                 :             :      procedure :: current_spin
     111                 :             :      procedure :: set_ncfile_name
     112                 :             :   end type spin_mover_t
     113                 :             :   !!***
     114                 :             : 
     115                 :             : contains
     116                 :             : 
     117                 :             :   !!****f* m_spin_mover/initialize
     118                 :             :   !!
     119                 :             :   !! NAME
     120                 :             :   !!  initialize
     121                 :             :   !!
     122                 :             :   !! FUNCTION
     123                 :             :   !!  initialize the spin mover
     124                 :             :   !!
     125                 :             :   !! INPUTS
     126                 :             :   !!
     127                 :             :   !! OUTPUT
     128                 :             :   !!
     129                 :             :   !! NOTES
     130                 :             :   !!
     131                 :             :   !! SOURCE
     132                 :           2 :   subroutine initialize(self, params, supercell, rng)
     133                 :             :     class(spin_mover_t), intent(inout) :: self
     134                 :             :     type(multibinit_dtset_type), target :: params
     135                 :             :     type(mbsupercell_t), target :: supercell
     136                 :             :     type(rng_t), target, intent(in) :: rng
     137                 :             :     integer ::  nspin
     138                 :             : 
     139                 :             :     integer :: master, my_rank, comm, nproc, ierr
     140                 :             :     logical :: iam_master
     141                 :           2 :     call init_mpi_info(master, iam_master, my_rank, comm, nproc)
     142                 :             : 
     143                 :           2 :     self%params=>params
     144                 :           2 :     self%supercell=>supercell
     145                 :           2 :     self%rng => rng
     146         [ +  - ]:           2 :     if (iam_master) then
     147                 :           2 :        nspin=supercell%spin%nspin
     148                 :           2 :        self%nspin=nspin
     149                 :           2 :        self%dt= params%spin_dt
     150                 :           2 :        self%thermal_time= params%spin_ntime_pre * self%dt
     151                 :           2 :        self%total_time= params%spin_ntime * self%dt
     152                 :           2 :        self%temperature=params%spin_temperature
     153         [ +  - ]:           2 :        if(params%spin_dynamics>=0) then
     154                 :           2 :           self%method=params%spin_dynamics
     155                 :             :        endif
     156         [ -  + ]:           2 :        if(params%spin_init_state==3) then
     157         [ #  # ]:           0 :          self%init_qpoint = params%spin_init_qpoint
     158         [ #  # ]:           0 :          self%init_rotate_axis = params%spin_init_rotate_axis
     159         [ #  # ]:           0 :          self%init_orientation = params%spin_init_orientation
     160                 :             :        endif
     161                 :             :     end if
     162         [ -  + ]:           2 :     if(params%spin_dynamics==3) then ! Monte carlo
     163                 :           0 :        call self%spin_mc%initialize(nspin=nspin, angle=0.2_dp, temperature=params%spin_temperature)
     164                 :             :     end if
     165                 :           2 :     call xmpi_bcast(self%nspin, master, comm, ierr)
     166                 :           2 :     call xmpi_bcast(self%dt, master, comm, ierr)
     167                 :           2 :     call xmpi_bcast(self%thermal_time, master, comm, ierr)
     168                 :           2 :     call xmpi_bcast(self%total_time, master, comm, ierr)
     169                 :           2 :     call xmpi_bcast(self%temperature, master, comm, ierr)
     170                 :           2 :     call xmpi_bcast(self%method, master, comm, ierr)
     171                 :             : 
     172   [ -  +  +  -  :           6 :     ABI_MALLOC(self%ms, (self%nspin) )
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     173   [ -  +  +  -  :           6 :     ABI_MALLOC(self%gyro_ratio, (self%nspin) )
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     174   [ -  +  +  -  :           6 :     ABI_MALLOC(self%damping, (self%nspin) )
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     175   [ -  +  +  -  :           6 :     ABI_MALLOC(self%gamma_l, (self%nspin) )
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     176   [ -  +  +  -  :           6 :     ABI_MALLOC(self%H_lang_coeff, (self%nspin) )
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     177                 :             : 
     178   [ -  +  +  -  :           6 :     ABI_MALLOC(self%Heff_tmp, (3,self%nspin) )
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     179   [ -  +  +  -  :           6 :     ABI_MALLOC(self%Htmp, (3,self%nspin) )
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     180   [ -  +  +  -  :           6 :     ABI_MALLOC(self%Hrotate, (3,self%nspin) )
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     181   [ -  +  +  -  :           6 :     ABI_MALLOC(self%Stmp, (3,self%nspin) )
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     182   [ -  +  +  -  :           6 :     ABI_MALLOC(self%Stmp2, (3,self%nspin) )
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     183   [ -  +  +  -  :           6 :     ABI_MALLOC(self%buffer, (3,self%nspin) )
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     184   [ -  +  +  -  :           6 :     ABI_MALLOC(self%H_lang, (3,self%nspin) )
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     185                 :             : 
     186                 :           2 :     self%gamma_l_calculated=.False.
     187                 :           2 :     call self%mps%initialize(ntasks=nspin,master=master, comm=comm)
     188                 :             : 
     189                 :             : 
     190                 :           2 :     call xmpi_bcast(params%spin_damping, master, comm, ierr)
     191                 :             : 
     192         [ +  - ]:           2 :     if (iam_master) then
     193         [ +  - ]:           2 :        if (params%spin_damping >=0) then
     194         [ +  + ]:         434 :           self%damping(:)= params%spin_damping
     195                 :             :        else
     196         [ #  # ]:           0 :           self%damping(:)=supercell%spin%gilbert_damping(:)
     197                 :             :        end if
     198                 :             : 
     199         [ +  + ]:         434 :        self%gyro_ratio(:)=supercell%spin%gyro_ratio(:)
     200         [ +  + ]:         434 :        self%ms(:)=supercell%spin%ms(:)
     201                 :             :     endif
     202                 :             : 
     203                 :           2 :     call xmpi_bcast(self%damping, master, comm, ierr)
     204                 :           2 :     call xmpi_bcast(self%gyro_ratio, master, comm, ierr)
     205                 :           2 :     call xmpi_bcast(self%ms, master, comm, ierr)
     206                 :           2 :     call self%set_temperature(temperature=params%spin_temperature)
     207                 :             : 
     208                 :             :     ! Hist and set initial spin state
     209         [ +  - ]:           2 :     if(iam_master) then
     210                 :             :        call self%hist%initialize(nspin=self%nspin, &
     211                 :           2 :             &   mxhist=3, has_latt=.False.)
     212                 :             :        call self%hist%set_params(spin_nctime=params%spin_nctime, &
     213                 :           2 :             &     spin_temperature=params%spin_temperature)
     214                 :             :     endif
     215                 :             : 
     216                 :           2 :     call self%set_initial_state(mode=params%spin_init_state)
     217                 :             : 
     218                 :             :     ! observable
     219         [ +  - ]:           2 :     if(iam_master) then
     220                 :           2 :        call self%spin_ob%initialize(self%supercell, params)
     221                 :             :     endif
     222                 :             : 
     223                 :           6 :   end subroutine initialize
     224                 :             :   !!***
     225                 :             : 
     226                 :             :   !-------------------------------------------------------------------!
     227                 :             :   !set_ncfile_name :
     228                 :             :   !-------------------------------------------------------------------!
     229                 :           2 :   subroutine set_ncfile_name(self, params, fname)
     230                 :             :     class(spin_mover_t), intent(inout) :: self
     231                 :             :     type(multibinit_dtset_type) :: params
     232                 :             :     character(len=fnlen), intent(in) :: fname
     233                 :             :     integer :: master, my_rank, comm, nproc
     234                 :             :     logical :: iam_master
     235                 :           2 :     call init_mpi_info(master, iam_master, my_rank, comm, nproc)
     236         [ +  - ]:           2 :     if (iam_master) then
     237         [ +  - ]:           2 :        call self%prepare_ncfile(params, trim(fname)//'_spinhist.nc')
     238                 :           2 :        call self%spin_ncfile%write_one_step(self%hist)
     239                 :             :     endif
     240                 :           2 :   end subroutine set_ncfile_name
     241                 :             : 
     242                 :             : 
     243                 :             :   !-------------------------------------------------------------------!
     244                 :             :   ! read_hist_spin_state
     245                 :             :   !  read the last step of spin from hist file.
     246                 :             :   !  and save if to self%Stmp
     247                 :             :   !-------------------------------------------------------------------!
     248                 :           0 :   subroutine read_hist_spin_state(self, fname)
     249                 :             :     class(spin_mover_t), intent(inout) :: self
     250                 :             :     character(len=fnlen), intent(in) :: fname
     251                 :             :     integer :: ierr, ncid, varid
     252                 :             :     integer :: nspin, ntime
     253                 :             :     character(len=500) :: msg
     254                 :             :     ! open file
     255                 :             : 
     256                 :             : #if defined HAVE_NETCDF
     257                 :           0 :     ierr=nf90_open(trim(fname), NF90_NOWRITE, ncid)
     258   [ #  #  #  # ]:           0 :     NCF_CHECK_MSG(ierr, "The spin_init_mode is set to 4. But opening netcdf file "//trim(fname)//" Failed. ")
     259                 :             : 
     260                 :             :     ! sanity check. If the hist file is consistent with the current calculation
     261                 :           0 :     ierr=nctk_get_dim(ncid, "nspin" , nspin)
     262         [ #  # ]:           0 :     NCF_CHECK_MSG(ierr, "when reading nspin")
     263                 :             : 
     264                 :             :     msg="The number of spins in histfile is not equal & & to the present calculation." // &
     265                 :           0 :          & " Please check if the file is consistent."
     266         [ #  # ]:           0 :     if (nspin /= self%nspin) then
     267                 :           0 :        ABI_ERROR(msg)
     268                 :             :     end if
     269                 :             : 
     270                 :             : 
     271                 :           0 :     ierr=nctk_get_dim(ncid, "ntime", ntime)
     272         [ #  # ]:           0 :     NCF_CHECK_MSG(ierr, "when reading ntime")
     273                 :             : 
     274                 :             : 
     275                 :             :     ! TODO: more check ???
     276                 :             : 
     277                 :             :     ! read Spin and set as initial state
     278                 :           0 :     ierr =nf90_inq_varid(ncid, "S", varid)
     279                 :             :     msg="when reading S. Try using spin_init_state=3 option instead (specify spin_init_qpoint," // &
     280                 :           0 :       & " spin_init_rotate_axis and spin_init_orientation as needed)."
     281         [ #  # ]:           0 :     NCF_CHECK_MSG(ierr, msg)
     282                 :             : 
     283   [ #  #  #  # ]:           0 :     ierr = nf90_get_var(ncid=ncid, varid=varid, values=self%Stmp(:,:), start=(/1, 1, ntime/), count=(/3, nspin,1/))
     284         [ #  # ]:           0 :     NCF_CHECK_MSG(ierr, "when reading S from spin hist file")
     285                 :             : 
     286                 :             :     ! close file
     287                 :           0 :     ierr=nf90_close(ncid)
     288         [ #  # ]:           0 :     NCF_CHECK_MSG(ierr, "Close netcdf file")
     289                 :             : #else
     290                 :             :     ABI_ERROR("spin_init_state set to 4 but abinit is not compiled with netcdf.")
     291                 :             : #endif
     292                 :             : 
     293                 :           0 :   end subroutine read_hist_spin_state
     294                 :             : 
     295                 :             :   !----------------------------------------------------------------------------!
     296                 :             :   !set_initial_state:
     297                 :             :   ! mode: which configuration to use
     298                 :             :   !   1. Random
     299                 :             :   !   2. reference state from potential file
     300                 :             :   !   3. spin configuration using qpoint and rotation axis (e.g. for FM or AFM)
     301                 :             :   !   4. Restart from last entry of hist netcdf file
     302                 :             :   !----------------------------------------------------------------------------!
     303                 :           2 :   subroutine set_initial_state(self, mode)
     304                 :             :     class(spin_mover_t),            intent(inout) :: self
     305                 :             :     integer,              optional, intent(in)    :: mode
     306                 :             : 
     307                 :             :     integer :: i, init_mode
     308                 :             :     character(len=500) :: msg
     309                 :             : 
     310                 :             :     integer :: master, my_rank, comm, nproc, ierr
     311                 :             :     logical :: iam_master
     312                 :           2 :     real(dp), allocatable :: Sprim(:,:)
     313                 :             : 
     314                 :           2 :     call init_mpi_info(master, iam_master, my_rank, comm, nproc)
     315                 :             : 
     316         [ +  - ]:           2 :     if(iam_master) then
     317         [ +  - ]:           2 :        if (present(mode)) then
     318                 :           2 :           init_mode=mode
     319                 :             :        else
     320                 :             :           init_mode=1
     321                 :             :        end if
     322                 :             : 
     323                 :           2 :        select case (init_mode)
     324                 :             :          case (1)
     325                 :             :            ! randomize S using uniform random number
     326                 :           2 :            write(msg,*) "Initial spins set to random values."
     327                 :           2 :            call wrtout(ab_out,msg,'COLL')
     328                 :           2 :            call wrtout(std_out,msg,'COLL')
     329                 :             :            !call random_number(self%Stmp)
     330                 :           2 :            call self%rng%rand_unif_01_array(self%Stmp, self%nspin*3 )
     331   [ +  +  +  + ]:        1730 :            self%Stmp=self%Stmp-0.5
     332         [ +  + ]:         434 :            do i=1, self%nspin
     333   [ +  +  +  + ]:        3026 :              self%Stmp(:,i)=self%Stmp(:,i)/sqrt(sum(self%Stmp(:, i)**2))
     334                 :             :            end do
     335                 :             : 
     336                 :             :          case (2)
     337                 :             :            ! set spin to reference state using the reference qpoint and rotation axis from potential file
     338                 :           0 :            write(msg,*) "Initial spins set to reference configuration."
     339                 :           0 :            call wrtout(ab_out,msg,'COLL')
     340                 :           0 :            call wrtout(std_out,msg,'COLL')
     341                 :             : 
     342         [ #  # ]:           0 :            do i=1, self%nspin
     343   [ #  #  #  # ]:           0 :              self%Stmp(:,:) = self%supercell%spin%Sref(:,:)
     344                 :             :            end do
     345                 :             : 
     346                 :             :          case (3)
     347                 :           0 :            write(msg,*) "Initial spins set according to spin_init_* variables."
     348                 :           0 :            call wrtout(ab_out,msg,'COLL')
     349                 :           0 :            call wrtout(std_out,msg,'COLL')
     350                 :             : 
     351   [ #  #  #  #  :           0 :            ABI_MALLOC(Sprim, (3,self%supercell%unitcell%spin%nspin) )
          #  #  #  #  #  
                #  #  # ]
     352                 :             : 
     353                 :             :            ! set inital spin state using the input variables
     354                 :             :            ! set spin to ferromagnetic along init_orientation then rotate
     355         [ #  # ]:           0 :            do i=1, self%supercell%unitcell%spin%nspin
     356         [ #  # ]:           0 :              Sprim(:,i)=self%init_orientation(:)
     357                 :             :            enddo
     358   [ #  #  #  # ]:           0 :            self%Stmp(:,:) = 0.0d0
     359                 :             : 
     360                 :             :            call self%supercell%supercell_maker%generate_spin_wave_vectorlist(A=Sprim, &
     361                 :           0 :              & kpoint=self%init_qpoint, axis=self%init_rotate_axis, A_sc=self%Stmp)
     362                 :             : 
     363         [ #  # ]:           0 :            ABI_SFREE(SPrim)
     364                 :             : 
     365                 :             :          case (4)
     366                 :             :           ! read from last step of hist file
     367                 :           0 :           write(msg,'(a,a,a)') "Initial spins set to input spin hist file ",&
     368                 :           0 :              &  trim(self%params%spin_init_hist_fname), '.'
     369                 :           0 :           call wrtout(ab_out,msg,'COLL')
     370                 :           0 :           call wrtout(std_out,msg,'COLL')
     371   [ +  -  -  -  :           2 :            call self%read_hist_spin_state(fname=self%params%spin_init_hist_fname)
                      - ]
     372                 :             : 
     373                 :             :        end select
     374                 :             : 
     375                 :             :        call self%hist%set_vars(S=self%Stmp, Snorm=self%supercell%spin%ms, &
     376                 :           2 :             &  time=0.0_dp, ihist_latt=0, inc=.True.)
     377                 :             : 
     378                 :             :     endif
     379                 :           2 :     call xmpi_bcast(self%Stmp, 0, comm, ierr)
     380         [ -  + ]:           2 :   end subroutine set_initial_state
     381                 :             : 
     382                 :             : 
     383                 :             :   !-------------------------------------------------------------------!
     384                 :             :   ! prepare_ncfile:
     385                 :             :   !-------------------------------------------------------------------!
     386                 :           2 :   subroutine prepare_ncfile(self, params, fname)
     387                 :             :     class(spin_mover_t), intent(inout) :: self
     388                 :             :     type(multibinit_dtset_type) :: params
     389                 :             :     character(len=*), intent(in) :: fname
     390                 :             : 
     391                 :             :     integer :: master, my_rank, comm, nproc
     392                 :             :     logical :: iam_master
     393                 :           2 :     call init_mpi_info(master, iam_master, my_rank, comm, nproc)
     394                 :             : 
     395         [ +  - ]:           2 :     if(iam_master) then
     396         [ +  - ]:           2 :        call self%spin_ncfile%initialize( trim(fname), params%spin_write_traj)
     397                 :           2 :        call self%spin_ncfile%def_spindynamics_var(self%hist)
     398                 :           2 :        call self%spin_ncfile%def_observable_var(self%spin_ob)
     399                 :           2 :        call self%spin_ncfile%write_primitive_cell(self%supercell%unitcell)
     400                 :           2 :        call self%spin_ncfile%write_supercell(self%supercell)
     401                 :           2 :        call self%spin_ncfile%write_parameters(params)
     402                 :             :     endif
     403                 :           2 :   end subroutine prepare_ncfile
     404                 :             : 
     405                 :             : 
     406                 :             : 
     407                 :           4 :   subroutine set_temperature(self, temperature)
     408                 :             :     class(spin_mover_t), intent(inout) :: self
     409                 :             :     real(dp), optional, intent(in) ::  temperature
     410                 :             : 
     411                 :             :     integer :: master, my_rank, comm, nproc, ierr
     412                 :             :     logical :: iam_master
     413                 :           2 :     call init_mpi_info(master, iam_master, my_rank, comm, nproc)
     414                 :             : 
     415         [ +  - ]:           2 :     if(present(temperature)) self%temperature=temperature
     416                 :           2 :     call xmpi_bcast(self%temperature, master, comm, ierr)
     417         [ -  + ]:           2 :     if(self%method==3) then
     418         [ #  # ]:           0 :        if(iam_master) self%spin_mc%temperature = temperature
     419         [ #  # ]:           0 :        if(iam_master) self%spin_mc%beta=1.0_dp/temperature
     420                 :           0 :        call xmpi_bcast(self%spin_mc%temperature, master, comm, ierr)
     421                 :           0 :        call xmpi_bcast(self%spin_mc%beta, master, comm, ierr)
     422                 :             :     end if
     423         [ +  + ]:         434 :     self%gamma_l(:)= self%gyro_ratio(:)/(1.0_dp+ self%damping(:)**2)
     424                 :           2 :     self%gamma_l_calculated=.True.
     425                 :             :     self%H_lang_coeff(:)=sqrt(2.0*self%damping(:)* self%temperature &
     426         [ +  + ]:         434 :          &  /(self%gyro_ratio(:)* self%dt *self%ms(:)))
     427                 :           2 :   end subroutine set_temperature
     428                 :             : 
     429                 :             : 
     430                 :        2002 :   subroutine get_Langevin_Heff(self, H_lang)
     431                 :             :     class(spin_mover_t), intent(inout) :: self
     432                 :             :     real(dp), intent(inout):: H_lang(3,self%nspin)
     433                 :             :     integer :: i
     434         [ -  + ]:        2002 :     if ( self%temperature .gt. 1d-7) then
     435                 :        2002 :        call rand_normal_array(self%rng, H_lang(:, self%mps%istart:self%mps%iend), 3*self%mps%ntask)
     436         [ +  + ]:      434434 :        do i = self%mps%istart, self%mps%iend
     437         [ +  + ]:     1731730 :           H_lang(:,i)= H_lang(:,i) * self%H_lang_coeff(i)
     438                 :             :        end do
     439                 :             :     else
     440   [ #  #  #  # ]:           0 :        H_lang(:,:)=0.0_dp
     441                 :             :     end if
     442                 :        2002 :   end subroutine get_Langevin_Heff
     443                 :             : 
     444                 :             : 
     445                 :             :   !!****f* m_spin_mover/spin_mover_t_run_one_step_HeunP
     446                 :             :   !!
     447                 :             :   !! NAME
     448                 :             :   !!  spin_mover_t_run_one_step_HeunP
     449                 :             :   !!
     450                 :             :   !! FUNCTION
     451                 :             :   !! run one spin step using HeunP method
     452                 :             :   !!
     453                 :             :   !! INPUTS
     454                 :             :   !! effpot: abstract_potential_t type.
     455                 :             :   !! S_in : input spin. (3*nspin)
     456                 :             :   !!
     457                 :             :   !! OUTPUT
     458                 :             :   !! etot: energy (scalar)
     459                 :             :   !!
     460                 :             :   !! SOURCE
     461                 :           0 :   subroutine spin_mover_t_run_one_step_HeunP(self, effpot, S_in, &
     462   [ #  #  #  #  :           0 :        & etot, displacement, strain, lwf, energy_table)
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     463                 :             :     !class (spin_mover_t), intent(inout):: self
     464                 :             :     class(spin_mover_t), intent(inout):: self
     465                 :             :     class(abstract_potential_t), intent(inout) :: effpot
     466                 :             : 
     467                 :             :     real(dp), optional, intent(inout):: displacement(:,:), &
     468                 :             :          strain(:,:), lwf(:)
     469                 :             :     real(dp), intent(inout) :: S_in(3,self%nspin)
     470                 :             :     real(dp), intent(out) ::  etot
     471                 :             :     integer :: i
     472                 :             :     real(dp) :: dSdt(3), Htmp(3), Ri(3)
     473                 :             :     type(hash_table_t),optional, intent(inout) :: energy_table
     474                 :             : 
     475                 :             :     !integer :: master, my_rank, comm, nproc, ierr
     476                 :             :     !logical :: iam_master
     477                 :             :     !call init_mpi_info(master, iam_master, my_rank, comm, nproc)
     478                 :             : 
     479                 :             :     ! predict
     480                 :           0 :     etot=0.0
     481   [ #  #  #  # ]:           0 :     self%Heff_tmp(:,:)=0.0
     482                 :             :     call effpot%calculate(displacement=displacement, strain=strain, lwf=lwf, spin=S_in, &
     483   [ #  #  #  #  :           0 :          & bfield=self%Heff_tmp, energy=etot, energy_table=energy_table)
                   #  # ]
     484                 :           0 :     call self%get_Langevin_Heff(self%H_lang)
     485         [ #  # ]:           0 :     do i=self%mps%istart, self%mps%iend
     486         [ #  # ]:           0 :        Htmp=self%Heff_tmp(:,i)+self%H_lang(:,i)
     487                 :           0 :        Ri = cross(S_in(:,i),Htmp)
     488         [ #  # ]:           0 :        dSdt = -self%gamma_L(i)*(Ri+self%damping(i)* cross(S_in(:,i), Ri))
     489         [ #  # ]:           0 :        Ri=S_in(:,i)+dSdt*self%dt
     490   [ #  #  #  #  :           0 :        Ri=Ri/norm2(Ri)
             #  #  #  # ]
     491         [ #  # ]:           0 :        self%Stmp2(:,i)=Ri
     492                 :             :     end do
     493                 :           0 :     call self%mps%allgatherv_dp2d(self%Stmp2, 3, buffer=self%buffer)
     494                 :             : 
     495                 :             :     ! correction
     496   [ #  #  #  # ]:           0 :     self%Htmp(:,:)=0.0
     497                 :           0 :     etot=0.0
     498                 :             :     call effpot%calculate(displacement=displacement, strain=strain, lwf=lwf,spin=self%Stmp2, &
     499   [ #  #  #  #  :           0 :          & bfield=self%Htmp, energy=etot, energy_table=energy_table)
                   #  # ]
     500         [ #  # ]:           0 :     do i=self%mps%istart, self%mps%iend
     501         [ #  # ]:           0 :        Htmp=(self%Heff_tmp(:,i)+self%Htmp(:,i))*0.5_dp+self%H_lang(:,i)
     502                 :           0 :        Ri = cross(S_in(:,i),Htmp)
     503         [ #  # ]:           0 :        dSdt = -self%gamma_L(i)*(Ri+self%damping(i)* cross(S_in(:,i), Ri))
     504         [ #  # ]:           0 :        Ri=S_in(:,i)+dSdt*self%dt
     505   [ #  #  #  #  :           0 :        Ri=Ri/norm2(Ri)
             #  #  #  # ]
     506         [ #  # ]:           0 :        self%Stmp(:,i)=Ri
     507                 :             :     end do
     508                 :           0 :     call self%mps%allgatherv_dp2d(self%Stmp, 3, buffer=self%buffer)
     509                 :           0 :   end subroutine spin_mover_t_run_one_step_HeunP
     510                 :             :   !!***
     511                 :             : 
     512                 :             : 
     513                 :             : 
     514                 :             :   !!****f* m_spin_mover/spin_mover_t_run_one_step_dummy
     515                 :             :   !!
     516                 :             :   !! NAME
     517                 :             :   !!  spin_mover_t_run_one_step_dummy
     518                 :             :   !!
     519                 :             :   !! FUNCTION
     520                 :             :   !! run one spin step using dummy method
     521                 :             :   !!
     522                 :             :   !! INPUTS
     523                 :             :   !! effpot: abstract_potential_t type.
     524                 :             :   !! S_in : input spin. (3*nspin)
     525                 :             :   !!
     526                 :             :   !! OUTPUT
     527                 :             :   !! etot: energy (scalar)
     528                 :             :   !!
     529                 :             :   !! SOURCE
     530                 :           0 :   subroutine spin_mover_t_run_one_step_dummy(self, effpot, S_in, etot, &
     531   [ #  #  #  #  :           0 :        & displacement, strain, lwf, energy_table)
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     532                 :             :     !class (spin_mover_t), intent(inout):: self
     533                 :             :     class(spin_mover_t), intent(inout):: self
     534                 :             :     class(abstract_potential_t), intent(inout) :: effpot
     535                 :             : 
     536                 :             :     real(dp), optional, intent(inout):: displacement(:,:), &
     537                 :             :          strain(:,:), lwf(:)
     538                 :             :     real(dp), intent(inout) :: S_in(3,self%nspin)
     539                 :             :     real(dp), intent(out) ::  etot
     540                 :             :     type(hash_table_t),optional, intent(inout) :: energy_table
     541                 :             :     integer :: i
     542                 :             :     real(dp) ::  Htmp(3), Ri(3)
     543                 :             : 
     544                 :             :     ! predict
     545                 :           0 :     etot=0.0
     546   [ #  #  #  # ]:           0 :     self%Heff_tmp(:,:)=0.0
     547                 :             :     call effpot%calculate(displacement=displacement, strain=strain, lwf=lwf, spin=S_in, &
     548   [ #  #  #  #  :           0 :          & bfield=self%Heff_tmp, energy=etot, energy_table=energy_table)
                   #  # ]
     549                 :           0 :     call self%get_Langevin_Heff(self%H_lang)
     550         [ #  # ]:           0 :     do i=self%mps%istart, self%mps%iend
     551                 :           0 :        Htmp=self%Heff_tmp(:,i)+self%H_lang(:,i)
     552                 :             :        !Ri = cross(S_in(:,i),Htmp)
     553                 :             :        !dSdt = -self%gamma_L(i)*(Ri+self%damping(i)* cross(S_in(:,i), Ri))
     554         [ #  # ]:           0 :        Ri=S_in(:,i)!+dSdt*self%dt
     555   [ #  #  #  #  :           0 :        Ri=Ri/norm2(Ri)
             #  #  #  # ]
     556         [ #  # ]:           0 :        self%Stmp(:,i)=Ri
     557                 :             :     end do
     558                 :           0 :     call self%mps%allgatherv_dp2d(self%Stmp2, 3, buffer=self%buffer)
     559                 :             : 
     560                 :           0 :   end subroutine spin_mover_t_run_one_step_dummy
     561                 :             :   !!***
     562                 :             : 
     563                 :             : 
     564                 :             : 
     565                 :             :   !----------------------------------------------------------------------
     566                 :             :   !> @brief rotate spin with a rotation matrix
     567                 :             :   !>
     568                 :             :   !> @param[in]  S_in: input spin array(3)
     569                 :             :   !> @param[in]  Heff: effective field
     570                 :             :   !> @param[in]  dt: time step
     571                 :             :   !> @param[out]  S_out: output spin
     572                 :             :   !----------------------------------------------------------------------
     573                 :             : 
     574         [ -  + ]:      864864 :   pure function rotate_S_DM(S_in, Heff, dt) result(S_out)
     575                 :             :     ! Depondt & Mertens method to rotate S_in
     576                 :             :     real(dp), intent(in) :: S_in(3), Heff(3), dt
     577                 :             :     real(dp) :: S_out(3)
     578                 :             :     real(dp) :: B(3) , w, u, Bnorm, R(3,3), cosw, sinw
     579         [ +  + ]:     3459456 :     Bnorm=sqrt(sum(Heff*Heff))
     580         [ +  + ]:     3459456 :     B(:)=Heff(:)/Bnorm   ! axis of rotation
     581                 :      864864 :     w=Bnorm*dt             ! amplitude of rotation
     582                 :      864864 :     sinw=sin(w)
     583                 :      864864 :     cosw=cos(w)
     584                 :      864864 :     u=1.0d0-cosw
     585                 :             : 
     586                 :             :     ! R is rotation matrix
     587                 :      864864 :     R(1,1)=B(1)*B(1)*u+cosw
     588                 :      864864 :     R(2,1)=B(1)*B(2)*u+B(3)*sinw
     589                 :      864864 :     R(3,1)=B(1)*B(3)*u-B(2)*sinw
     590                 :             : 
     591                 :      864864 :     R(1,2)=B(1)*B(2)*u-B(3)*sinw
     592                 :      864864 :     R(2,2)=B(2)*B(2)*u+cosw
     593                 :      864864 :     R(3,2)=B(2)*B(3)*u+B(1)*sinw
     594                 :             : 
     595                 :      864864 :     R(1,3)=B(1)*B(3)*u+B(2)*sinw
     596                 :      864864 :     R(2,3)=B(2)*B(3)*u-B(1)*sinw
     597                 :      864864 :     R(3,3)=B(3)*B(3)*u+cosw
     598                 :             :     ! rotate
     599   [ +  +  +  +  :    13837824 :     S_out=matmul(R, S_in)
                   +  + ]
     600                 :      864864 :   end function rotate_S_DM
     601                 :             : 
     602   [ +  -  +  -  :        2002 :   subroutine spin_mover_t_run_one_step_DM(self, effpot, S_in, etot, displacement, strain,&
          -  +  -  +  -  
                -  -  - ]
     603   [ -  +  -  -  :        2002 :        & lwf, energy_table)
                   -  - ]
     604                 :             :     ! Depondt & Mertens (2009) method, using a rotation matrix so length doesn't change.
     605                 :             :     !class (spin_mover_t), intent(inout):: self
     606                 :             :     class(spin_mover_t), intent(inout):: self
     607                 :             :     class(abstract_potential_t), intent(inout) :: effpot
     608                 :             :     real(dp), optional, intent(inout) :: displacement(:,:), strain(:,:), lwf(:)
     609                 :             :     real(dp), intent(inout) :: S_in(3,self%nspin)
     610                 :             :     real(dp), intent(out) ::  etot
     611                 :             :     type(hash_table_t),optional, intent(inout) :: energy_table
     612                 :             :     real(dp) :: Htmp(3)
     613                 :             :     integer :: i
     614                 :             : 
     615                 :             :     ! predict
     616   [ +  +  +  + ]:     1731730 :     self%Stmp2(:,:)=0.0_dp
     617                 :        2002 :     etot=0.0
     618   [ +  +  +  + ]:     1731730 :     self%Heff_tmp(:,:)=0.0_dp
     619                 :             :     call effpot%calculate(displacement=displacement, strain=strain, lwf=lwf,spin=S_in, &
     620   [ -  +  +  -  :        6006 :          bfield=self%Heff_tmp, energy=etot, energy_table=energy_table)
                   +  - ]
     621                 :        2002 :     call self%get_Langevin_Heff(self%H_lang)
     622         [ +  + ]:      434434 :     do i=self%mps%istart, self%mps%iend
     623         [ +  + ]:     1729728 :        Htmp=self%Heff_tmp(:,i)+self%H_lang(:,i)
     624                 :             :        ! Note that there is no - , because dsdt =-cross (S, Hrotate)
     625   [ +  +  +  + ]:     3027024 :        self%Hrotate(:,i) = self%gamma_L(i) * (Htmp + self%damping(i)* cross(S_in(:,i), Htmp))
     626         [ +  + ]:     1731730 :        self%Stmp2(:,i)= rotate_S_DM(S_in(:,i), self%Hrotate(:,i), self%dt)
     627                 :             :     end do
     628                 :        2002 :     call self%mps%allgatherv_dp2d(self%Stmp2, 3, self%buffer)
     629                 :             : 
     630                 :             :     ! correction
     631   [ +  +  +  + ]:     1731730 :     self%Htmp(:,:)=0.0_dp
     632                 :        2002 :     etot=0.0
     633                 :             :     call effpot%calculate(displacement=displacement, strain=strain, lwf=lwf, spin=self%Stmp2, &
     634   [ -  +  +  -  :        6006 :          bfield=self%Htmp, energy=etot, energy_table=energy_table)
                   +  - ]
     635                 :             : 
     636         [ +  + ]:      434434 :     do i=self%mps%istart, self%mps%iend
     637         [ +  + ]:     1729728 :        Htmp=(self%Heff_tmp(:,i)+self%Htmp(:,i))*0.5_dp + self%H_lang(:,i)
     638   [ +  +  +  + ]:     3027024 :        self%Hrotate(:,i) = self%gamma_L(i) * (Htmp + self%damping(i)* cross(S_in(:,i), Htmp))
     639         [ +  + ]:     1731730 :        self%Stmp(:, i)= rotate_S_DM(S_in(:,i), self%Hrotate(:,i), self%dt)
     640                 :             :     end do
     641                 :        2002 :     call self%mps%allgatherv_dp2d(self%Stmp, 3, self%buffer)
     642                 :        2002 :   end subroutine spin_mover_t_run_one_step_DM
     643                 :             : 
     644   [ #  #  #  #  :           0 :   subroutine spin_mover_t_run_one_step_MC(self, effpot, S_in,  etot, displacement, strain,  lwf, energy_table)
                   #  # ]
     645                 :             :     class(spin_mover_t), intent(inout) :: self
     646                 :             :     class(abstract_potential_t), intent(inout) :: effpot
     647                 :             :     real(dp), optional, intent(inout) :: displacement(:, :), strain(:,:), lwf(:)
     648                 :             :     real(dp), intent(inout) :: S_in(3,self%nspin)
     649                 :             :     real(dp), intent(out) ::  etot
     650                 :             :     type(hash_table_t),optional, intent(inout) :: energy_table
     651   [ #  #  #  # ]:           0 :     if(present(displacement) .or. present(lwf) .or. present(strain)) then
     652                 :           0 :        ABI_BUG("Monte Carlo only implemented for spin.")
     653                 :             :     else
     654                 :           0 :        call self%spin_mc%run_MC(self%rng, effpot, S_in, etot, bfield=self%Htmp)
     655                 :             :     end if
     656                 :           0 :     call energy_table%put(self%label, etot)
     657                 :           0 :   end subroutine spin_mover_t_run_one_step_MC
     658                 :             : 
     659   [ -  +  +  -  :        2002 :   subroutine spin_mover_t_run_one_step(self, effpot, displacement, strain, spin, lwf, energy_table)
          +  -  -  +  -  
          +  -  -  -  -  
          -  +  -  -  -  
                      - ]
     660                 :             :     class(spin_mover_t), intent(inout) :: self
     661                 :             :     class(abstract_potential_t), intent(inout) :: effpot
     662                 :             :     real(dp), optional, intent(inout) :: displacement(:,:), strain(:,:), spin(:,:), lwf(:)
     663                 :             :     real(dp) ::  etot
     664                 :             :     type(hash_table_t),optional, intent(inout) :: energy_table
     665                 :             : 
     666         [ -  + ]:        2002 :     if(present(spin)) ABI_ERROR("spin should not be input for spin mover.")
     667         [ -  + ]:        2002 :     if(self%method==1) then
     668                 :             :        call self%run_one_step_HeunP(effpot=effpot, S_in=self%Stmp, etot=etot, &
     669   [ #  #  #  #  :           0 :             displacement=displacement, strain=strain, lwf=lwf, energy_table=energy_table)
                   #  # ]
     670         [ +  - ]:        2002 :     else if (self%method==2) then
     671                 :             :        call self%run_one_step_DM(effpot=effpot, S_in=self%Stmp, etot=etot,&
     672   [ -  +  +  -  :        6006 :             displacement=displacement, strain=strain, lwf=lwf, energy_table=energy_table)
                   +  - ]
     673         [ #  # ]:           0 :     else if (self%method==3) then
     674   [ #  #  #  # ]:           0 :        if(present(displacement) .or. present(strain) .or. present(lwf)) then
     675                 :           0 :           ABI_ERROR("Monte carlo not implemented for lattice and lwf yet.")
     676                 :             :        endif
     677                 :           0 :        call self%run_one_step_MC(effpot, self%Stmp, etot, energy_table=energy_table)
     678         [ #  # ]:           0 :     else if (self%method==20) then
     679                 :             :        call self%run_one_step_dummy(effpot=effpot, S_in=self%Stmp, etot=etot, &
     680   [ #  #  #  #  :           0 :             displacement=displacement, strain=strain, lwf=lwf, energy_table=energy_table)
                   #  # ]
     681                 :             :     end if
     682                 :             : 
     683                 :             :     ! do not inc until time is set to hist.
     684                 :             :     ! run one step does not know about time. So it will be done in the outer loop.
     685         [ +  - ]:        2002 :     if(self%mps%irank==0) then
     686                 :        2002 :        call self%hist%set_vars(S=self%Stmp, Snorm=effpot%supercell%spin%ms, etot=etot, inc=.False.)
     687                 :             :     end if
     688                 :        2002 :   end subroutine spin_mover_t_run_one_step
     689                 :             : 
     690                 :             :   !!****f* m_spin_mover/spin_mover_t_run_time
     691                 :             :   !!
     692                 :             :   !! NAME
     693                 :             :   !!  spin_mover_t_run_time
     694                 :             :   !!
     695                 :             :   !! FUNCTION
     696                 :             :   !! run all spin step
     697                 :             :   !!
     698                 :             :   !! INPUTS
     699                 :             :   !!
     700                 :             :   !! OUTPUT
     701                 :             :   !!
     702                 :             :   !! NOTES
     703                 :             :   !!
     704                 :             :   !!
     705                 :             :   !! SOURCE
     706   [ #  #  #  #  :           0 :   subroutine spin_mover_t_run_time(self, calculator, displacement, strain, spin, lwf, energy_table)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     707                 :             : 
     708                 :             :     class(spin_mover_t), intent(inout):: self
     709                 :             :     class(abstract_potential_t), intent(inout) :: calculator
     710                 :             : 
     711                 :             :     real(dp), optional, intent(inout) :: displacement(:,:), strain(:,:), lwf(:), spin(:,:)
     712                 :             : 
     713                 :             :     type(hash_table_t),optional, intent(inout) :: energy_table
     714                 :             :     !type(spin_hist_t), intent(inout) :: hist
     715                 :             :     !type(spin_ncfile_t), intent(inout) :: ncfile
     716                 :             :     !type(spin_observable_t), intent(inout) :: ob
     717                 :             :     !real(dp) ::  S(3, self%nspin)
     718                 :             :     real(dp):: t, etotal
     719                 :             :     integer :: counter, i, ii
     720                 :             :     character(len=80) :: msg, msg_empty
     721                 :             : 
     722                 :             :     integer :: master, my_rank, comm, nproc
     723                 :             :     logical :: iam_master
     724                 :             : 
     725                 :           0 :     call init_mpi_info(master, iam_master, my_rank, comm, nproc)
     726                 :             : 
     727                 :           0 :     t=0.0
     728                 :           0 :     counter=0
     729         [ #  # ]:           0 :     if(iam_master) then
     730                 :           0 :        msg_empty=ch10
     731                 :             : 
     732                 :           0 :        msg=repeat("=", 80)
     733                 :           0 :        call wrtout(std_out,msg,'COLL')
     734                 :           0 :        call wrtout(ab_out, msg, 'COLL')
     735                 :           0 :        write(msg, '(A20)') "Spin dynamic steps:"
     736                 :           0 :        call wrtout(std_out,msg,'COLL')
     737                 :           0 :        call wrtout(ab_out, msg, 'COLL')
     738                 :           0 :        msg=repeat("=", 80)
     739                 :           0 :        call wrtout(std_out,msg,'COLL')
     740                 :           0 :        call wrtout(ab_out, msg, 'COLL')
     741                 :             : 
     742                 :           0 :        write(msg, "(A13, 4X, A13, 6X, A13, 4X, A13)")  "Iteration", "time(s)", "Avg_Mst/Ms", "ETOT(Ha/uc)"
     743                 :           0 :        call wrtout(std_out,msg,'COLL')
     744                 :           0 :        call wrtout(ab_out, msg, 'COLL')
     745                 :             : 
     746                 :           0 :        msg=repeat("-", 80)
     747                 :           0 :        call wrtout(std_out,msg,'COLL')
     748                 :           0 :        call wrtout(ab_out, msg, 'COLL')
     749                 :             :     end if
     750                 :             : 
     751         [ #  # ]:           0 :     if (abs(self%thermal_time) > 1e-30) then
     752         [ #  # ]:           0 :        if (iam_master) then
     753                 :           0 :           msg="Thermalization run:"
     754                 :           0 :           call wrtout(std_out,msg,'COLL')
     755                 :           0 :           call wrtout(ab_out, msg, 'COLL')
     756                 :             :        end if
     757                 :             : 
     758         [ #  # ]:           0 :        do while(t<self%thermal_time)
     759                 :           0 :           counter=counter+1
     760                 :             :           call self%run_one_step(effpot=calculator, displacement=displacement, strain=strain, &
     761   [ #  #  #  #  :           0 :                & lwf=lwf, energy_table=energy_table)
                   #  # ]
     762         [ #  # ]:           0 :           if (iam_master) then
     763                 :           0 :              call self%hist%set_vars( time=t,  inc=.True.)
     764         [ #  # ]:           0 :              if(mod(counter, self%hist%spin_nctime)==0) then
     765                 :             :                 call self%spin_ob%get_observables( self%hist%S(:,:, self%hist%ihist_prev), &
     766                 :           0 :                      self%hist%Snorm(:,self%hist%ihist_prev),self%hist%etot(self%hist%ihist_prev))
     767                 :           0 :                 etotal = energy_table%sum_val()
     768                 :           0 :                 write(msg, "(A1, 1X, I13, 4X, ES13.5, 4X, ES13.5, 4X, ES13.5)") "-", counter, t*Time_Sec, &
     769                 :           0 :                      & self%spin_ob%Mst_norm_total/self%spin_ob%Snorm_total, &
     770                 :           0 :                      & etotal/self%spin_ob%nscell
     771                 :             :                 ! total : 13+4+...= 64
     772                 :           0 :                 call wrtout(std_out,msg,'COLL')
     773                 :           0 :                 call wrtout(ab_out, msg, 'COLL')
     774                 :             :              endif
     775                 :             :           end if
     776                 :           0 :           t=t+self%dt
     777                 :             :        end do
     778                 :             : 
     779                 :           0 :        t=0.0
     780                 :           0 :        counter=0
     781         [ #  # ]:           0 :        if (iam_master) then
     782                 :           0 :           call self%hist%reset(array_to_zero=.False.)
     783                 :             :        end if
     784                 :             :     endif
     785         [ #  # ]:           0 :     if(iam_master) then
     786                 :           0 :        call self%spin_ob%reset()
     787                 :             :     endif
     788                 :             : 
     789         [ #  # ]:           0 :     if (iam_master) then
     790                 :           0 :        msg="Measurement run:"
     791                 :           0 :        call wrtout(std_out,msg,'COLL')
     792                 :           0 :        call wrtout(ab_out, msg, 'COLL')
     793                 :             :     end if
     794                 :             : 
     795         [ #  # ]:           0 :     do while(t<self%total_time)
     796                 :           0 :        counter=counter+1
     797                 :             :        call self%run_one_step(effpot=calculator, displacement=displacement, strain=strain, &
     798   [ #  #  #  #  :           0 :             & spin=spin, lwf=lwf, energy_table=energy_table)
             #  #  #  # ]
     799         [ #  # ]:           0 :        if (iam_master) then
     800                 :           0 :           call self%hist%set_vars(time=t,  inc=.True.)
     801                 :             :           call self%spin_ob%get_observables(self%hist%S(:,:, self%hist%ihist_prev), &
     802                 :           0 :                self%hist%Snorm(:,self%hist%ihist_prev), self%hist%etot(self%hist%ihist_prev))
     803         [ #  # ]:           0 :           if(modulo(counter, self%hist%spin_nctime)==0) then
     804                 :           0 :              call self%spin_ncfile%write_one_step(self%hist)
     805                 :           0 :              etotal = energy_table%sum_val()
     806                 :           0 :              write(msg, "(A1, 1X, I13, 4X, ES13.5, 4X, ES13.5, 4X, ES13.5)") "-", counter, t*Time_Sec, &
     807                 :           0 :                   & self%spin_ob%Mst_norm_total/self%spin_ob%Snorm_total, &
     808                 :           0 :                   & etotal/self%spin_ob%nscell
     809                 :           0 :              call wrtout(std_out,msg,'COLL')
     810                 :           0 :              call wrtout(ab_out, msg, 'COLL')
     811                 :             :           endif
     812                 :             :        end if
     813                 :           0 :        t=t+self%dt
     814                 :             :     enddo
     815                 :             : 
     816         [ #  # ]:           0 :     if (iam_master) then
     817                 :           0 :        msg=repeat("-", 80)
     818                 :           0 :        call wrtout(std_out,msg,'COLL')
     819                 :           0 :        call wrtout(ab_out, msg, 'COLL')
     820                 :             : 
     821                 :           0 :        write(msg, "(A27)") "Summary of spin dynamics:"
     822                 :           0 :        call wrtout(std_out,msg,'COLL')
     823                 :           0 :        call wrtout(ab_out, msg, 'COLL')
     824                 :             : 
     825                 :           0 :        write(msg, "(A65)") "At the end of the run, the average spin at each sublattice is"
     826                 :           0 :        call wrtout(std_out,msg,'COLL')
     827                 :           0 :        call wrtout(ab_out, msg, 'COLL')
     828                 :             : 
     829                 :           0 :        write(msg, "(6X, A10, 5X, 3A10, A11)")  'Sublattice', '<M_i>(x)', '<M_i>(y)', '<M_i>(z)', '||<M_i>||'
     830                 :           0 :        call wrtout(std_out,msg,'COLL')
     831                 :           0 :        call wrtout(ab_out, msg, 'COLL')
     832                 :             : 
     833         [ #  # ]:           0 :        do i =1, self%spin_ob%nsublatt
     834                 :           0 :           write(msg, "(A1, 5X, 2X, I5.4, 8X, 4F10.5)") '-', i, &
     835         [ #  # ]:           0 :                (self%spin_ob%Mst_sub(ii,i)/self%spin_ob%nspin_sub(i)/mu_B , ii=1, 3), &
     836   [ #  #  #  # ]:           0 :                sqrt(sum((self%spin_ob%Mst_sub(:, i)/self%spin_ob%nspin_sub(i)/mu_B)**2))
     837                 :           0 :           call wrtout(std_out,msg,'COLL')
     838                 :           0 :           call wrtout(ab_out, msg, 'COLL')
     839                 :             :        end do
     840                 :             : 
     841                 :           0 :        call wrtout(std_out,msg_empty,'COLL')
     842                 :           0 :        call wrtout(ab_out, msg_empty, 'COLL')
     843                 :             : 
     844                 :             :        write(msg, "(A1, 1X, A11, 3X, A13, 3X, A13, 3X, A13, 3X, A13 )" ) &
     845                 :           0 :             "#", "Temperature", "Cv", "chi",  "BinderU4", "Mst"
     846                 :           0 :        call wrtout(std_out, msg, "COLL")
     847                 :           0 :        call wrtout(ab_out, msg, "COLL")
     848                 :             :        write(msg, "(2X, F11.5, 3X, ES13.5, 3X, ES13.5, 3X, E13.5, 3X, ES13.5, 3X )" ) &
     849                 :           0 :             self%temperature*Ha_K , self%spin_ob%Cv, self%spin_ob%chi, &
     850                 :           0 :             self%spin_ob%binderU4, self%spin_ob%Avg_Mst_norm_total/self%spin_ob%snorm_total
     851                 :           0 :        call wrtout(std_out, msg, "COLL")
     852                 :           0 :        call wrtout(ab_out,  msg, "COLL")
     853                 :             : 
     854                 :           0 :        msg=repeat("=", 80)
     855                 :           0 :        call wrtout(std_out,msg,'COLL')
     856                 :           0 :        call wrtout(ab_out, msg, 'COLL')
     857                 :             :     end if
     858                 :           0 :   end subroutine spin_mover_t_run_time
     859                 :             :   !!***
     860                 :             : 
     861                 :             : 
     862                 :             : 
     863                 :             : 
     864                 :             :   !!****f* m_spin_mover/run_MvT
     865                 :             :   !!
     866                 :             :   !! NAME
     867                 :             :   !! run_MvT
     868                 :             :   !!
     869                 :             :   !! FUNCTION
     870                 :             :   !! run M vs Temperature
     871                 :             :   !!
     872                 :             :   !! INPUTS
     873                 :             :   !! pot: potential
     874                 :             :   !! T_start, Tend, T_nstep
     875                 :             :   !u
     876                 :             :   !! OUTPUT
     877                 :             :   !!
     878                 :             :   !! SOURCE
     879   [ #  #  #  #  :           0 :   subroutine  run_MvT(self, pot, ncfile_prefix, displacement, strain, spin, lwf, energy_table)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     880                 :             :     class(spin_mover_t), intent(inout) :: self
     881                 :             :     class(abstract_potential_t), intent(inout) :: pot
     882                 :             :     real(dp), optional, intent(inout) :: displacement(:,:), strain(:,:), lwf(:), spin(:,:)
     883                 :             :     character(fnlen), intent(inout) :: ncfile_prefix
     884                 :             :     type(hash_table_t), optional, intent(inout) :: energy_table
     885                 :             :     real(dp) :: T_start, T_end
     886                 :             :     integer :: T_nstep
     887                 :             :     !type(spin_ncfile_t) :: spin_ncfile
     888                 :             :     character(len=4) :: post_fname
     889                 :             :     real(dp) :: T, T_step
     890                 :             :     integer :: i, ii, Tfile, iostat
     891                 :             :     character(len=90) :: msg
     892                 :             :     character(len=4200) :: Tmsg ! to write to var T file
     893                 :             :     character(len=150) :: iomsg
     894                 :             :     character(fnlen) :: Tfname ! file name for output various T calculation
     895                 :           0 :     real(dp), allocatable :: Tlist(:), chi_list(:), Cv_list(:), binderU4_list(:)
     896                 :           0 :     real(dp), allocatable :: Mst_sub_norm_list(:, :)
     897                 :           0 :     real(dp), allocatable ::  Mst_norm_total_list(:)
     898                 :             : 
     899                 :             :     integer :: master, my_rank, comm, nproc, ierr
     900                 :             :     logical :: iam_master
     901                 :           0 :     call init_mpi_info(master, iam_master, my_rank, comm, nproc)
     902                 :             : 
     903         [ #  # ]:           0 :     if (iam_master) then
     904                 :           0 :        T_start=self%params%spin_temperature_start
     905                 :           0 :        T_end=self%params%spin_temperature_end
     906                 :           0 :        T_nstep=self%params%spin_temperature_nstep
     907                 :           0 :        Tfile=get_unit()
     908         [ #  # ]:           0 :        Tfname = trim(ncfile_prefix)//'.varT'
     909                 :           0 :        iostat=open_file(file=Tfname, unit=Tfile, iomsg=iomsg )
     910         [ #  # ]:           0 :        if (T_nstep<=1) then
     911                 :             :           T_step=0.0
     912                 :             :        else
     913                 :           0 :           T_step=(T_end-T_start)/(T_nstep-1)
     914                 :             :        endif
     915                 :             :        write(msg, "(A52, ES13.5, A11, ES13.5, A1)") &
     916                 :           0 :             & "Starting temperature dependent calculations. T from ", &
     917                 :           0 :             & T_start*Ha_K, "K to ", T_end*Ha_K, " K."
     918                 :           0 :        call wrtout(std_out, msg, "COLL")
     919                 :           0 :        call wrtout(ab_out, msg, "COLL")
     920                 :             : 
     921   [ #  #  #  #  :           0 :        ABI_MALLOC(Tlist, (T_nstep))
          #  #  #  #  #  
                #  #  # ]
     922   [ #  #  #  #  :           0 :        ABI_MALLOC(chi_list, (T_nstep))
             #  #  #  # ]
     923   [ #  #  #  #  :           0 :        ABI_MALLOC(Cv_list, (T_nstep))
             #  #  #  # ]
     924   [ #  #  #  #  :           0 :        ABI_MALLOC(binderU4_list, (T_nstep))
             #  #  #  # ]
     925   [ #  #  #  #  :           0 :        ABI_MALLOC(Mst_sub_norm_list, (self%spin_ob%nsublatt, T_nstep))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     926   [ #  #  #  #  :           0 :        ABI_MALLOC( Mst_norm_total_list, (T_nstep))
             #  #  #  # ]
     927                 :             :     end if
     928                 :             : 
     929                 :           0 :     call xmpi_bcast(T_nstep, 0, comm, ierr)
     930                 :             : 
     931                 :             :     ! write header of varT file
     932         [ #  # ]:           0 :     if(iam_master) then
     933                 :             :        write(Tmsg, "(A1, 1X, A11, 3X, A13, 3X, A13, 3X, A13, 3X, A13, 3X, *(I13, 3X) )" ) &
     934   [ #  #  #  # ]:           0 :             "#", "Temperature (K)", "Cv (1)", "chi (1)",  "BinderU4 (1)", "Mst/Ms(1)", (ii, ii=1, self%spin_ob%nsublatt)
     935                 :           0 :        call wrtout(Tfile, Tmsg, "COLL")
     936                 :           0 :        flush(Tfile)
     937                 :             :     endif
     938                 :             : 
     939                 :             : 
     940                 :             : 
     941                 :             : 
     942         [ #  # ]:           0 :     do i=1, T_nstep
     943         [ #  # ]:           0 :        if(iam_master) then
     944                 :           0 :           T=T_start+(i-1)*T_step
     945                 :           0 :           msg=repeat("=", 79)
     946                 :           0 :           call wrtout(std_out, msg, "COLL")
     947                 :           0 :           call wrtout(ab_out, msg, "COLL")
     948                 :             : 
     949                 :           0 :           write(msg, "(A13, 5X, ES13.5, A3)") "Temperature: ", T*Ha_K, " K."
     950                 :           0 :           call wrtout(std_out, msg, "COLL")
     951                 :           0 :           call wrtout(ab_out,  msg, "COLL")
     952                 :             : 
     953                 :           0 :           call self%hist%reset(array_to_zero=.False.)
     954                 :             :           ! set temperature
     955                 :             :           ! TODO make this into a subroutine set_params
     956                 :           0 :           self%params%spin_temperature=T
     957                 :             :        endif
     958                 :           0 :        call self%set_temperature(temperature=T)
     959                 :             : 
     960         [ #  # ]:           0 :        if(iam_master) then
     961                 :             :           call self%hist%set_params(spin_nctime=self%params%spin_nctime, &
     962                 :           0 :                &     spin_temperature=T)
     963                 :           0 :           call self%spin_ob%reset(self%params)
     964                 :             :        endif
     965                 :             :           ! uncomment if then to use spin initializer at every temperature. otherwise use last temperature
     966         [ #  # ]:           0 :        if(i==1) then
     967                 :           0 :           call self%set_initial_state(mode=self%params%spin_init_state)
     968                 :             :        else
     969         [ #  # ]:           0 :           if(iam_master) then
     970                 :           0 :             call self%hist%inc1()
     971                 :             :            endif
     972                 :             :        endif
     973                 :             : 
     974         [ #  # ]:           0 :        if(iam_master) then
     975                 :           0 :           write(post_fname, "(I4.4)") i
     976                 :             :           call self%prepare_ncfile( self%params, &
     977         [ #  # ]:           0 :                & trim(ncfile_prefix)//'_T'//post_fname//'_spinhist.nc')
     978                 :           0 :           call self%spin_ncfile%write_one_step(self%hist)
     979                 :             :        endif
     980                 :             : 
     981                 :             :        ! run in parallel
     982                 :             :        call self%run_time(pot, displacement=displacement, strain=strain, spin=spin, &
     983   [ #  #  #  #  :           0 :             & lwf=lwf, energy_table=energy_table)
             #  #  #  # ]
     984                 :             : 
     985         [ #  # ]:           0 :        if(iam_master) then
     986                 :           0 :           call self%spin_ncfile%close()
     987                 :             :           ! save observables
     988                 :           0 :           Tlist(i)=T
     989                 :           0 :           chi_list(i)=self%spin_ob%chi
     990                 :           0 :           Cv_list(i)=self%spin_ob%Cv
     991                 :           0 :           binderU4_list(i)=self%spin_ob%binderU4
     992                 :             :           !Mst_sub_list(:,:,i)=self%spin_ob%Mst_sub(:,:)  ! not useful
     993         [ #  # ]:           0 :           Mst_sub_norm_list(:,i)=self%spin_ob%Avg_Mst_sub_norm(:)
     994                 :           0 :           Mst_norm_total_list(i)=self%spin_ob%Avg_Mst_norm_total
     995                 :             : 
     996                 :             :           ! write to varT file
     997                 :             :           write(Tmsg, "(2X, F11.5, 3X, ES13.5, 3X, ES13.5, 3X, E13.5, 3X, ES13.5, 3X, *(ES13.5, 3X) )" ) &
     998                 :           0 :                   Tlist(i)*Ha_K, Cv_list(i), chi_list(i),  binderU4_list(i), Mst_norm_total_list(i)/self%spin_ob%snorm_total,&
     999   [ #  #  #  # ]:           0 :                   & (Mst_sub_norm_list(ii,i)/mu_B, ii=1, self%spin_ob%nsublatt)
    1000                 :           0 :           call wrtout(Tfile, Tmsg, "COLL")
    1001                 :           0 :           flush(Tfile)
    1002                 :             : 
    1003                 :             :        endif
    1004                 :             : 
    1005                 :             :     end do
    1006                 :             : 
    1007                 :             : 
    1008         [ #  # ]:           0 :     if(iam_master) then
    1009                 :             :        ! write summary of MvT run
    1010                 :           0 :        msg=repeat("=", 79)
    1011                 :           0 :        call wrtout(std_out, msg, "COLL")
    1012                 :           0 :        call wrtout(ab_out, msg, "COLL")
    1013                 :             : 
    1014                 :           0 :        write(msg, *) "Summary of various T run: "
    1015                 :           0 :        call wrtout(std_out, msg, "COLL")
    1016                 :           0 :        call wrtout(ab_out, msg, "COLL")
    1017                 :             : 
    1018                 :             :        write(msg, "(A1, 1X, A11, 3X, A13, 3X, A13, 3X, A13, 3X, A13)" ) &
    1019                 :           0 :             "#", "Temperature", "Cv", "chi",  "BinderU4", "Mst"
    1020                 :           0 :        call wrtout(std_out, msg, "COLL")
    1021                 :           0 :        call wrtout(ab_out,  msg, "COLL")
    1022                 :             : 
    1023         [ #  # ]:           0 :        do i = 1, T_nstep
    1024                 :             :           write(msg, "(2X, F11.5, 3X, ES13.5, 3X, ES13.5, 3X, E13.5, 3X, ES13.5 )" ) &
    1025                 :           0 :                Tlist(i)*Ha_K, Cv_list(i), chi_list(i),  binderU4_list(i), Mst_norm_total_list(i)/self%spin_ob%snorm_total
    1026                 :           0 :           call wrtout(std_out, msg, "COLL")
    1027                 :           0 :           call wrtout(ab_out, msg, "COLL")
    1028                 :             :        end do
    1029                 :             : 
    1030                 :           0 :        msg=repeat("=", 79)
    1031                 :           0 :        call wrtout(std_out, msg, "COLL")
    1032                 :           0 :        call wrtout(ab_out, msg, "COLL")
    1033                 :             : 
    1034                 :             : 
    1035                 :             :        ! close varT file
    1036                 :           0 :        iostat= close_unit(unit=Tfile, iomsg=iomsg)
    1037                 :             : 
    1038         [ #  # ]:           0 :        ABI_FREE(Tlist)
    1039         [ #  # ]:           0 :        ABI_FREE(chi_list)
    1040         [ #  # ]:           0 :        ABI_FREE(Cv_list)
    1041         [ #  # ]:           0 :        ABI_FREE(binderU4_list)
    1042         [ #  # ]:           0 :        ABI_FREE(Mst_sub_norm_list)
    1043         [ #  # ]:           0 :        ABI_FREE( Mst_norm_total_list)
    1044                 :             : 
    1045                 :             :     endif
    1046   [ #  #  #  #  :           0 :   end subroutine run_MvT
          #  #  #  #  #  
                #  #  # ]
    1047                 :             :   !!***
    1048                 :             : 
    1049                 :             :   !!****f* m_spin_mover/current_spin
    1050                 :             :   !!
    1051                 :             :   !! NAME
    1052                 :             :   !! current_spin
    1053                 :             :   !!
    1054                 :             :   !! FUNCTION
    1055                 :             :   !! return the current spin state
    1056                 :             :   !!
    1057                 :             :   !! INPUTS
    1058                 :             :   !!
    1059                 :             :   !!
    1060                 :             :   !! OUTPUT
    1061                 :             :   !!
    1062                 :             :   !!
    1063                 :             :   !!
    1064                 :             :   !! SOURCE
    1065                 :           0 :   function current_spin(self) result(ret)
    1066                 :             :     class(spin_mover_t), target, intent(inout) :: self
    1067                 :             :     real(dp), pointer :: ret(:,:)
    1068                 :             :     integer :: i
    1069                 :           0 :     i=self%hist%findIndex(step=0)
    1070                 :           0 :     ret => self%hist%S(:,:,i)
    1071                 :           0 :   end function current_spin
    1072                 :             :   !!***
    1073                 :             : 
    1074                 :             : 
    1075                 :             : 
    1076                 :             : 
    1077                 :             :   !!****f* m_spin_mover/finalize
    1078                 :             :   !!
    1079                 :             :   !! NAME
    1080                 :             :   !! finalize
    1081                 :             :   !!
    1082                 :             :   !! FUNCTION
    1083                 :             :   !! finalize spin mover.
    1084                 :             :   !!
    1085                 :             :   !! INPUTS
    1086                 :             :   !!
    1087                 :             :   !! OUTPUT
    1088                 :             :   !!
    1089                 :             :   !! NOTES
    1090                 :             :   !!   does nothing. But it's better to preserve initialize-finalize symmetry.
    1091                 :             :   !!
    1092                 :             :   !! SOURCE
    1093                 :           2 :   subroutine finalize(self)
    1094                 :             : 
    1095                 :             :     class(spin_mover_t), intent(inout):: self
    1096         [ +  - ]:           2 :     if(allocated(self%gyro_ratio) ) then
    1097                 :           2 :        ABI_FREE(self%gyro_ratio)
    1098                 :             :     end if
    1099                 :             : 
    1100         [ +  - ]:           2 :     if(allocated(self%damping) ) then
    1101                 :           2 :        ABI_FREE(self%damping)
    1102                 :             :     end if
    1103                 :             : 
    1104         [ +  - ]:           2 :     if(allocated(self%gamma_l) ) then
    1105                 :           2 :        ABI_FREE(self%gamma_l)
    1106                 :             :     end if
    1107                 :             : 
    1108         [ +  - ]:           2 :     if(allocated(self%H_lang_coeff) ) then
    1109                 :           2 :        ABI_FREE(self%H_lang_coeff)
    1110                 :             :     end if
    1111                 :             : 
    1112         [ +  - ]:           2 :     if(allocated(self%ms) ) then
    1113                 :           2 :        ABI_FREE(self%ms)
    1114                 :             :     end if
    1115                 :             : 
    1116                 :             : 
    1117                 :             : 
    1118         [ -  + ]:           2 :     if(self%method==3) then
    1119                 :           0 :        call self%spin_mc%finalize()
    1120                 :             :     end if
    1121                 :             : 
    1122         [ +  - ]:           2 :     if(allocated(self%Stmp)) then
    1123                 :           2 :        ABI_FREE(self%Stmp)
    1124                 :             :     end if
    1125                 :             : 
    1126         [ +  - ]:           2 :     if(allocated(self%Stmp2)) then
    1127                 :           2 :        ABI_FREE(self%Stmp2)
    1128                 :             :     end if
    1129                 :             : 
    1130                 :             : 
    1131         [ +  - ]:           2 :     if(allocated(self%Heff_tmp)) then
    1132                 :           2 :        ABI_FREE(self%Heff_tmp)
    1133                 :             :     end if
    1134                 :             : 
    1135         [ +  - ]:           2 :     if(allocated(self%Htmp)) then
    1136                 :           2 :        ABI_FREE(self%Htmp)
    1137                 :             :     end if
    1138                 :             : 
    1139         [ +  - ]:           2 :     if(allocated(self%Hrotate)) then
    1140                 :           2 :        ABI_FREE(self%Hrotate)
    1141                 :             :     end if
    1142                 :             : 
    1143         [ +  - ]:           2 :     if(allocated(self%H_lang)) then
    1144                 :           2 :        ABI_FREE(self%H_lang)
    1145                 :             :     end if
    1146                 :             : 
    1147         [ +  - ]:           2 :     if(allocated(self%buffer)) then
    1148                 :           2 :        ABI_FREE(self%buffer)
    1149                 :             :     end if
    1150                 :             : 
    1151                 :             : 
    1152                 :           2 :     nullify(self%supercell)
    1153                 :           2 :     nullify(self%params)
    1154                 :           2 :     nullify(self%rng)
    1155                 :           2 :     call self%mps%finalize()
    1156                 :           2 :     call self%hist%finalize()
    1157                 :           2 :     call self%spin_ob%finalize()
    1158                 :             :     !call self%spin_ncfile%close()
    1159                 :           2 :     call self%spin_ob%finalize()
    1160                 :           2 :   end subroutine finalize
    1161                 :             :   !!***
    1162                 :             : 
    1163   [ #  #  #  #  :           0 : end module m_spin_mover
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
        

Generated by: LCOV version 2.3-1