LCOV - code coverage report
Current view: top level - src/78_effpot - m_lattice_mover.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 61.9 % 189 117
Test Date: 2026-09-19 17:42:43 Functions: 58.8 % 17 10

            Line data    Source code
       1              : !!****m* ABINIT/m_lattice_mover
       2              : !! NAME
       3              : !! m_lattice_mover
       4              : !!
       5              : !! FUNCTION
       6              : !! This module contains the lattice mover.
       7              : !!
       8              : !!
       9              : !! Datatypes:
      10              : !!
      11              : !! * lattice_mover_t: defines the lattice movers
      12              : !!
      13              : !! Subroutines:
      14              : !! TODO: add this when F2003 doc style is determined.
      15              : !!
      16              : !!
      17              : !! COPYRIGHT
      18              : !! Copyright (C) 2001-2026 ABINIT group (hexu)
      19              : !! This file is distributed under the terms of the
      20              : !! GNU General Public License, see ~abinit/COPYING
      21              : !! or http://www.gnu.org/copyleft/gpl.txt .
      22              : !! For the initials of contributorsi see ~abinit/doc/developers/contributors.txt .
      23              : !!
      24              : !! SOURCE
      25              : 
      26              : 
      27              : 
      28              : #if defined HAVE_CONFIG_H
      29              : #include "config.h"
      30              : #endif
      31              : 
      32              : #include "abi_common.h"
      33              : 
      34              : module m_lattice_mover
      35              :   use defs_basis
      36              :   use m_abicore
      37              :   use m_errors
      38              :   use m_xmpi
      39              :   use m_multibinit_dataset, only: multibinit_dtset_type
      40              :   use m_abstract_potential, only: abstract_potential_t
      41              :   use m_abstract_mover, only: abstract_mover_t
      42              :   use m_multibinit_cell, only: mbcell_t, mbsupercell_t
      43              :   use m_random_xoroshiro128plus, only:  rng_t
      44              :   use m_hashtable_strval, only: hash_table_t
      45              :   use m_lattice_ncfile, only: lattice_ncfile_t
      46              :   use m_mpi_scheduler, only: init_mpi_info
      47              : !!***
      48              : 
      49              :   implicit none
      50              :   private
      51              : 
      52              :   type ,public, extends(abstract_mover_t) :: lattice_mover_t
      53              :      !> This is the abstract lattice mover
      54              : 
      55              :      type(multibinit_dtset_type), pointer :: params=>null() ! input parameters
      56              :      integer :: natom=0     ! number of atoms
      57              :      real(dp) :: stress(3,3), strain(3,3)  ! stress and strain
      58              :      real(dp), allocatable :: masses(:)  ! masses
      59              :      integer :: latt_dynamics=0 ! type of lattice dynamics
      60              : 
      61              :      ! hexu: is xcart needed?
      62              :      real(dp), allocatable :: current_xcart(:,:) ! xcart of current step
      63              :      real(dp), allocatable :: current_vcart(:,:) ! vcart of current step
      64              :      real(dp), allocatable :: forces(:,:)        ! forces
      65              :      real(dp), allocatable :: displacement(:,:)  ! displacement
      66              :      real(dp) :: energy  ! total energy
      67              :      real(dp) :: Ek      ! kinetic energy
      68              :      real(dp) :: T_ob    ! observed temperature
      69              :      logical :: is_null = .True.
      70              :      !> TODO: hist
      71              :      !type(lattice_hist_t) :: hist
      72              : 
      73              :      real(dp) :: mass_total
      74              :      type(lattice_ncfile_t) :: ncfile
      75              :    contains
      76              :      procedure:: initialize       ! perhaps each effpot type should have own
      77              :      procedure :: finalize
      78              :      procedure :: set_params
      79              :      procedure :: prepare_ncfile
      80              :      procedure :: set_ncfile_name
      81              :      procedure :: set_initial_state ! initial state
      82              :      procedure :: set_temperature
      83              :      procedure :: force_stationary
      84              :      procedure :: run_one_step
      85              :      procedure :: run_time
      86              :      procedure :: run_varT
      87              :      procedure :: reset            ! reset the mover
      88              :      procedure :: get_T_and_Ek     ! calculate temperature and kinetic energy.
      89              :      procedure :: calc_observables ! call functions to calculate observables
      90              :      procedure :: write_hist       ! write hist file
      91              :   end type lattice_mover_t
      92              : 
      93              : 
      94              : contains
      95              : 
      96              :   !-------------------------------------------------------------------!
      97              :   ! Initialize:
      98              :   !
      99              :   ! Inputs:
     100              :   !> params: input parameters
     101              :   !> supercell: supercell.
     102              :   !> rng: random number generator
     103              :   !-------------------------------------------------------------------!
     104            5 :   subroutine initialize(self, params, supercell, rng)
     105              :     class(lattice_mover_t), intent(inout) :: self
     106              :     type(multibinit_dtset_type),target, intent(in) :: params
     107              :     type(mbsupercell_t),target, intent(in) :: supercell
     108              :     type(rng_t), target, intent(in) :: rng
     109            5 :     self%params=>params
     110            5 :     self%supercell=>supercell
     111            5 :     self%label="Lattice Mover"
     112            5 :     self%natom = supercell%lattice%natom
     113           15 :     ABI_MALLOC(self%masses, (self%natom))
     114           15 :     ABI_MALLOC(self%displacement, (3, self%natom))
     115           15 :     ABI_MALLOC(self%current_xcart, (3, self%natom))
     116           15 :     ABI_MALLOC(self%current_vcart, (3, self%natom))
     117           15 :     ABI_MALLOC(self%forces, (3,self%natom))
     118            5 :     self%is_null=.False.
     119           65 :     self%strain(:,:) = 0.0
     120           65 :     self%stress(:,:) = 0.0
     121        18565 :     self%forces(:,:) = 0.0
     122        18565 :     self%displacement(:,:) = 0.0
     123        18565 :     self%current_vcart(:,:) = 0.0
     124            5 :     call self%set_params(params)
     125            5 :     call self%set_rng(rng)
     126            5 :   end subroutine initialize
     127              : 
     128              :   !-------------------------------------------------------------------!
     129              :   ! Finalize:
     130              :   !-------------------------------------------------------------------!
     131            5 :   subroutine finalize(self)
     132              :     class(lattice_mover_t), intent(inout) :: self
     133            5 :     nullify(self%supercell)
     134            5 :     nullify(self%params)
     135            5 :     self%label="Destroyed lattice mover"
     136            5 :     if (.not.self%is_null) then
     137            5 :        ABI_FREE(self%masses)
     138            5 :        ABI_FREE(self%current_xcart)
     139            5 :        ABI_FREE(self%current_vcart)
     140            5 :        ABI_FREE(self%forces)
     141            5 :        ABI_FREE(self%displacement)
     142              :     endif
     143            5 :     self%is_null=.True.
     144            5 :   end subroutine finalize
     145              : 
     146              :   !-------------------------------------------------------------------!
     147              :   ! Set the mover using the input parameters
     148              :   !-------------------------------------------------------------------!
     149            5 :   subroutine set_params(self, params)
     150              :     ! set parameters from input file. (something else, like temperature for MvT calculation?)
     151              :     class(lattice_mover_t), intent(inout) :: self
     152              :     type(multibinit_dtset_type) :: params
     153            5 :     self%temperature = params%temperature !TODO: to Hartree ??
     154            5 :     self%dt =params%dtion
     155         4645 :     self%masses(:)=self%supercell%lattice%masses(:)
     156         4645 :     self%mass_total = sum(self%masses)
     157            5 :     self%total_time = self%dt * params%ntime
     158            5 :     self%latt_dynamics = params%dynamics
     159            5 :   end subroutine set_params
     160              : 
     161              :   !-------------------------------------------------------------------!
     162              :   ! Set the mover temperature
     163              :   !-------------------------------------------------------------------!
     164            0 :   subroutine set_temperature(self, temperature)
     165              :     class(lattice_mover_t), intent(inout) :: self
     166              :     real(dp),intent(in) :: temperature
     167            0 :     self%temperature = temperature !TODO: to Hartree ??
     168            0 :   end subroutine set_temperature
     169              : 
     170              : 
     171              :   !-------------------------------------------------------------------!
     172              :   ! set initial state:
     173              :   !  Inputs:
     174              :   !   mode: integer
     175              :   !    if mode=1, use a Boltzman distribution to init the velocities.
     176              :   !    if mode=2, ...
     177              :   !-------------------------------------------------------------------!
     178            5 :   subroutine set_initial_state(self, mode)
     179              :     ! set initial positions, spin, etc
     180              :     class(lattice_mover_t), intent(inout) :: self
     181              :     integer, optional, intent(in) :: mode
     182           10 :     real(dp) :: xi(3, self%natom)
     183              :     integer :: i
     184              : 
     185              : 
     186            5 :     if(mode==1) then ! using a boltzmann distribution.
     187              :        ! Should only be used for a constant Temperature mover
     188              :        ! which includes:
     189              :        !   102:    Langevin
     190              :        !   103:    Brendesen
     191            5 :        if (.not.( &
     192              :           self%latt_dynamics==101 .or.  &  ! TODO remove
     193              :           self%latt_dynamics==102 .or. self%latt_dynamics==103 ) ) then
     194            0 :           ABI_ERROR("Only set lattice initial state with a Boltzmann distribution in a constant T mover.")
     195              :        end if
     196            5 :        call self%rng%rand_normal_array(xi, 3*self%natom)
     197         4645 :        do i=1, self%natom
     198        18565 :           self%current_vcart(:,i) = xi(:, i) *sqrt(self%temperature/self%masses(i))
     199              :        end do
     200            5 :        call self%force_stationary()
     201            5 :        call self%get_T_and_Ek()
     202        18565 :        self%current_xcart(:, :) = self%supercell%lattice%xcart(:,:)
     203            0 :     else if(mode==2) then ! Use reference structure and 0 velocity.
     204              :        ! other modes.
     205            0 :        if(self%latt_dynamics==102 .or. self%latt_dynamics==103 ) then
     206            0 :            ABI_ERROR("Displacement and velocity set to zero in a NVT mover.")
     207              :        end if
     208            0 :        do i=1, self%natom
     209            0 :           self%current_vcart(:,i) = 0.0
     210              :        end do
     211            0 :        self%current_xcart(:, :) = self%supercell%lattice%xcart(:,:)
     212            0 :        call self%get_T_and_Ek()
     213              :     end if
     214              : 
     215              : 
     216            5 :   end subroutine set_initial_state
     217              : 
     218            3 :   subroutine prepare_ncfile(self, params, fname)
     219              :     class(lattice_mover_t), intent(inout) :: self
     220              :     type(multibinit_dtset_type) :: params
     221              :     character(len=*), intent(in) :: fname
     222              :     integer :: master, my_rank, comm, nproc
     223              :     logical :: iam_master
     224            3 :     ABI_UNUSED_A(params)
     225            3 :     call init_mpi_info(master, iam_master, my_rank, comm, nproc)
     226            3 :     if(iam_master) then
     227            3 :        call self%ncfile%initialize( trim(fname), 1)
     228            3 :        call self%ncfile%write_cell(self%supercell)
     229            3 :        call self%ncfile%def_lattice_var()
     230              :     end if
     231            3 :   end subroutine prepare_ncfile
     232              : 
     233              : 
     234              :   !-------------------------------------------------------------------!
     235              :   !set_ncfile_name :
     236              :   !-------------------------------------------------------------------!
     237            3 :   subroutine set_ncfile_name(self, params, fname)
     238              :     class(lattice_mover_t), intent(inout) :: self
     239              :     type(multibinit_dtset_type) :: params
     240              :     character(len=fnlen), intent(in) :: fname
     241              :     integer :: master, my_rank, comm, nproc
     242              :     logical :: iam_master
     243            3 :     call init_mpi_info(master, iam_master, my_rank, comm, nproc)
     244            3 :     if (iam_master) then
     245            3 :        call self%prepare_ncfile(params, trim(fname)//'_latthist.nc')
     246            3 :        call self%ncfile%write_one_step(self%current_xcart, self%current_vcart, self%energy, self%Ek )
     247              :     endif
     248            3 :   end subroutine set_ncfile_name
     249              : 
     250              : 
     251              : 
     252              :   !-------------------------------------------------------------------!
     253              :   ! Make sure the mass center does not move.
     254              :   !-------------------------------------------------------------------!
     255         2005 :   subroutine force_stationary(self)
     256              :     class(lattice_mover_t), intent(inout) :: self
     257              :     integer :: i
     258              :     real(dp) :: p(3), pavg(3)
     259         2005 :     p(:)=0.0
     260      2166645 :     do i = 1, self%natom
     261      8660565 :        p(:)=p(:)+self%current_vcart(:,i) * self%masses(i)
     262              :     end do
     263         8020 :     pavg=p/self%mass_total
     264      2166645 :     do i = 1, self%natom
     265      8660565 :        self%current_vcart(:, i) = self%current_vcart(:, i) - pavg(:)
     266              :     end do
     267         2005 :   end subroutine force_stationary
     268              : 
     269              : 
     270              :   !-------------------------------------------------------------------!
     271              :   ! Force the temperature strictly.
     272              :   ! Since the boltzman distribution has some fluctuation
     273              :   !-------------------------------------------------------------------!
     274              :   subroutine force_temperature(self)
     275              :     class(lattice_mover_t), intent(inout) :: self
     276              :     ABI_UNUSED_A(self)
     277              :   end subroutine force_temperature
     278              : 
     279              : 
     280              :   !-------------------------------------------------------------------!
     281              :   ! run_one_step
     282              :   !  run one step of dynamics.
     283              :   !  Should be overrided.
     284              :   !  Inputs:
     285              :   !> effpot: effective potential
     286              :   !> displacement: should NOT be provided, since it is already stored.
     287              :   !> strain: Also should NOT be provided.
     288              :   !> spin: should be provided only if there is spin-lattice coupling
     289              :   !> lwf : should be provided only if there is lattice-lwf coupling (unlikely)
     290              :   !> energy_table: energy_table.
     291              :   !-------------------------------------------------------------------!
     292            0 :   subroutine run_one_step(self, effpot, displacement, strain, spin, lwf, energy_table)
     293              :     ! run one step. (For MC also?)
     294              :     class(lattice_mover_t),      intent(inout) :: self    ! array of effective potentials so that there can be multiple of them.
     295              :     class(abstract_potential_t), intent(inout) :: effpot
     296              :     real(dp), optional,          intent(inout) :: displacement(:,:), strain(:,:), spin(:,:), lwf(:)
     297              :     type(hash_table_t), optional, intent(inout) :: energy_table
     298              : 
     299              :     character(len=40) :: key
     300              : 
     301            0 :     if(present(displacement) .or. present(strain)) then
     302            0 :        ABI_ERROR("displacement and strain should not be input for lattice mover")
     303              :     end if
     304              : 
     305            0 :     ABI_BUG("The abstract lattice mover is used, which should be a bug.")
     306              : 
     307            0 :     ABI_UNUSED_A(self)
     308            0 :     ABI_UNUSED_A(effpot)
     309            0 :     ABI_UNUSED_A(displacement)
     310            0 :     ABI_UNUSED_A(strain)
     311            0 :     ABI_UNUSED_A(spin)
     312            0 :     ABI_UNUSED_A(lwf)
     313            0 :     ABI_UNUSED_A(energy_table)
     314              : 
     315            0 :     call self%get_T_and_Ek()
     316            0 :     if (present(energy_table)) then
     317            0 :       key = 'Lattice kinetic energy'
     318            0 :       call energy_table%put(key, self%Ek)
     319              :     end if
     320            0 :   end subroutine run_one_step
     321              : 
     322              : 
     323              :   !-------------------------------------------------------------------!
     324              :   !get_temperature_and_kinetic_energy
     325              :   ! Ek = 1/2 \sum m_i vi^2
     326              :   ! T = 2/3 Ek/natom  (in a.u.)
     327              :   !-------------------------------------------------------------------!
     328         4017 :   subroutine get_T_and_Ek(self)
     329              :     class(lattice_mover_t), intent(inout) :: self
     330              :     integer :: i
     331         4017 :     self%Ek=0.0
     332      4334017 :     do i =1, self%natom
     333              :        self%Ek = self%Ek+ 0.5* self%masses(i) *  &
     334     17324017 :             &sum(self%current_vcart(:,i)*self%current_vcart(:,i))
     335              :     end do
     336              :     ! temperature
     337         4017 :     self%T_ob = 2.0*self%Ek/(3*self%natom)
     338         4017 :   end subroutine get_T_and_Ek
     339              : 
     340              : 
     341              :   !-------------------------------------------------------------------!
     342              :   ! run from begining to end.
     343              :   !-------------------------------------------------------------------!
     344            3 :   subroutine run_time(self, effpot, displacement, strain, spin, lwf, energy_table)
     345              :     class(lattice_mover_t), intent(inout) :: self
     346              :     ! array of effective potentials so that there can be multiple of them.
     347              :     class(abstract_potential_t), intent(inout) :: effpot
     348              :     real(dp), optional, intent(inout) :: displacement(:,:), strain(:,:), spin(:,:), lwf(:)
     349              :     type(hash_table_t), optional, intent(inout) :: energy_table
     350              :     integer :: i, nstep
     351              :     character(len=90) :: msg
     352            3 :     if(present(displacement) .or. present(strain)) then
     353            0 :        ABI_ERROR("displacement and strain should not be input for lattice mover")
     354              :     end if
     355            3 :     ABI_UNUSED_A(self)
     356            3 :     ABI_UNUSED_A(effpot)
     357            3 :     ABI_UNUSED_A(spin)
     358            3 :     ABI_UNUSED_A(lwf)
     359            3 :     ABI_UNUSED_A(energy_table)
     360              : 
     361              : 
     362            3 :     msg=repeat("=", 90)
     363            3 :     call wrtout(std_out,msg,'COLL')
     364            3 :     call wrtout(ab_out, msg, 'COLL')
     365            3 :     write(msg, '(A22)') "Lattice dynamic steps:"
     366            3 :     call wrtout(std_out,msg,'COLL')
     367            3 :     call wrtout(ab_out, msg, 'COLL')
     368            3 :     msg=repeat("=", 90)
     369            3 :     call wrtout(std_out,msg,'COLL')
     370            3 :     call wrtout(ab_out, msg, 'COLL')
     371              : 
     372              :     write(msg, "(A13, 4X, A15, 4X, A15, 4X, A15, 4X, A15)") &
     373            3 :             &  "Iteration", "temperature(K)", "Ekin(Ha/uc)", &
     374            6 :             & "Epot(Ha/uc)", "ETOT(Ha/uc)"
     375            3 :     call wrtout(std_out,msg,'COLL')
     376            3 :     call wrtout(ab_out, msg, 'COLL')
     377              : 
     378            3 :     nstep=floor(self%thermal_time/self%dt)
     379            3 :     do i =1, nstep
     380            3 :        call self%run_one_step(effpot=effpot, spin=spin, lwf=lwf, energy_table=energy_table)
     381              :     end do
     382              : 
     383            3 :     nstep=floor(self%total_time/self%dt)
     384         2013 :     do i =1, nstep
     385         6030 :        call self%run_one_step(effpot=effpot, spin=spin, lwf=lwf, energy_table=energy_table)
     386         2013 :        if(modulo(i, self%params%nctime)==0) then
     387          210 :           write(msg, "(I13, 4X, F15.5, 4X, ES15.5, 4X, ES15.5, 4X, ES15.5)")  i, self%T_ob*Ha_K, &
     388          210 :                & self%Ek/self%supercell%ncell, self%energy/self%supercell%ncell, &
     389          420 :                & (self%Ek+self%energy)/self%supercell%ncell
     390          210 :           call wrtout(std_out,msg,'COLL')
     391          210 :           call wrtout(ab_out, msg, 'COLL')
     392       877220 :           self%current_xcart = self%supercell%lattice%xcart+self%displacement
     393          210 :           call self%ncfile%write_one_step(self%current_xcart, self%current_vcart, self%energy, self%Ek)
     394              :        end if
     395              :        !TODO: output, observables
     396              :     end do
     397              : 
     398            3 :     msg=repeat("=", 90)
     399            3 :     call wrtout(std_out,msg,'COLL')
     400            3 :     call wrtout(ab_out, msg, 'COLL')
     401              : 
     402            3 :   end subroutine run_time
     403              : 
     404              : 
     405              :   !-------------------------------------------------------------------!
     406              :   ! Reset:
     407              :   ! It reset the counter of steps, but does not set the initial state
     408              :   ! again.
     409              :   !-------------------------------------------------------------------!
     410            0 :   subroutine reset(self)
     411              :     ! reset the state of mover (e.g. counter->0)
     412              :     ! so it can be reused.
     413              :     class(lattice_mover_t), intent(inout) :: self
     414            0 :     ABI_UNUSED_A(self)
     415            0 :   end subroutine reset
     416              : 
     417              :   !-------------------------------------------------------------------!
     418              :   !Calc_observables
     419              :   !
     420              :   !-------------------------------------------------------------------!
     421            0 :   subroutine calc_observables(self)
     422              :     ! call functions to calculate observables.
     423              :     class(lattice_mover_t), intent(inout) :: self
     424            0 :     ABI_UNUSED_A(self)
     425            0 :   end subroutine calc_observables
     426              : 
     427              :   !-------------------------------------------------------------------!
     428              :   ! Write_hist: write to hist file
     429              :   !-------------------------------------------------------------------!
     430            0 :   subroutine write_hist(self)
     431              :     ! write to hist file
     432              :     class(lattice_mover_t), intent(inout) :: self
     433            0 :     ABI_UNUSED_A(self)
     434              : 
     435            0 :   end subroutine write_hist
     436              : 
     437              :   !-------------------------------------------------------------------!
     438              :   ! Get_state: get the current state
     439              :   !-------------------------------------------------------------------!
     440              :   subroutine get_state(self, displacement, strain, spin, lwf, ihist)
     441              :     ! get the state of the ihist(th) step. ihist can be 0 (current), -1 (last), ... -maxhist..
     442              :     class(lattice_mover_t), intent(in):: self
     443              :     real(dp), optional, intent(inout) :: displacement, strain, spin, lwf
     444              :     integer, optional, intent(in):: ihist
     445              :     ABI_UNUSED_A(self)
     446              :     ABI_UNUSED_A(displacement)
     447              :     ABI_UNUSED_A(strain)
     448              :     ABI_UNUSED_A(spin)
     449              :     ABI_UNUSED_A(lwf)
     450              :     ABI_UNUSED_A(ihist)
     451              :   end subroutine get_state
     452              : 
     453              : 
     454              :   !!****f* m_lwf_mover/run_varT
     455              :   !!
     456              :   !! NAME
     457              :   !! run_varT
     458              :   !!
     459              :   !! FUNCTION
     460              :   !! run M vs Temperature
     461              :   !!
     462              :   !! INPUTS
     463              :   !! pot: potential
     464              :   !! T_start, Tend, T_nstep
     465              :   !u
     466              :   !! OUTPUT
     467              :   !!
     468              :   !! SOURCE
     469            0 :   subroutine  run_varT(self, pot, ncfile_prefix, displacement, strain, spin, lwf, energy_table)
     470              :     class(lattice_mover_t), intent(inout) :: self
     471              :     class(abstract_potential_t), intent(inout) :: pot
     472              :     real(dp), optional, intent(inout) :: displacement(:,:), strain(:,:), lwf(:), spin(:,:)
     473              :     character(fnlen), intent(inout) :: ncfile_prefix
     474              :     type(hash_table_t), optional, intent(inout) :: energy_table
     475              :     real(dp) :: T_start, T_end
     476              :     integer :: T_nstep
     477              :     !type(lwf_ncfile_t) :: lwf_ncfile
     478              :     character(len=4) :: post_fname
     479              :     real(dp) :: T, T_step
     480              :     integer :: i
     481              :     !integer :: Tfile, iostat
     482              :     character(len=90) :: msg
     483              :     !character(len=4200) :: Tmsg ! to write to var T file
     484              :     !character(len=150) :: iomsg
     485              :     !character(fnlen) :: Tfname ! file name for output various T calculation
     486              :     !real(dp), allocatable :: Tlist(:), chi_list(:), Cv_list(:), binderU4_list(:)
     487              :     !real(dp), allocatable :: Mst_sub_norm_list(:, :)
     488              :     !real(dp), allocatable ::  Mst_norm_total_list(:)
     489              : 
     490              :     integer :: master, my_rank, comm, nproc, ierr
     491              :     logical :: iam_master
     492            0 :     call init_mpi_info(master, iam_master, my_rank, comm, nproc)
     493              : 
     494            0 :     ABI_UNUSED_A(displacement)
     495            0 :     ABI_UNUSED_A(strain)
     496              : 
     497            0 :     if (iam_master) then
     498            0 :        T_start=self%params%latt_temperature_start
     499            0 :        T_end=self%params%latt_temperature_end
     500            0 :        T_nstep=self%params%latt_temperature_nstep
     501              :        !Tfile=get_unit()
     502              :        !Tfname = trim(ncfile_prefix)//'.varT'
     503              :        !iostat=open_file(file=Tfname, unit=Tfile, iomsg=iomsg )
     504            0 :        if (T_nstep<=1) then
     505              :           T_step=0.0
     506              :        else
     507            0 :           T_step=(T_end-T_start)/(T_nstep-1)
     508              :        endif
     509              :        write(msg, "(A52, ES13.5, A11, ES13.5, A1)") &
     510            0 :             & "Starting temperature dependent calculations. T from ", &
     511            0 :             & T_start*Ha_K, "K to ", T_end*Ha_K, " K."
     512            0 :        call wrtout(std_out, msg, "COLL")
     513            0 :        call wrtout(ab_out, msg, "COLL")
     514              :     end if
     515              : 
     516            0 :     call xmpi_bcast(T_nstep, 0, comm, ierr)
     517            0 :     do i=1, T_nstep
     518            0 :        if(iam_master) then
     519            0 :           T=T_start+(i-1)*T_step
     520            0 :           msg=repeat("=", 79)
     521            0 :           call wrtout(std_out, msg, "COLL")
     522            0 :           call wrtout(ab_out, msg, "COLL")
     523              : 
     524            0 :           write(msg, "(A13, 5X, ES13.5, A3)") "Temperature: ", T*Ha_K, " K."
     525            0 :           call wrtout(std_out, msg, "COLL")
     526            0 :           call wrtout(ab_out,  msg, "COLL")
     527              : 
     528              :           ! set temperature
     529              :           ! TODO make this into a subroutine set_params
     530              :        endif
     531            0 :        call self%set_temperature(temperature=T)
     532            0 :        if(iam_master) then
     533            0 :           if(i==1) then
     534            0 :              call self%set_initial_state(mode=1)
     535              :           endif
     536              : 
     537            0 :           write(post_fname, "(I4.4)") i
     538              :           call self%prepare_ncfile( self%params, &
     539            0 :                & trim(ncfile_prefix)//'_T'//post_fname//'_latthist.nc')
     540            0 :           call self%ncfile%write_one_step(self%current_xcart, self%current_vcart, self%energy, self%Ek )
     541              :        endif
     542              : 
     543              :        call self%run_time(pot, spin=spin, &
     544            0 :             & lwf=lwf, energy_table=energy_table)
     545              : 
     546            0 :        if(iam_master) then
     547            0 :           call self%ncfile%finalize()
     548              :        endif
     549              :     end do
     550              : 
     551            0 :   end subroutine run_varT
     552              :   !!***
     553              : 
     554              : 
     555              : 
     556           15 : end module m_lattice_mover
     557              : 
        

Generated by: LCOV version 2.3-1