LCOV - code coverage report
Current view: top level - hybrid - unify_zmat.f90 (source / functions) Hit Total Coverage
Test: FLEUR test coverage Lines: 0 74 0.0 %
Date: 2024-05-02 04:21:52 Functions: 0 8 0.0 %

          Line data    Source code
       1             : module m_unify_zmat
       2             :    use m_types
       3             : contains
       4             : 
       5           0 :    subroutine unify_zmat(eigval, z)
       6             :       implicit none
       7             :       real, intent(in) :: eigval(:)
       8             :       type(t_mat)      :: z 
       9             : 
      10             :       integer :: beg_group, end_group, n_g
      11           0 :       integer, allocatable :: groups(:)
      12             : 
      13           0 :       groups = make_groups(eigval)
      14             :    
      15           0 :       do n_g = 1, size(groups)
      16           0 :          beg_group = sum(groups(1:n_g-1)) + 1
      17           0 :          end_group = sum(groups(1:n_g))
      18           0 :          if(end_group <= z%matsize2) call unify_group(beg_group, end_group, z)
      19             :       enddo
      20           0 :    end subroutine unify_zmat
      21             : 
      22           0 :    subroutine unify_group(beg_group, end_group, z)
      23             :       use m_legendre_poly
      24             :       implicit none
      25             :       integer, intent(in)        :: beg_group, end_group
      26             :       type(t_mat), intent(inout) :: z 
      27           0 :       type(t_mat)   :: targ, lhs, new_basis
      28             :       real, allocatable :: x(:)
      29             :       integer :: nrhs
      30             : 
      31           0 :       nrhs = (end_group - beg_group) + 1
      32             : 
      33             :       ! leg poly can be symmetric and we don't want that
      34           0 :       x = linspace(-1.1, 1.0, z%matsize1)
      35             : 
      36           0 :       call targ%init(z%l_real, z%matsize1, nrhs)
      37           0 :       call set_sin_targ(targ)
      38             : 
      39           0 :       call lhs%init(z%l_real, z%matsize1, nrhs )
      40           0 :       if(lhs%l_real) then 
      41           0 :          lhs%data_r = z%data_r(:,beg_group:end_group)
      42             :       else 
      43           0 :          lhs%data_c = z%data_c(:,beg_group:end_group)
      44             :       endif
      45             : 
      46           0 :       call lhs%leastsq(targ)
      47             : 
      48           0 :       if(lhs%l_real) then 
      49           0 :          lhs%data_r = z%data_r(:,beg_group:end_group)
      50             :       else 
      51           0 :          lhs%data_c = z%data_c(:,beg_group:end_group)
      52             :       endif
      53             : 
      54           0 :       call new_basis%init(lhs) 
      55           0 :       call lhs%multiply(targ, res=new_basis)
      56           0 :       call mod_gram_schmidt(new_basis)
      57             : 
      58           0 :       if(lhs%l_real) then 
      59           0 :          z%data_r(:,beg_group:end_group) = new_basis%data_r
      60             :       else 
      61           0 :          z%data_c(:,beg_group:end_group) = new_basis%data_c
      62             :       endif
      63           0 :    end subroutine
      64             : 
      65           0 :    subroutine set_sin_targ(targ)
      66             :       use m_constants
      67             :       implicit none 
      68             :       type(t_mat), intent(inout) :: targ 
      69             :       integer :: i 
      70             :       real, allocatable :: x(:) 
      71             : 
      72           0 :       x = linspace(0.0,4.0, targ%matsize1)
      73           0 :       do i = 1, targ%matsize2 
      74           0 :          if(targ%l_real) then 
      75           0 :             targ%data_r(:,i) = sin(i*x)
      76             :          else 
      77           0 :             targ%data_c(:,i) = sin(i*x) + imagunit * cos(i*x)
      78             :          endif 
      79             :       enddo
      80             : 
      81           0 :    end subroutine set_sin_targ
      82             : 
      83           0 :    function proj_r(u,v) result(p)
      84             :       implicit none 
      85             :       real, intent(in) :: u(:), v(:)
      86             :       real :: p(size(u)) 
      87             : 
      88           0 :       p = dot_product(u,v) / dot_product(u,u) * u 
      89           0 :    end function
      90             : 
      91           0 :    function proj_c(u,v) result(p)
      92             :       implicit none 
      93             :       complex, intent(in) :: u(:), v(:)
      94             :       complex :: p(size(u)) 
      95             : 
      96           0 :       p = dot_product(u,v) / dot_product(u,u) * u 
      97           0 :    end function
      98             : 
      99           0 :    subroutine mod_gram_schmidt(M)
     100             :       implicit none 
     101             :       type(t_mat), intent(inout) :: M 
     102             :       
     103             :       integer :: k, i 
     104             : 
     105           0 :       do k = 1,M%matsize2 
     106           0 :          do i = 1,k-1 
     107           0 :             if(M%l_real) then 
     108           0 :                M%data_r(:,k) = M%data_r(:,k) - proj_r(M%data_r(:,i), M%data_r(:,k)) 
     109             :             else
     110           0 :                M%data_c(:,k) = M%data_c(:,k) - proj_c(M%data_c(:,i), M%data_c(:,k)) 
     111             :             endif 
     112             :          enddo 
     113             : 
     114             : 
     115           0 :          if(M%l_real) then
     116           0 :             M%data_r(:,k) = M%data_r(:,k) / norm2(M%data_r(:,k))
     117             :          else 
     118           0 :             M%data_c(:,k) = M%data_c(:,k) / norm2(abs(M%data_c(:,k)))
     119             :          endif
     120             :       enddo 
     121           0 :    end subroutine mod_gram_schmidt
     122             : 
     123           0 :    function linspace(beg, fin, n_steps) result(res)
     124             :       implicit none 
     125             :       real, intent(in)    :: beg, fin 
     126             :       integer, intent(in) :: n_steps
     127             :       real                :: res(n_steps), step
     128             : 
     129             :       integer :: i
     130             : 
     131           0 :       step = (fin - beg)  / (n_steps - 1.0)
     132             : 
     133           0 :       do i = 0,n_steps-1 
     134           0 :          res(i+1) = beg + step * i 
     135             :       enddo 
     136           0 :    end function linspace
     137             : 
     138           0 :    function make_groups(eigval) result(groups)
     139             :       implicit none
     140             :       real, intent(in)     :: eigval(:)
     141             :       integer, allocatable :: groups(:)
     142           0 :       integer              :: color(size(eigval))
     143             : 
     144             :       integer :: i, beg, g_cnt, n_groups
     145             : 
     146           0 :       g_cnt = 1
     147           0 :       beg  = 1 
     148             : 
     149           0 :       do while (beg <= size(eigval)) 
     150           0 :          i = beg
     151           0 :          do while (abs(eigval(i) - eigval(beg)) < 1e-8  ) 
     152           0 :             color(i) = g_cnt
     153           0 :             i = i + 1 
     154           0 :             if(i > size(eigval)) exit
     155             :          enddo 
     156           0 :          g_cnt = g_cnt + 1 
     157           0 :          beg = i 
     158             :       enddo
     159             : 
     160             : 
     161           0 :       n_groups = color(size(eigval))
     162           0 :       allocate(groups(n_groups))
     163             : 
     164           0 :       do i = 1,n_groups 
     165           0 :          groups(i) = count(i == color)
     166             :       enddo 
     167           0 :    end function make_groups
     168             : end module m_unify_zmat

Generated by: LCOV version 1.14