LCOV - code coverage report
Current view: top level - src/78_effpot - m_linked_list.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 74.7 % 79 59
Test Date: 2026-09-21 22:40:37 Functions: 60.0 % 10 6

            Line data    Source code
       1              : !!****m* ABINIT/m_linked_list
       2              : !! NAME
       3              : !! m_linked_list
       4              : !!
       5              : !! FUNCTION
       6              : !! This module contains the a linked list for real(dp).
       7              : !! It is used to build the LIL (list of linked list) format of sparse matrix.
       8              : !!
       9              : !! Datatypes:
      10              : !!
      11              : !! * lnode: a node in the linked list, in each node, there is an integer and a real(dp)
      12              : !! * llist: linked list of lnode
      13              : !!
      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              : #include "abi_common.h"
      32              : 
      33              : module m_linked_list
      34              :   use defs_basis
      35              :   use m_errors
      36              :   use m_xmpi
      37              :   use m_profiling_abi
      38              :   implicit none
      39              : !!***
      40              : 
      41              :   ! node of linked list, which will be used as one non-zero entry in LIL matrix
      42              :   ! each node has an integer (i) and a real(dp) (val).
      43              :   ! That is because in a LIL sparse matrix, it saves the information of a
      44              :   ! column/row indices (int) and values (real)
      45              :   ! and the pointer points to the next node
      46              :   type, public:: lnode
      47              :      integer :: i
      48              :      real(dp):: val
      49              :      type(lnode), pointer :: next=>null()
      50              :   end type lnode
      51              : 
      52              :   ! linked list of (i, val), it can be a column or a row of LIL sparse matrix
      53              :   type, public:: llist
      54              :      type(lnode), pointer :: first=>null() ! pointer to first node
      55              :      type(lnode), pointer :: last=>null()  ! pointer to last node
      56              :      type(lnode), pointer :: iter=>null()  ! pointer to the current node (e.g. in a loop)
      57              :      integer :: length =0                  ! number of nodes
      58              :    contains
      59              :      procedure :: finalize=>llist_finalize      ! free memory
      60              :      procedure :: append => llist_append        ! add a new entry
      61              :      procedure :: iter_restart => llist_iter_restart
      62              :      procedure :: insert_after => llist_insert_after
      63              :      procedure :: insert_head => llist_insert_head
      64              :      procedure :: sorted_insert => llist_sorted_insert
      65              :      procedure :: get_data => llist_get_data
      66              :   end type llist
      67              : 
      68              :   contains
      69              : 
      70              :     !----------------------------------------------------------------------
      71              :     !> @brief finalize: free memory
      72              :     !----------------------------------------------------------------------
      73         1296 :   recursive subroutine llist_finalize(self)
      74              :     class(llist), intent(inout) ::self
      75              :     type(lnode), pointer :: iter, tmp
      76         1296 :     iter=>self%first
      77        34992 :     do while(associated(iter))
      78        33696 :        tmp=>iter
      79        33696 :        iter=>iter%next
      80         1296 :        if( associated(tmp)) then
      81        33696 :           ABI_FREE_SCALAR(tmp)
      82              :        endif
      83              :     enddo
      84         1296 :     nullify(self%first)
      85         1296 :     nullify(self%last)
      86         1296 :     self%length=0
      87         1296 :   end subroutine llist_finalize
      88              : 
      89              :   !----------------------------------------------------------------------
      90              :   !> @brief append to the end of the list
      91              :   !> @param[in]  i: int
      92              :   !> @param[in]  val: real value
      93              :   !----------------------------------------------------------------------
      94        19500 :   subroutine llist_append(self, i, val)
      95              :     ! append a element at the end of list
      96              :     class(llist), intent(inout) ::self
      97              :     integer, intent(in)::i
      98              :     real(dp), intent(in)::val
      99        19500 :     if(.not. associated(self%last)) then
     100         1296 :        ABI_MALLOC_SCALAR(self%first)
     101         1296 :        self%last=>self%first
     102              :     else
     103        18204 :        ABI_MALLOC_SCALAR(self%last%next)
     104        18204 :        self%last=>self%last%next
     105              :     endif
     106        19500 :     self%last%i=i
     107        19500 :     self%last%val=val
     108        19500 :     self%last%next=>null()
     109        19500 :     self%length = self%length+1
     110        19500 :   end subroutine llist_append
     111              : 
     112              :   !----------------------------------------------------------------------
     113              :   !> @brief restart the iteration. set iter to first node
     114              :   !----------------------------------------------------------------------
     115        34992 :   subroutine llist_iter_restart(self)
     116              :     class(llist):: self
     117        34992 :     self%iter=>self%first
     118         1296 :   end subroutine llist_iter_restart
     119              : 
     120              :   !----------------------------------------------------------------------
     121              :   !> @brief insert to the node after one node ptr
     122              :   !>
     123              :   !> @param[in] ptr: a pointer to a node in the list
     124              :   !> @param[in] i: the integer
     125              :   !> @param[in] val: the real value
     126              :   !----------------------------------------------------------------------
     127        12420 :   subroutine llist_insert_after(self, ptr, i, val)
     128              :     !insert a element so i is sorted.
     129              :     ! if mode=0: if i already exist, substitute i, val
     130              :     ! if mode=1: val+=val
     131              :     class(llist):: self
     132              :     integer, intent(in) :: i
     133              :     real(dp), intent(in):: val
     134              :     type(lnode), pointer, intent(in):: ptr
     135              :     type(lnode), pointer:: tmp=>null()
     136        12420 :     if(.not.associated(ptr%next)) then
     137            0 :        call llist_append(self,i,val)
     138              :     else
     139        12420 :        ABI_MALLOC_SCALAR(tmp)
     140        12420 :        tmp%i=i
     141        12420 :        tmp%val=val
     142        12420 :        tmp%next=>ptr%next
     143        12420 :        ptr%next=>tmp
     144        12420 :        self%length=self%length+1
     145              :     endif
     146        12420 :   end subroutine llist_insert_after
     147              : 
     148              : !----------------------------------------------------------------------
     149              :   !> @brief inset to the head of the list
     150              :   !>
     151              :   !> @param[in]  i
     152              :   !> @param[in] val
     153              :   !----------------------------------------------------------------------
     154         1776 :   subroutine llist_insert_head(self, i, val)
     155              :     class(llist):: self
     156              :     integer, intent(in) :: i
     157              :     real(dp), intent(in):: val
     158              :     type(lnode), pointer:: tmp=>null()
     159         1776 :     ABI_MALLOC_SCALAR(tmp)
     160         1776 :     tmp%i=i
     161         1776 :     tmp%val=val
     162         1776 :     tmp%next=>self%first
     163         1776 :     self%first=>tmp
     164         1776 :     if (self%length==0) then
     165            0 :        self%last=>tmp
     166              :     endif
     167         1776 :     self%length=self%length+1
     168         1776 :   end subroutine llist_insert_head
     169              : 
     170              :   !----------------------------------------------------------------------
     171              :   !> @brief insert to a node so that the list is sorted by i
     172              :   !>
     173              :   !> @param[in]  i :  integer value
     174              :   !> @param[in]  val : real value
     175              :   !> @param[in]  mode :
     176              :   !> if mode=0: if i already exist, substitute i, val
     177              :   !> if mode=1: val+=val
     178              :   !----------------------------------------------------------------------
     179        33696 :   subroutine llist_sorted_insert(self, i, val, mode)
     180              :     !insert a element so i is sorted.
     181              :     class(llist):: self
     182              :     integer, intent(in) :: i, mode
     183              :     real(dp), intent(in):: val
     184        33696 :     call llist_iter_restart(self)
     185        33696 :     if(.not.associated(self%last)) then
     186         1296 :        call llist_append(self,i,val)
     187        32400 :     else if (i<self%first%i) then
     188         1776 :        call llist_insert_head(self, i, val)
     189              :     else
     190       343932 :        do while(associated(self%iter))
     191              :           ! at the begining i<i0
     192              :           ! before the end,
     193       325728 :           if (i>self%iter%i) then
     194       325728 :              if (associated(self%iter%next)) then
     195       307524 :                  if (i<self%iter%next%i) then
     196        12420 :                     call llist_insert_after(self,self%iter,i,val)
     197        12420 :                     return
     198              :                  end if
     199              :              end if
     200            0 :           else if(i==self%iter%i) then
     201              :              ! i<i0 or i>i
     202            0 :              if(mode==0) then
     203            0 :                 self%iter%val=val
     204            0 :              else if(mode==1) then
     205            0 :                 self%iter%val=self%iter%val+val
     206              :              endif
     207            0 :              return
     208              :           endif
     209       313308 :           self%iter=>self%iter%next
     210              :        enddo
     211              :        ! i>last i
     212        18204 :        if(i>self%last%i) then
     213        18204 :           call llist_append(self,i,val)
     214        18204 :           return
     215              :        else
     216            0 :           ABI_BUG("m_linked_list cannot find proper place to insert")
     217              :        endif
     218              :     endif
     219              : 
     220              : 
     221              :   end subroutine llist_sorted_insert
     222              : 
     223              : 
     224              :   !----------------------------------------------------------------------
     225              :   !> @brief get all the data to arrays of i and val
     226              :   !> @param[out]  ilist: the array of i
     227              :   !> @param[out]  vallist: the array of val
     228              :   !----------------------------------------------------------------------
     229            0 :   subroutine llist_get_data(self, ilist, vallist)
     230              : 
     231              :     class(llist), intent(inout)::self
     232              :     integer, allocatable, intent(inout)::ilist(:)
     233              :     real(dp),allocatable, intent(inout)::vallist(:)
     234              :     integer::ind=1
     235            0 :     ABI_MALLOC(ilist,(self%length))
     236            0 :     ABI_MALLOC(vallist, (self%length))
     237            0 :     call llist_iter_restart(self)
     238            0 :     do while(associated(self%iter))
     239            0 :        ilist(ind)=self%iter%i
     240            0 :        vallist(ind)=self%iter%val
     241            0 :        self%iter=>self%iter%next
     242            0 :        ind=ind+1
     243              :     enddo
     244            0 :   end subroutine llist_get_data
     245              : 
     246            0 : end module m_linked_list
        

Generated by: LCOV version 2.3-1