LCOV - code coverage report
Current view: top level - src/78_effpot - m_dynarray.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 51.1 % 186 95
Test Date: 2026-11-06 14:42:53 Functions: 37.9 % 29 11
Branches: 37.2 % 312 116

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_dynarray
       2                 :             : !!
       3                 :             : !! NAME
       4                 :             : !! m_dynarray
       5                 :             : !!
       6                 :             : !! FUNCTION
       7                 :             : !! Module for int and real(dp) array which allocate memory dynamically
       8                 :             : !! real_array_type for real(dp) and int_array_type for integer.
       9                 :             : !! they have push (but no pop) and finalize methods.
      10                 :             : !! TODO hexu: Is this already implemented somewhere in abinit.
      11                 :             : !! If not, should this file be moved to the place to make it more general usable?
      12                 :             : !!
      13                 :             : !! MG: Yes, this module should be moved to a lower level directory so that one can reuse it in other
      14                 :             : !! parts of the code.
      15                 :             : !!
      16                 :             : !!
      17                 :             : !! COPYRIGHT
      18                 :             : !! Copyright (C) 2010-2026 ABINIT group (hexu)
      19                 :             : !! This file is distributed under the terms of the
      20                 :             : !! GNU General Public Licence, see ~abinit/COPYING
      21                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
      22                 :             : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
      23                 :             : !!
      24                 :             : !! SOURCE
      25                 :             : 
      26                 :             : 
      27                 :             : #if defined HAVE_CONFIG_H
      28                 :             : #include "config.h"
      29                 :             : #endif
      30                 :             : #include "abi_common.h"
      31                 :             : 
      32                 :             : module m_dynamic_array
      33                 :             :   use defs_basis
      34                 :             :   use m_abicore
      35                 :             :   use m_errors
      36                 :             :   use m_mathfuncs, only: array_morethan, binsearch_left_integerlist,binsearch_left_integer
      37                 :             :   use m_mergesort, only: MergeSort, MergeSort2D
      38                 :             :   use m_xmpi, only: xmpi_sum, xmpi_allgather, xmpi_allgatherv
      39                 :             :   implicit none
      40                 :             :   private
      41                 :             : !!***
      42                 :             : 
      43                 :             : !!****t* m_dynarray/real_array_type
      44                 :             : !! NAME
      45                 :             : !! real_array_type
      46                 :             : !!
      47                 :             : !! FUNCTION
      48                 :             : !! datatype of real(dp) array which can be dynamically allocated
      49                 :             : !!
      50                 :             : !! SOURCE
      51                 :             :   type, public:: real_array_type
      52                 :             :     integer:: size=0, capacity=0
      53                 :             :     real(dp), allocatable :: data(:)
      54                 :             :   CONTAINS
      55                 :             :     procedure :: push => real_array_type_push
      56                 :             :     procedure :: sort => real_array_type_sort
      57                 :             :     procedure :: from_static => real_array_type_from_static
      58                 :             :     procedure :: allgatherv => real_array_type_allgatherv
      59                 :             :     procedure :: finalize => real_array_type_finalize
      60                 :             :   end type real_array_type
      61                 :             : 
      62                 :             : 
      63                 :             : !!***
      64                 :             : 
      65                 :             : !!****t* m_dynarray/int_array_type
      66                 :             : !! NAME
      67                 :             : !! int_array_type
      68                 :             : !!
      69                 :             : !! FUNCTION
      70                 :             : !! datatype of real(dp) array which can be dynamically allocated
      71                 :             : !!
      72                 :             : !! SOURCE
      73                 :             :   type , public::int_array_type
      74                 :             :     integer:: size=0, capacity=0
      75                 :             :     integer, allocatable :: data(:)
      76                 :             :   CONTAINS
      77                 :             :     procedure :: push => int_array_type_push
      78                 :             :     procedure :: concate => int_array_type_concate
      79                 :             :     procedure :: finalize => int_array_type_finalize
      80                 :             :     procedure :: sort => int_array_type_sort
      81                 :             :     procedure :: tostatic => int_array_type_tostatic
      82                 :             :     procedure :: allgatherv => int_array_type_allgatherv
      83                 :             :   end type int_array_type
      84                 :             : !!***
      85                 :             : 
      86                 :             :   !!****t* defs_abitypes/int2d_array_type
      87                 :             :   !! NAME
      88                 :             :   !! int2d_array_type
      89                 :             :   !!
      90                 :             :   !! FUNCTION
      91                 :             :   !! datatype of integer array which the dim=2 can be dynamically allocated
      92                 :             :   !!
      93                 :             :   !! SOURCE
      94                 :             :   type , public::int2d_array_type
      95                 :             :      integer:: size=0, capacity=0, size1=-1
      96                 :             :      logical :: sorted=.False.
      97                 :             :      integer, allocatable :: data(:,:)
      98                 :             :    CONTAINS
      99                 :             :      procedure :: push => int2d_array_type_push
     100                 :             :      procedure :: concate => int2d_array_type_concate
     101                 :             :      procedure :: tostatic => int2d_array_type_tostatic
     102                 :             :      procedure :: push_unique => int2d_array_type_push_unique
     103                 :             :      procedure :: sort => int2d_array_type_sort
     104                 :             :      procedure :: binsearch =>int2d_array_type_binsearch
     105                 :             :      procedure :: finalize => int2d_array_type_finalize
     106                 :             :   end type int2d_array_type
     107                 :             :   !!***
     108                 :             : 
     109                 :             :   !public :: mpi_gather_int_array
     110                 :             :   public::  dynamic_array_unittest
     111                 :             : CONTAINS
     112                 :             : 
     113                 :             : !  subroutine merge_int_array(x1, x2, y)
     114                 :             : !    class(int_array_type), intent(in) :: x
     115                 :             : !    class(int_array_type),  :: y
     116                 :             : 
     117                 :             : !  end subroutine gather_int_array
     118                 :             : 
     119                 :             :   !subroutine mpi_gather_int_array(a, comm, y, ny)
     120                 :             :   !  class(int_array_type) :: a
     121                 :             :   !  integer :: comm
     122                 :             :   !  integer, allocatable, intent(out) :: y(:, :)
     123                 :             :   !  integer, intent(out) :: ny
     124                 :             :   !end subroutine mpi_gather_int_array
     125                 :             : 
     126                 :             : 
     127                 :             : 
     128                 :             : 
     129                 :             : !****f* m_dynarray/real_array_type_push
     130                 :             : !!
     131                 :             : !! NAME
     132                 :             : !! real_array_type_push
     133                 :             : !!
     134                 :             : !! FUNCTION
     135                 :             : !! push data to a real_array_type
     136                 :             : !!
     137                 :             : !! INPUTS
     138                 :             : !! self = real_array_type object
     139                 :             : !! val= data to be pushed
     140                 :             : !! OUTPUT
     141                 :             : !! real_array<type(real_array_type)()> = real_array_type data
     142                 :             : !! SOURCE
     143                 :     2553449 : subroutine real_array_type_push(self, val)
     144                 :             : 
     145                 :             :     class(real_array_type), intent(inout):: self
     146                 :             :     real(dp) :: val
     147                 :     2553449 :     real(dp), allocatable :: temp(:)
     148                 :     2553449 :     self%size=self%size+1
     149         [ +  + ]:     2553449 :     if(self%size==1) then
     150                 :          25 :       self%capacity=8
     151   [ -  +  -  + ]:          25 :       ABI_MALLOC(self%data, (self%capacity))
     152         [ +  + ]:     2553424 :     else if ( self%size>self%capacity ) then
     153                 :         603 :       self%capacity = self%size + self%size / 4 + 8
     154   [ -  +  +  -  :        1809 :       ABI_MALLOC(temp, (self%capacity))
          +  -  +  -  -  
                +  -  + ]
     155         [ +  + ]:    12015622 :       temp(:self%size-1) = self%data
     156         [ +  - ]:         603 :       ABI_MOVE_ALLOC(temp, self%data)
     157                 :             :     end if
     158                 :     2553449 :     self%data(self%size)=val
     159                 :             : 
     160                 :     2553449 : end subroutine real_array_type_push
     161                 :             : !!***
     162                 :             : 
     163                 :             : subroutine int_array_type_from_static(self, A)
     164                 :             :   class(int_array_type), intent(inout):: self
     165                 :             :   integer, intent(in) :: A(:)
     166                 :             :   integer :: n
     167                 :             :   n=size(A)
     168                 :             :   self%size=n
     169                 :             :   self%capacity=n
     170                 :             :   ABI_MALLOC(self%data, (n))
     171                 :             :   self%data(:) = A
     172                 :             : end subroutine int_array_type_from_static
     173                 :             : 
     174         [ #  # ]:           0 : subroutine real_array_type_from_static(self, A)
     175                 :             :   class(real_array_type), intent(inout):: self
     176                 :             :   real(dp), intent(in) :: A(:)
     177                 :             :   integer :: n
     178                 :           0 :   n=size(A)
     179                 :           0 :   self%size=n
     180                 :           0 :   self%capacity=n
     181   [ #  #  #  #  :           0 :   ABI_MALLOC(self%data, (n))
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     182         [ #  # ]:           0 :   self%data(:) = A
     183                 :           0 : end subroutine real_array_type_from_static
     184                 :             : 
     185                 :           0 : subroutine real_array_type_sort(self, order)
     186                 :             :   class(real_array_type), intent(inout):: self
     187                 :           0 :   real(dp):: work((self%size+1)/2)
     188                 :             :   integer, optional, intent(inout):: order(self%size)
     189                 :           0 :   integer :: work_order((self%size+1)/2)
     190                 :           0 :   call MergeSort(self%data(:self%size), work, order, work_order)
     191                 :           0 : end subroutine real_array_type_sort
     192                 :             : 
     193                 :           0 : subroutine real_array_type_allgatherv(self,buff, comm, nproc)
     194                 :             :   class(real_array_type), intent(inout):: self
     195                 :             :   integer, intent(in) :: comm, nproc
     196                 :             :   real(dp), allocatable, intent(out) :: buff(:)
     197                 :             :   real(dp), allocatable :: tmp(:)
     198                 :           0 :   integer :: disps(nproc), sizes(nproc)
     199                 :             :   integer :: totsize, ierr, i
     200                 :           0 :   totsize=self%size
     201                 :           0 :   call xmpi_sum(totsize, comm, ierr)
     202   [ #  #  #  #  :           0 :   ABI_MALLOC(buff, (totsize))
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     203                 :           0 :   call xmpi_allgather(self%size, sizes, comm, ierr)
     204                 :           0 :   disps(1)=0
     205         [ #  # ]:           0 :   do i=2, nproc
     206                 :           0 :     disps(i)=disps(i-1)+sizes(i-1)
     207                 :             :   end do
     208   [ #  #  #  #  :           0 :   ABI_MALLOC(tmp, (self%size))
          #  #  #  #  #  
                #  #  # ]
     209         [ #  # ]:           0 :   if(self%size>0) then
     210         [ #  # ]:           0 :     tmp(:)=self%data(:self%size)
     211                 :             :   end if
     212                 :           0 :   call xmpi_allgatherv(tmp, self%size, buff, sizes, disps, comm, ierr  )
     213         [ #  # ]:           0 :   ABI_FREE(tmp)
     214                 :           0 : end subroutine real_array_type_allgatherv
     215                 :             : 
     216                 :             : 
     217                 :             : 
     218                 :             : !****f* m_disarray/real_array_type_finalize
     219                 :             : !!
     220                 :             : !! NAME
     221                 :             : !! real_array_type_finalize
     222                 :             : !!
     223                 :             : !! FUNCTION
     224                 :             : !! destroy real_array_type
     225                 :             : !!
     226                 :             : !! INPUTS
     227                 :             : !! self= real_array_type object
     228                 :             : !! OUTPUT
     229                 :             : !! real_array<type(real_array_type)()> = real_array_type data
     230                 :             : !! SOURCE
     231                 :          38 : subroutine real_array_type_finalize(self)
     232                 :             : 
     233                 :             :   class(real_array_type), intent(inout):: self
     234         [ +  + ]:          38 :   ABI_SFREE(self%data)
     235                 :          38 :   self%size=0
     236                 :          38 :   self%capacity=0
     237                 :             : 
     238                 :          38 : end subroutine real_array_type_finalize
     239                 :             : !!***
     240                 :             : 
     241                 :             : !****f* m_dynarray/int_array_type_push
     242                 :             : !!
     243                 :             : !! NAME
     244                 :             : !! int_array_type_push
     245                 :             : !!
     246                 :             : !! FUNCTION
     247                 :             : !! push data to a int_array_type
     248                 :             : !!
     249                 :             : !! INPUTS
     250                 :             : !! self = int_array_type object
     251                 :             : !! val= data to be pushed
     252                 :             : !! OUTPUT
     253                 :             : !! int_array<type(real_array_type)()> = int_array_type data
     254                 :             : !! SOURCE
     255                 :       28015 : subroutine int_array_type_push(self, val)
     256                 :             : 
     257                 :             :     class(int_array_type), intent(inout):: self
     258                 :             :     integer :: val
     259                 :       28015 :     integer, allocatable :: temp(:)
     260                 :       28015 :     self%size=self%size+1
     261         [ +  + ]:       28015 :     if(self%size==1) then
     262                 :          27 :       self%capacity=8
     263   [ -  +  -  + ]:          27 :       ABI_MALLOC(self%data, (self%capacity))
     264         [ +  + ]:       27988 :     else if ( self%size>self%capacity ) then
     265                 :         208 :       self%capacity = self%size + self%size / 4 + 8
     266   [ -  +  +  -  :         624 :       ABI_MALLOC(temp, (self%capacity))
          +  -  +  -  -  
                +  -  + ]
     267         [ +  + ]:      127026 :       temp(:self%size-1) = self%data
     268                 :             :       !temp gets deallocated
     269         [ +  - ]:         208 :       ABI_MOVE_ALLOC(temp, self%data)
     270                 :             :     end if
     271                 :       28015 :     self%data(self%size)=val
     272                 :             : 
     273                 :       28015 : end subroutine int_array_type_push
     274                 :             : !!***
     275                 :             : 
     276                 :             : 
     277                 :             : !----------------------------------------------------------------------
     278                 :             : !> @brief insertion_sort_int: sort a array using insertion sort algorithm
     279                 :             : !>  it is a memory safe method but is generally slow.
     280                 :             : !> @param[inout]  a: the array to be sorted. and will output inplace
     281                 :             : !> @param[inout] order (optional) the sorted index, it can be used to sort
     282                 :             : !>  other arrays so that the order in consistent.
     283                 :             : !----------------------------------------------------------------------
     284         [ #  # ]:           0 : subroutine insertion_sort_int(a, order)
     285                 :             :   integer, intent(inout) :: a(:)
     286                 :             :   integer, optional, intent(inout):: order(size(a))
     287                 :             :   integer :: n,i,j, v
     288                 :           0 :   n=size(a)
     289         [ #  # ]:           0 :   if (present(order)) then
     290         [ #  # ]:           0 :      do i = 1,n
     291                 :           0 :         order(i)=i
     292                 :             :      end do
     293                 :             :   end if
     294         [ #  # ]:           0 :   do i = 2,n
     295                 :           0 :      v=a(i)
     296                 :           0 :      j=i-1
     297         [ #  # ]:           0 :      do while(j>=1 )
     298         [ #  # ]:           0 :         if (a(j)<=v) exit
     299                 :           0 :         a(j+1)=a(j)
     300         [ #  # ]:           0 :         if(present(order)) order(j+1)=order(j)
     301                 :           0 :         j=j-1
     302                 :             :      end do
     303                 :           0 :      a(j+1)=v
     304         [ #  # ]:           0 :      if(present(order)) order(j+1)=i
     305                 :             :   end do
     306                 :             : 
     307         [ #  # ]:           0 : end subroutine insertion_sort_int
     308                 :             : 
     309                 :             : !----------------------------------------------------------------------
     310                 :             : !> @brief int_array_type_insertion_sort: sort a DYNAMIC INT array using insertion sort algorithm
     311                 :             : !>  it is a memory safe method but is generally slow.
     312                 :             : !> @param[inout]  a: an dynamic array. the array to be sorted. and will output inplace
     313                 :             : !> @param[inout] order (optional) the sorted index, it can be used to sort
     314                 :             : !>  other arrays so that the order in consistent.
     315                 :             : !----------------------------------------------------------------------
     316                 :             : subroutine int_array_type_insertion_sort(self, order)
     317                 :             :   class(int_array_type), intent(inout):: self
     318                 :             :   integer, optional, intent(inout):: order(self%size)
     319                 :             :   integer :: i,j, v
     320                 :             :   if (present(order)) then
     321                 :             :      do i = 1, self%size
     322                 :             :         order(i)=i
     323                 :             :      end do
     324                 :             :   end if
     325                 :             :   do i = 2, self%size
     326                 :             :      v=self%data(i)
     327                 :             :      j=i-1
     328                 :             :      do while(j>=1 )
     329                 :             :         if(.not. self%data(j)>v) exit
     330                 :             :         self%data(j+1)=self%data(j)
     331                 :             :         if(present(order)) order(j+1)=order(j)
     332                 :             :         j=j-1
     333                 :             :      end do
     334                 :             :      self%data(j+1)=v
     335                 :             :      if(present(order)) order(j+1)=i
     336                 :             :   end do
     337                 :             : end subroutine int_array_type_insertion_sort
     338                 :             : 
     339                 :             : 
     340                 :             : !----------------------------------------------------------------------
     341                 :             : !> @brief int_array_type_insertion_sort: sort a DYNAMIC INT array using merge sort algorithm
     342                 :             : !> @param[inout]  a: an dynamic array. the array to be sorted. and will output inplace
     343                 :             : !> @param[inout] order (optional) the sorted index, it can be used to sort
     344                 :             : !>  other arrays so that the order in consistent.
     345                 :             : !----------------------------------------------------------------------
     346                 :           0 : subroutine int_array_type_sort(self, order)
     347                 :             :   class(int_array_type), intent(inout):: self
     348                 :             :   integer, optional, intent(inout):: order(self%size)
     349                 :           0 :   integer :: work((self%size+1)/2), work_order((self%size+1)/2)
     350                 :           0 :   call MergeSort(self%data(:self%size), work, order, work_order)
     351                 :           0 : end subroutine int_array_type_sort
     352                 :             : 
     353                 :             : 
     354                 :             : !****f* m_dynarray/int_array_type_concate
     355                 :             : !!
     356                 :             : !! NAME
     357                 :             : !! int_array_type_concate
     358                 :             : !!
     359                 :             : !! FUNCTION
     360                 :             : !! concate int_array to a int_array_type
     361                 :             : !!
     362                 :             : !! INPUTS
     363                 :             : !! self = int_array_type object
     364                 :             : !! array= array to be concateed
     365                 :             : !! OUTPUT
     366                 :             : !! int_array<type(real_array_type)()> = int_array_type data
     367                 :             : !! SOURCE
     368                 :           0 : subroutine int_array_type_concate(self, array)
     369                 :             :   class(int_array_type), intent(inout):: self
     370                 :             :   class(int_array_type), intent(in):: array
     371                 :             :   integer :: i
     372         [ #  # ]:           0 :   do i=1, array%size
     373                 :           0 :     call self%push(array%data(i))
     374                 :             :   end do
     375                 :           0 : end subroutine int_array_type_concate
     376                 :             : !!***
     377                 :             : 
     378                 :             : 
     379                 :             : 
     380                 :             : 
     381                 :             : 
     382                 :             : !****f* m_dynarray/int_array_type_finalize
     383                 :             : !!
     384                 :             : !! NAME
     385                 :             : !! int_array_type_finalize
     386                 :             : !!
     387                 :             : !! FUNCTION
     388                 :             : !! destroy int_array_type
     389                 :             : !!
     390                 :             : !! INPUTS
     391                 :             : !! self= int_array_type object
     392                 :             : !! OUTPUT
     393                 :             : !! int_array<type(int_array_type)()> = int_array_type data
     394                 :             : !! SOURCE
     395                 :          39 : subroutine int_array_type_finalize(self)
     396                 :             : 
     397                 :             :   class(int_array_type), intent(inout):: self
     398         [ +  + ]:          39 :   ABI_SFREE(self%data)
     399                 :          39 :   self%size=0
     400                 :          39 :   self%capacity=0
     401                 :             : 
     402                 :          39 : end subroutine int_array_type_finalize
     403                 :             : 
     404                 :          27 : subroutine int_array_type_allgatherv(self,buff, comm, nproc)
     405                 :             :   class(int_array_type), intent(inout):: self
     406                 :             :   integer, intent(in) :: comm, nproc
     407                 :             :   integer, allocatable, intent(out) :: buff(:)
     408                 :             :   integer, allocatable :: tmp(:)
     409                 :          54 :   integer :: disps(nproc), sizes(nproc)
     410                 :             :   integer :: totsize, ierr, i
     411                 :          27 :   totsize=self%size
     412                 :          27 :   call xmpi_sum(totsize, comm, ierr)
     413   [ -  +  +  -  :          81 :   ABI_MALLOC(buff, (totsize))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     414                 :          27 :   call xmpi_allgather(self%size, sizes, comm, ierr)
     415                 :          27 :   disps(1)=0
     416         [ +  + ]:          69 :   do i=2, nproc
     417                 :          69 :     disps(i)=disps(i-1)+sizes(i-1)
     418                 :             :   end do
     419   [ +  +  +  -  :          81 :   ABI_MALLOC(tmp, (self%size))
          +  -  +  +  -  
                +  -  + ]
     420         [ +  + ]:          27 :   if(self%size>0) then
     421         [ +  + ]:          57 :     tmp(:)=self%data(:self%size)
     422                 :             :   end if
     423                 :          27 :   call xmpi_allgatherv(tmp, self%size, buff, sizes, disps, comm, ierr  )
     424         [ -  + ]:          27 :   ABI_FREE(tmp)
     425                 :          27 : end subroutine int_array_type_allgatherv
     426                 :             : 
     427                 :             : !==================================================================
     428                 :             : 
     429                 :             : !****f* m_dynarray/int2d_array_type_push
     430                 :             : !!
     431                 :             : !! NAME
     432                 :             : !! int2d_array_type_push
     433                 :             : !!
     434                 :             : !! FUNCTION
     435                 :             : !! push data to a int2d_array_type
     436                 :             : !!
     437                 :             : !! INPUTS
     438                 :             : !! self = int2d_array_type object
     439                 :             : !! val= data to be pushed
     440                 :             : !! OUTPUT
     441                 :             : !! int_array<type(real_array_type)()> = int2d_array_type data
     442                 :             : !! SOURCE
     443         [ -  + ]:     2571053 : subroutine int2d_array_type_push(self, val)
     444                 :             : 
     445                 :             :     class(int2d_array_type), intent(inout):: self
     446                 :             :     integer :: val(:)
     447                 :     2571053 :     integer, allocatable :: temp(:,:)
     448         [ +  + ]:     2571053 :     if(self%size1<0) then
     449                 :         113 :       self%size1=size(val)
     450         [ -  + ]:     2570940 :     else if(self%size1 /= size(val)) then
     451                 :           0 :       ABI_BUG("The size of  the array is inconsistent with the 2d dynamic array")
     452                 :             :     end if
     453                 :     2571053 :     self%size=self%size+1
     454         [ +  + ]:     2571053 :     if(self%size==1) then
     455                 :        1038 :       self%capacity=8
     456   [ -  +  +  -  :        4152 :       ABI_MALLOC(self%data, (size(val), self%capacity))
          +  -  +  -  +  
          -  -  +  -  +  
                   -  + ]
     457         [ +  + ]:     2570015 :     else if ( self%size>self%capacity ) then
     458                 :        1342 :       self%capacity = self%size + self%size / 4 + 8
     459   [ -  +  +  -  :        5368 :       ABI_MALLOC(temp, (size(val), self%capacity))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     460   [ +  +  +  + ]:    42790057 :       temp(:,:self%size-1) = self%data
     461         [ +  - ]:        1342 :       ABI_MOVE_ALLOC(temp, self%data) !temp gets deallocated
     462                 :             :     end if
     463         [ +  + ]:     9075108 :     self%data(:,self%size)=val
     464                 :     2571053 : end subroutine int2d_array_type_push
     465                 :             : !!***
     466                 :             : 
     467                 :             : !****f* m_dynarray/int2d_array_type_concate
     468                 :             : !!
     469                 :             : !! NAME
     470                 :             : !! int2d_array_type_concate
     471                 :             : !!
     472                 :             : !! FUNCTION
     473                 :             : !! concate int2d_array to a int2d_array_type
     474                 :             : !!
     475                 :             : !! INPUTS
     476                 :             : !! self = int2d_array_type object
     477                 :             : !! array= array to be concateed
     478                 :             : !! OUTPUT
     479                 :             : !! int_array<type(real_array_type)()> = int2d_array_type data
     480                 :             : !! SOURCE
     481                 :        1404 : subroutine int2d_array_type_concate(self, array)
     482                 :             :   class(int2d_array_type), intent(inout):: self
     483                 :             :   class(int2d_array_type), intent(in):: array
     484                 :             :   integer :: i
     485         [ +  + ]:        8660 :   do i=1, array%size
     486                 :        8660 :     call self%push(array%data(:, i))
     487                 :             :   end do
     488                 :        1404 : end subroutine int2d_array_type_concate
     489                 :             : !!***
     490                 :             : 
     491                 :           0 : subroutine int_array_type_tostatic(self, a)
     492                 :             :   class(int_array_type), intent(inout):: self
     493                 :             :   integer, allocatable :: a(:)
     494         [ #  # ]:           0 :   if(self%size>0) then
     495   [ #  #  #  #  :           0 :     ABI_MALLOC(a, (self%size))
          #  #  #  #  #  
                #  #  # ]
     496         [ #  # ]:           0 :     a(:) = self%data(:self%size)
     497                 :             :   else
     498   [ #  #  #  #  :           0 :     ABI_MALLOC(a, (self%size))
          #  #  #  #  #  
                #  #  # ]
     499                 :             :   end if
     500                 :           0 : end subroutine int_array_type_tostatic
     501                 :             : !!***
     502                 :             : 
     503                 :             : 
     504                 :             : 
     505                 :          38 : subroutine int2d_array_type_tostatic(self, a, size1)
     506                 :             :   class(int2d_array_type), intent(inout):: self
     507                 :             :   integer, allocatable :: a(:, :)
     508                 :             :   integer, optional :: size1
     509         [ +  - ]:          38 :   if(self%size>0) then
     510   [ -  +  +  -  :         152 :     ABI_MALLOC(a, (self%size1, self%size))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
     511   [ +  +  +  + ]:       29556 :     a(:, :) = self%data(:, :self%size)
     512         [ #  # ]:           0 :   else if(present(size1)) then
     513   [ #  #  #  #  :           0 :     ABI_MALLOC(a, (size1, self%size))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     514                 :             :   else
     515                 :           0 :     ABI_BUG("the size of the 2darray is unkown.")
     516                 :             :   end if
     517                 :          38 : end subroutine int2d_array_type_tostatic
     518                 :             : !!***
     519                 :             : 
     520                 :             : 
     521                 :             : 
     522                 :             : 
     523                 :             : !****f* m_dynarray/int2d_array_type_push
     524                 :             : !!
     525                 :             : !! NAME
     526                 :             : !! int2d_array_type_push
     527                 :             : !!
     528                 :             : !! FUNCTION
     529                 :             : !! push data to a int2d_array_type
     530                 :             : !!
     531                 :             : !! INPUTS
     532                 :             : !! self = int2d_array_type object
     533                 :             : !! val= data to be pushed
     534                 :             : !! OUTPUT
     535                 :             : !! int_array<type(real_array_type)()> = int2d_array_type data
     536                 :             : !! SOURCE
     537         [ -  + ]:       11644 : subroutine int2d_array_type_push_unique(self, val, position)
     538                 :             : 
     539                 :             :     class(int2d_array_type), intent(inout):: self
     540                 :             :     integer, intent(in) :: val(:)
     541                 :             :     integer, optional, intent(out) :: position
     542                 :             :     integer :: i
     543                 :             :     logical :: inside
     544                 :       11644 :     inside=.False.
     545         [ +  + ]:      106266 :     do i=1, self%size
     546   [ +  +  +  +  :      175210 :        if(all(self%data(:,i)==val)) then
                   +  + ]
     547                 :       11438 :           inside=.True.
     548         [ +  - ]:       11438 :           if (present(position)) position=i
     549                 :             :           exit
     550                 :             :        endif
     551                 :             :     enddo
     552                 :             :     if(.not. inside) then
     553                 :         206 :        call self%push(val)
     554         [ +  - ]:         206 :        if (present(position)) position=self%size
     555                 :             :     end if
     556                 :       11644 :   end subroutine int2d_array_type_push_unique
     557                 :             : !!***
     558                 :             : 
     559                 :             : 
     560                 :             : 
     561                 :             : !****f* m_dynarray/int2d_array_type_finalize
     562                 :             : !!
     563                 :             : !! NAME
     564                 :             : !! int2d_array_type_finalize
     565                 :             : !!
     566                 :             : !! FUNCTION
     567                 :             : !! destroy int2d_array_type
     568                 :             : !!
     569                 :             : !! INPUTS
     570                 :             : !! self= int2d_array_type object
     571                 :             : !! OUTPUT
     572                 :             : !! int_array<type(int2d_array_type)()> = int2d_array_type data
     573                 :             : !! SOURCE
     574                 :        2419 : subroutine int2d_array_type_finalize(self)
     575                 :             : 
     576                 :             :   class(int2d_array_type), intent(inout):: self
     577         [ +  + ]:        2419 :   if ( allocated(self%data) ) then
     578                 :        1038 :       ABI_SFREE(self%data)
     579                 :             :   end if
     580                 :        2419 :   self%size=0
     581                 :        2419 :   self%capacity=0
     582                 :             : 
     583                 :        2419 : end subroutine int2d_array_type_finalize
     584                 :             : 
     585                 :             : !----------------------------------------------------------------------
     586                 :             : !> @brief sort a 2D DYNAMIC INT array using insertion sort algorithm
     587                 :             : !>  it is a memory safe method but is generally slow.
     588                 :             : !> it compares the elements in first dimension i.e. A(:, i) and sort the second dim.
     589                 :             : !>  The comparing is from left to right.
     590                 :             : !> @param[inout]  a: an dynamic array. the array to be sorted. and will output inplace
     591                 :             : !> @param[inout] order (optional) the sorted index, it can be used to sort
     592                 :             : !>  other arrays so that the order in consistent.
     593                 :             : !----------------------------------------------------------------------
     594                 :             : 
     595                 :             : subroutine int2d_array_type_insertion_sort(self, order)
     596                 :             :   class(int2d_array_type), intent(inout):: self
     597                 :             :   integer, optional, intent(inout):: order(self%size)
     598                 :             :   integer :: i,j, v(size(self%data, dim=1))
     599                 :             :   if (present(order)) then
     600                 :             :      do i = 1, self%size
     601                 :             :         order(i)=i
     602                 :             :      end do
     603                 :             :   end if
     604                 :             :   do i = 2, self%size
     605                 :             :      v(:)=self%data(:,i)
     606                 :             :      j=i-1
     607                 :             :      do while(j>=1)
     608                 :             :         if (.not. (array_morethan(self%data(:,j),v, size(self%data, dim=1)))) exit
     609                 :             :         self%data(:,j+1)=self%data(:,j)
     610                 :             :         if(present(order)) order(j+1)=order(j)
     611                 :             :         j=j-1
     612                 :             :      end do
     613                 :             :      self%data(:,j+1)=v(:)
     614                 :             :      if(present(order)) order(j+1)=i
     615                 :             :   end do
     616                 :             :   self%sorted=.True.
     617                 :             : end subroutine int2d_array_type_insertion_sort
     618                 :             : 
     619                 :             : 
     620                 :             : !----------------------------------------------------------------------
     621                 :             : !> @brief sort a 2D DYNAMIC INT array using merge sort algorithm
     622                 :             : !>  It is now set as the default sorting algorithm.
     623                 :             : !>  it is a memory safe method but is generally slow.
     624                 :             : !> it compares the elements in first dimension i.e. A(:, i) and sort the second dim.
     625                 :             : !>  The comparing is from left to right.
     626                 :             : !> @param[inout]  a: an dynamic array. the array to be sorted. and will output inplace
     627                 :             : !> @param[inout] order (optional) the sorted index, it can be used to sort
     628                 :             : !>  other arrays so that the order in consistent.
     629                 :             : !----------------------------------------------------------------------
     630                 :             : 
     631                 :          12 : subroutine int2d_array_type_sort(self, order)
     632                 :             :   class(int2d_array_type), intent(inout):: self
     633                 :             :   integer, optional, intent(inout):: order(self%size)
     634                 :          24 :   integer :: work(size(self%data, dim=1), (self%size+1)/2), work_order((self%size+1)/2)
     635                 :          12 :   call MergeSort2D(self%data(:, :self%size), work, order, work_order )
     636                 :          12 : end subroutine int2d_array_type_sort
     637                 :             : 
     638                 :             : 
     639                 :             : !----------------------------------------------------------------------
     640                 :             : !> @brief binary search
     641                 :             : !>
     642                 :             : !> @param[in] self: the 2D array to be searched from
     643                 :             : !> @param[in] val: the value to be searched
     644                 :             : !> @param[out] i: the index of the first one found. returns 0 if not found.
     645                 :             : !----------------------------------------------------------------------
     646                 :             : 
     647         [ #  # ]:           0 : function int2d_array_type_binsearch(self, val) result(i)
     648                 :             :   class(int2d_array_type), intent(inout):: self
     649                 :             :   integer, intent(inout) :: val(:)
     650                 :             :   integer :: i
     651                 :           0 :   i=binsearch_left_integerlist(self%data(:,1:self%size), val)
     652                 :           0 : end function int2d_array_type_binsearch
     653                 :             : 
     654                 :             : 
     655                 :             : 
     656                 :             : !====================== Unit tests======================
     657                 :             : 
     658                 :           0 : subroutine binsearch_test()
     659                 :             :   integer :: a(4)=[1,2,3,4], b(3,3)=reshape([0,0,0,0,1,0,1,0,0], [3,3])
     660                 :             :   integer :: i
     661                 :           0 :   i=binsearch_left_integer(a, 5)
     662                 :           0 :   i=binsearch_left_integerlist(b, [0,0,0])
     663                 :           0 : end subroutine binsearch_test
     664                 :             : 
     665                 :           0 : subroutine insertion_sort_int_test()
     666                 :             :   integer :: a(4), order(4), b(4), a2(8)
     667                 :           0 :   a=[1,5,3,4]
     668                 :           0 :   b=a
     669                 :           0 :   call insertion_sort_int(a, order)
     670                 :           0 :   a2=[3,6,2,4, 3, 5, 0, 9]
     671                 :           0 :   call insertion_sort_int(a2)
     672                 :           0 : end subroutine insertion_sort_int_test
     673                 :             : 
     674                 :           0 : subroutine int2d_array_test()
     675                 :           0 :   type(int2d_array_type) :: t
     676                 :           0 :   call t%push_unique([1,1,2])
     677                 :           0 :   call t%push_unique([1,2,2])
     678                 :           0 :   call t%push_unique([1,1,2])
     679                 :           0 :   call t%push_unique([1,1,1])
     680                 :           0 :   call t%push_unique([-1, 3, 3])
     681                 :           0 :   call t%push_unique([2,1, 4])
     682                 :           0 :   call t%sort()
     683         [ #  # ]:           0 : end subroutine int2d_array_test
     684                 :             : 
     685                 :           0 : subroutine dynamic_array_unittest()
     686                 :           0 :   call binsearch_test()
     687                 :           0 :   call insertion_sort_int_test()
     688                 :           0 :   call int2d_array_test()
     689                 :           0 : end subroutine dynamic_array_unittest
     690                 :             : 
     691                 :             : 
     692   [ #  #  #  #  :           0 : end module m_dynamic_array
          #  #  #  #  #  
                #  #  # ]
     693                 :             : !!***
        

Generated by: LCOV version 2.3-1