LCOV - code coverage report
Current view: top level - src/78_effpot - m_lattice_harmonic_potential.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 42 42
Test Date: 2026-09-20 15:27:41 Functions: 100.0 % 8 8

            Line data    Source code
       1              : !!****m* ABINIT/m_lattice_harmonic_potential
       2              : !! NAME
       3              : !! m_lattice_harmonic_potential
       4              : !!
       5              : !! FUNCTION
       6              : !! This module contains an harmonic lattice potential.
       7              : !!
       8              : !! Datatypes:
       9              : !!
      10              : !! Subroutines:
      11              : !! TODO: add this when F2003 doc style is determined.
      12              : !!
      13              : !!
      14              : !! COPYRIGHT
      15              : !! Copyright (C) 2001-2026 ABINIT group (hexu)
      16              : !! This file is distributed under the terms of the
      17              : !! GNU General Public License, see ~abinit/COPYING
      18              : !! or http://www.gnu.org/copyleft/gpl.txt .
      19              : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
      20              : !!
      21              : !! SOURCE
      22              : 
      23              : 
      24              : #if defined HAVE_CONFIG_H
      25              : #include "config.h"
      26              : #endif
      27              : 
      28              : #include "abi_common.h"
      29              : 
      30              : 
      31              : module m_lattice_harmonic_potential
      32              :   use defs_basis
      33              :   use m_errors
      34              :   use m_abicore
      35              :   use m_abstract_potential, only: abstract_potential_t
      36              :   use m_spmat_coo, only: COO_mat_t
      37              :   use m_multibinit_cell, only: mbcell_t, mbsupercell_t
      38              :   use m_hashtable_strval, only: hash_table_t
      39              :   implicit none
      40              : !!***
      41              : 
      42              :   private
      43              : 
      44              :   type, public, extends(abstract_potential_t) :: lattice_harmonic_potential_t
      45              :      integer :: natom           ! number of atoms
      46              :      real(dp) :: ref_energy=0.0      ! reference energy
      47              :      !real(dp):: ref_cell(3,3)   ! reference structure cell parameters.Not needed.
      48              :      !real(dp), allocatable :: ref_xcart(:,:) ! reference xcart. not needed
      49              :      type(COO_mat_t) :: coeff  ! coefficient. A COO sparse matrix (3N*3N).
      50              :    contains
      51              :      procedure :: initialize
      52              :      procedure :: finalize
      53              :      procedure :: set_supercell
      54              :      procedure :: set_ref_energy
      55              :      procedure :: calculate
      56              :      procedure :: add_term
      57              :   end type lattice_harmonic_potential_t
      58              : 
      59              : contains
      60              : 
      61              : 
      62              :   !-------------------------------------------------------------------!
      63              :   ! initialize
      64              :   ! Input:
      65              :   !  natom: number of atoms
      66              :   !-------------------------------------------------------------------!
      67            5 :   subroutine initialize(self, natom)
      68              :     class(lattice_harmonic_potential_t), intent(inout) :: self
      69              :     integer, intent(in) :: natom
      70            5 :     self%has_displacement = .True.
      71            5 :     self%is_null = .False.
      72            5 :     self%label="Lattice_harmonic_potential"
      73            5 :     self%natom=natom
      74           15 :     call self%coeff%initialize(mshape= [3*self%natom, 3*self%natom])
      75              :     !ABI_MALLOC(self%ref_xcart, (3, self%natom))
      76            5 :   end subroutine initialize
      77              : 
      78              :   !-------------------------------------------------------------------!
      79              :   ! Finalize
      80              :   !-------------------------------------------------------------------!
      81            5 :   subroutine finalize(self)
      82              :     class(lattice_harmonic_potential_t), intent(inout) :: self
      83            5 :     self%has_displacement=.False.
      84            5 :     call self%coeff%finalize()
      85            5 :     call self%abstract_potential_t%finalize()
      86            5 :     self%is_null=.True.
      87            5 :     self%natom=0
      88            5 :   end subroutine finalize
      89              : 
      90              :   !-------------------------------------------------------------------!
      91              :   ! Add a term to the potential
      92              :   !-------------------------------------------------------------------!
      93       531744 :   subroutine add_term(self, i,j, val)
      94              :     class(lattice_harmonic_potential_t), intent(inout) :: self
      95              :     integer, intent(in) :: i, j
      96              :     real(dp), intent(in) :: val
      97      1595232 :     call self%coeff%add_entry([i,j], val)
      98       531744 :   end subroutine add_term
      99              : 
     100              : 
     101              :   !-------------------------------------------------------------------!
     102              :   ! Set the reference energy.
     103              :   !-------------------------------------------------------------------!
     104            5 :   subroutine set_ref_energy(self, ref_energy)
     105              :     class(lattice_harmonic_potential_t), intent(inout) :: self
     106              :     real(dp), intent(in) :: ref_energy
     107            5 :     self%ref_energy=ref_energy
     108            5 :   end subroutine set_ref_energy
     109              : 
     110              :   !-------------------------------------------------------------------!
     111              :   ! set_supercell
     112              :   !  link the supercell with potential.
     113              :   ! Inputs:
     114              :   !   supercell: mbsupercell_t
     115              :   !-------------------------------------------------------------------!
     116           10 :   subroutine set_supercell(self, supercell)
     117              :     class(lattice_harmonic_potential_t), intent(inout) :: self
     118              :     type(mbsupercell_t), target, intent(inout) :: supercell
     119           10 :     self%supercell => supercell
     120           10 :   end subroutine set_supercell
     121              : 
     122              : 
     123              :   !-------------------------------------------------------------------!
     124              :   ! calculate force and energy from harmonic potential
     125              :   ! F= - IFC .matmul. displacement
     126              :   ! E = 1/2 (-F) .dot. displacement = 1/2<disp|IFC|disp>
     127              :   ! Input:
     128              :   !   displacement: required.
     129              :   !-------------------------------------------------------------------!
     130        12028 :   subroutine calculate(self, displacement, strain, spin, lwf, force, stress, bfield, lwf_force, energy, energy_table)
     131              :     ! This function calculate the energy and its first derivative
     132              :     ! the inputs and outputs are optional so that each effpot can adapt to its
     133              :     ! own.
     134              :     ! In principle, the 1st derivatives are only calculated if asked to (present). However, they can be computed if it is simply convinient to do.
     135              :     class(lattice_harmonic_potential_t), intent(inout) :: self  ! the effpot may save the states.
     136              : 
     137              :     real(dp), optional, intent(inout) :: displacement(:,:), strain(:,:), spin(:,:), lwf(:)
     138              :     real(dp), optional, intent(inout) :: force(:,:), stress(:,:), bfield(:,:), lwf_force(:), energy
     139              :     type(hash_table_t),optional, intent(inout) :: energy_table
     140              :     real(dp) :: etmp
     141        24056 :     real(dp) :: f(3,self%natom)
     142              :     ! if present in input
     143              :     ! calculate if required
     144        12028 :     ABI_UNUSED_A(strain)
     145        12028 :     ABI_UNUSED_A(spin)
     146        12028 :     ABI_UNUSED_A(lwf)
     147        12028 :     ABI_UNUSED_A(stress)
     148        12028 :     ABI_UNUSED_A(bfield)
     149        12028 :     ABI_UNUSED_A(lwf_force)
     150              : 
     151        12028 :     etmp=0.0_dp
     152              : 
     153        12028 :     call self%coeff%mv(displacement, f)
     154        12028 :     if (present(force)) then
     155     34610904 :        force(:,:) = force(:,:) - f
     156              :     endif
     157              : 
     158              :     !energy =energy + 0.5_dp * sum(f*displacement)
     159     51912188 :     etmp=0.5_dp * sum(f*displacement)
     160        12028 :     if (present(energy)) then
     161        12028 :        energy=energy+etmp
     162              :     endif
     163        12028 :     if(present(energy_table)) then
     164        12028 :        call energy_table%put(self%label, etmp)
     165              :     endif
     166        12028 :   end subroutine calculate
     167              : 
     168           15 : end module m_lattice_harmonic_potential
        

Generated by: LCOV version 2.3-1