matrix_inversion.f90 Source File


Files dependent on this one

sourcefile~~matrix_inversion.f90~~AfferentGraph sourcefile~matrix_inversion.f90 matrix_inversion.f90 sourcefile~implicit.f90 implicit.f90 sourcefile~implicit.f90->sourcefile~matrix_inversion.f90 sourcefile~time_stepping.f90 time_stepping.f90 sourcefile~time_stepping.f90->sourcefile~implicit.f90 sourcefile~tendencies.f90 tendencies.f90 sourcefile~time_stepping.f90->sourcefile~tendencies.f90 sourcefile~tendencies.f90->sourcefile~implicit.f90 sourcefile~speedy.f90 speedy.f90 sourcefile~speedy.f90->sourcefile~time_stepping.f90 sourcefile~initialization.f90 initialization.f90 sourcefile~speedy.f90->sourcefile~initialization.f90 sourcefile~initialization.f90->sourcefile~time_stepping.f90

Contents

Source Code


Source Code

module matrix_inversion
    implicit none

    private
    public inv

contains
    subroutine ludcmp(a,n,np,indx,d)
        real, intent(inout) :: a(np,np), d
        integer, intent(inout) :: indx(n)
        integer, intent(in) :: n, np
        integer, parameter :: nmax = 100
        real, parameter :: tiny = 1.0e-20
        integer :: i, j, k, imax
        real :: vv(nmax), aamax, dum, sum

        d = 1.0

        do i=1,n
            aamax=0.
            do j=1,n
                if(abs(a(i,j)).gt.aamax) aamax=abs(a(i,j))
            end do
            if(aamax.eq.0.) stop 'singular'
            vv(i)=1./aamax
        end do

        do j=1,n
            if(j.gt.1) then
                do i=1,j-1
                    sum=a(i,j)
                    if(i.gt.1) then
                        do k=1,i-1
                            sum=sum-a(i,k)*a(k,j)
                        end do
                        a(i,j)=sum
                    end if
                end do
            end if

            aamax=0.
            do i=j,n
                sum=a(i,j)
                if(j.gt.1) then
                    do k=1,j-1
                      sum=sum-a(i,k)*a(k,j)
                    end do
                    a(i,j)=sum
                end if
                dum=vv(i)*abs(sum)
                if(dum.ge.aamax) then
                    imax=i
                    aamax=dum
                end if
            end do

            if(j.ne.imax) then
                do k=1,n
                    dum=a(imax,k)
                    a(imax,k)=a(j,k)
                    a(j,k)=dum
                end do
                d=-d
                vv(imax)=vv(j)
            end if

            indx(j)=imax
            if(j.ne.n) then
                if(a(j,j).eq.0) a(j,j)=tiny
                dum=1./a(j,j)
                do i=j+1,n
                    a(i,j)=a(i,j)*dum
                end do
            end if
        end do

        if(a(n,n).eq.0.) a(n,n)=tiny
    end

    subroutine lubksb(a,n,np,indx,b)
        real, intent(inout) :: a(np,np), b(n)
        integer, intent(in) :: n, np, indx(n)
        integer :: ii, i, ll, j
        real :: sum

        ii=0

        do i=1,n
            ll=indx(i)
            sum=b(ll)
            b(ll)=b(i)
            if(ii.ne.0) then
                do j=ii,i-1
                    sum=sum-a(i,j)*b(j)
                end do
            else if(sum.ne.0) then
                ii=i
            end if
            b(i)=sum
        end do

        do i=n,1,-1
            sum=b(i)
            if(i.lt.n) then
              do j=i+1,n
                sum=sum-a(i,j)*b(j)
              end do
            end if
            b(i)=sum/a(i,i)
        end do
    end

    subroutine inv(a,y,indx,n)
        real, intent(inout) :: a(n,n), y(n,n)
        integer, intent(inout) :: indx(n)
        integer, intent(in) :: n
        integer :: i
        real :: d

        y = 0.0

        do i=1,n
            y(i,i)=1.
        end do

        call ludcmp(a,n,n,indx,d)

        do i=1,n
            call lubksb(a,n,n,indx,y(1,i))
        end do
    end
end module