LCOV - code coverage report
Current view: top level - src/78_effpot - m_abstract_potential.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 20.0 % 45 9
Test Date: 2026-09-21 13:49:52 Functions: 28.6 % 7 2

            Line data    Source code
       1              : !!****m* ABINIT/m_abstract_potential
       2              : !! NAME
       3              : !! m_abstract_potential
       4              : !!
       5              : !! FUNCTION
       6              : !! This module contains the base type for all effective potentials.
       7              : !!
       8              : !!
       9              : !! Datatypes:
      10              : !!
      11              : !! * abstract_potential_t: defines the base api of effective potentials.
      12              : !! * potential_list_t: list of abstract_potential_t, which is essentially a list of pointer to abstract_potential_t
      13              : !!    itself is also a effpot type, and its energy, 1st derivative to energy are the sum of all items.
      14              : !! Subroutines:
      15              : !! TODO: add this when F2003 doc style is determined.
      16              : !!
      17              : !!
      18              : !! COPYRIGHT
      19              : !! Copyright (C) 2001-2026 ABINIT group (hexu)
      20              : !! This file is distributed under the terms of the
      21              : !! GNU General Public License, see ~abinit/COPYING
      22              : !! or http://www.gnu.org/copyleft/gpl.txt .
      23              : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
      24              : !!
      25              : !! SOURCE
      26              : 
      27              : 
      28              : #if defined HAVE_CONFIG_H
      29              : #include "config.h"
      30              : #endif
      31              : 
      32              : #include "abi_common.h"
      33              : 
      34              : module m_abstract_potential
      35              :   use defs_basis
      36              :   use m_abicore
      37              :   use m_errors
      38              :   use m_xmpi
      39              : 
      40              :   use m_multibinit_dataset, only: multibinit_dtset_type
      41              :   use m_multibinit_cell, only: mbcell_t, mbsupercell_t
      42              :   use m_hashtable_strval, only: hash_table_t
      43              : 
      44              :   implicit none
      45              : !!***
      46              :   private
      47              : 
      48              : 
      49              :   type ,public :: abstract_potential_t
      50              :      ! This is the abstract class of effective potential.
      51              :      ! It do the following things:
      52              :      ! calculate 0th, 1st,... derivative of energy related, e.g. Force for lattice model
      53              :      ! labels for variables. If a new degree of freedom is to be added, a label
      54              :      ! should be added here.
      55              :      logical :: has_displacement=.False.
      56              :      logical :: has_strain=.False.
      57              :      logical :: has_spin=.False.
      58              :      logical :: has_lwf = .False.
      59              :      logical :: is_null=.True.   ! if is_null, this term does not exist.
      60              :      ! it is important to set it to True before initialization.
      61              :      ! Because it is used as the tag for deallocatign memory.
      62              :      type(mbsupercell_t) ,pointer :: supercell => null()
      63              :      ! every supercell potential has a pointer to the supercell,
      64              :      ! which could be used for like reference structure.
      65              :      character (len=200) :: label="Abstract Potential"  !
      66              :      ! the label is used for printing information.
      67              :    contains
      68              :      procedure :: set_supercell   ! set_supercell
      69              :      procedure :: finalize        ! finalize
      70              :      procedure :: set_params      ! parameters from input file
      71              :      procedure :: calculate       ! get energy and 1st derivative from input state
      72              :      procedure :: get_delta_E     ! calculate energy diffence if one component is changed for Monte carlo algorithm
      73              :      procedure :: get_delta_E_lwf     ! calculate energy diffence if one component is changed for Monte carlo algorithm
      74              :   end type abstract_potential_t
      75              : 
      76              : contains
      77              : 
      78              :   !----------------------------------------------------------------------
      79              :   !> @brief link a supercell to the potential
      80              :   !>
      81              :   !> @param[in]  supercell: supercell object
      82              :   !----------------------------------------------------------------------
      83            0 :   subroutine set_supercell(self, supercell)
      84              :     class(abstract_potential_t), intent(inout) :: self
      85              :     type(mbsupercell_t), target, intent(inout) :: supercell
      86            0 :     ABI_UNUSED_A(self)
      87            0 :     ABI_UNUSED_A(supercell)
      88            0 :     ABI_ERROR("Every potential should override this set_supercell method to avoid mistake.")
      89            0 :   end subroutine set_supercell
      90              : 
      91              :   !----------------------------------------------------------------------
      92              :   !> @brief finalize
      93              :   !>
      94              :   !----------------------------------------------------------------------
      95            6 :   subroutine finalize(self)
      96              :     class(abstract_potential_t), intent(inout) :: self
      97            6 :     self%is_null=.True.
      98            6 :     nullify(self%supercell)
      99            6 :     self%label="Destroyed potential"
     100            6 :   end subroutine finalize
     101              : 
     102              :   !----------------------------------------------------------------------
     103              :   !> @brief set_params: set the parameters from input file parameters
     104              :   !>
     105              :   !> @param[in]  params: multibinit_dtset_type: from input file
     106              :   !----------------------------------------------------------------------
     107            5 :   subroutine set_params(self, params)
     108              :     class(abstract_potential_t), intent(inout) :: self
     109              :     type(multibinit_dtset_type), intent(inout) :: params
     110            5 :     ABI_UNUSED_A(self)
     111            5 :     ABI_UNUSED_A(params)
     112              :     ! The default behavior is do nothing
     113            5 :   end subroutine set_params
     114              : 
     115              :   ! hexu comment : which one is better, more general variables,
     116              :   !  or one function for each type of var?
     117              :   !subroutine set_variables(self, displacements, strain, spin)
     118              :   !  class(lattice_api_t), intent(inout) :: self
     119              :   !  real(dp), optional, intent(in) :: displacements(:,:), strain(:,:), spin(:,:)
     120              :   !end subroutine set_variables
     121              : 
     122              :   !subroutine get_1st_deriv(self, force, stress, bfield)
     123              :   !  class(lattice_api_t), intent(inout) :: self
     124              :   !  real(dp), optional, intent(out) :: force(:,:), stress(:,:), bfield(:,:)
     125              :   !end subroutine get_1st_deriv
     126              : 
     127              :   ! subroutine set_distortion(self, displacement, strain)
     128              :   !   class(abstract_potential_t), intent(inout) :: self
     129              :   !   real(dp), optional, intent(in) :: displacement(:,:), strain(:,:)
     130              :   !   ABI_ERROR("set_distortion not implemented.")
     131              :   ! end subroutine set_distortion
     132              : 
     133              :   ! subroutine set_spin(self, spin)
     134              :   !   class(abstract_potential_t), intent(inout) :: self
     135              :   !   real(dp), optional, intent(in) :: spin
     136              :   !   ABI_ERROR("set_spin not implemented.")
     137              :   ! end subroutine set_spin
     138              : 
     139              :   !----------------------------------------------------------------------
     140              :   !> @brief calculate energy and derivatives with given state.
     141              :   !> This function calculate the energy and its first derivative
     142              :   !> the inputs and outputs are optional so that each effpot can adapt to its
     143              :   !> own.
     144              :   !> In principle, the 1st derivatives are only calculated if
     145              :   !> asked to (present).
     146              :   !> However, they can be computed if it is simply convinient to do.
     147              :   !> @param[in]  displacement (optional)
     148              :   !> @param[in]  strain (optional)
     149              :   !> @param[in]  spin (optional)
     150              :   !> @param[in]  lwf (optional)
     151              :   !> @param[out] force (optional)
     152              :   !> @param[out] stress (optional)
     153              :   !> @param[out] bfield (optional)
     154              :   !> @param[out] energy_table (optional)
     155              :   !----------------------------------------------------------------------
     156            0 :   subroutine calculate(self, displacement, strain, spin, lwf, force, stress, bfield, lwf_force, &
     157              :        & energy, energy_table)
     158              :       class(abstract_potential_t), intent(inout) :: self  ! the effpot may save the states.
     159              : 
     160              :     real(dp), optional, intent(inout) :: displacement(:,:), strain(:,:), spin(:,:), lwf(:)
     161              :     real(dp), optional, intent(inout) :: force(:,:), stress(:,:), bfield(:,:), lwf_force(:), energy
     162              :     type(hash_table_t),optional, intent(inout) :: energy_table
     163              :     ! if present in input
     164              :     ! calculate if required
     165            0 :     ABI_UNUSED_A(self)
     166            0 :     ABI_UNUSED_A(displacement)
     167            0 :     ABI_UNUSED_A(strain)
     168            0 :     ABI_UNUSED_A(spin)
     169            0 :     ABI_UNUSED_A(lwf)
     170            0 :     ABI_UNUSED_A(force)
     171            0 :     ABI_UNUSED_A(stress)
     172            0 :     ABI_UNUSED_A(bfield)
     173            0 :     ABI_UNUSED_A(lwf_force)
     174            0 :     ABI_UNUSED_A(energy)
     175            0 :     ABI_UNUSED_A(energy_table)
     176            0 :     ABI_ERROR("calculate not implemented for this effpot.")
     177            0 :   end subroutine calculate
     178              : 
     179              :   !----------------------------------------------------------------------
     180              :   !> @brief get_delta_E: calculate the energy difference when a given spin
     181              :   !> is changed. This is to be used for spin Monte Carlo. Currently the
     182              :   !> only supported is the spin model.
     183              :   !>
     184              :   !> @param[in]  S: spin of full structure. array of (3, nspin)
     185              :   !> @param[in]  ispin: the index of spin changed. integer
     186              :   !> @param[in]  snew: the new value of the changed spin.
     187              :   !> @param[out] deltaE: the energy difference
     188              :   !----------------------------------------------------------------------
     189            0 :   subroutine get_delta_E(self, S, ispin, Snew, deltaE)
     190              :     ! for spin monte carlo
     191              :     ! calculate energy difference if one spin is moved.
     192              :     class(abstract_potential_t), intent(inout) :: self  ! the effpot may save the states.
     193              :     real(dp),  intent(inout) :: S(:,:),  Snew(:)
     194              :     integer,  intent(in) :: ispin
     195              :     real(dp), intent(inout) :: deltaE
     196            0 :     ABI_UNUSED_A(self)
     197            0 :     ABI_UNUSED_A(S)
     198            0 :     ABI_UNUSED_A(ispin)
     199            0 :     ABI_UNUSED_A(Snew)
     200            0 :     ABI_UNUSED_A(deltaE)
     201            0 :     ABI_ERROR("get_delta_E not implemented for this effpot.")
     202            0 :   end subroutine get_delta_E
     203              : 
     204              :   !----------------------------------------------------------------------
     205              :   !> @brief get_delta_E_lwf: calculate the energy difference when a given lwf
     206              :   !> is changed. This is to be used for spin Monte Carlo. Currently the
     207              :   !> only supported is the spin model.
     208              :   !>
     209              :   !> @param[in]  lwf: lwf of full structure. array of (nlwf)
     210              :   !> @param[in]  ilwf: the index of spin changed. integer
     211              :   !> @param[in]  lwf_new: the new value of the changed spin.
     212              :   !> @param[out] deltaE: the energy difference
     213              :   !----------------------------------------------------------------------
     214            0 :   subroutine get_delta_E_lwf(self, lwf, ilwf, lwf_new, deltaE)
     215              :     ! for spin monte carlo
     216              :     ! calculate energy difference if one spin is moved.
     217              :     class(abstract_potential_t), intent(inout) :: self  ! the effpot may save the states.
     218              :     real(dp),  intent(inout) :: lwf(:),  lwf_new
     219              :     integer,  intent(in) :: ilwf
     220              :     real(dp), intent(inout) :: deltaE
     221            0 :     ABI_UNUSED_A(self)
     222            0 :     ABI_UNUSED_A(lwf)
     223            0 :     ABI_UNUSED_A(ilwf)
     224            0 :     ABI_UNUSED_A(lwf_new)
     225            0 :     ABI_UNUSED_A(deltaE)
     226            0 :     ABI_ERROR("get_delta_E_lwf not implemented for this effpot."//self%label)
     227            0 :   end subroutine get_delta_E_lwf
     228              : 
     229              : 
     230              : 
     231              : !   subroutine get_energy(self, energy)
     232              : !     class(abstract_potential_t), intent(inout) :: self
     233              : !     real(dp) , intent(inout) :: energy
     234              : !   end subroutine get_energy
     235              : 
     236              : 
     237              : !   subroutine get_force(self, force)
     238              : !     class(abstract_potential_t), intent(inout) :: self
     239              : !     real(dp), intent(out) :: force(:,:)
     240              : !   end subroutine get_force
     241              : 
     242              : !   subroutine get_stress(self, stress)
     243              : !     class(abstract_potential_t), intent(inout) :: self
     244              : !     real(dp), intent(out) :: stress(:,:)
     245              : !   end subroutine get_stress
     246              : 
     247              : !   subroutine get_effective_Bfield(self, spin,bfield)
     248              : !     class(abstract_potential_t), intent(in) :: self
     249              : !     real(dp), intent(in) :: spin(:,:)
     250              : !     real(dp), intent(inout) :: bfield(:,:)
     251              : !   end subroutine get_effective_Bfield
     252              : 
     253            0 : end module m_abstract_potential
        

Generated by: LCOV version 2.3-1