gaussquad_rosetta Subroutine

subroutine gaussquad_rosetta(n, r1, r2)

Arguments

Type IntentOptional AttributesName
integer, intent(in) :: n
real(kind=wp), intent(out) :: r1(n)
real(kind=wp), intent(out) :: r2(n)

Called by

proc~~gaussquad_rosetta~~CalledByGraph proc~gaussquad_rosetta gaussquad_rosetta proc~gaussquad gaussquad proc~gaussquad->proc~gaussquad_rosetta interface~gaussquad gaussquad interface~gaussquad->proc~gaussquad proc~integrate2d integrate2D proc~integrate2d->interface~gaussquad proc~integrate1d integrate1D proc~integrate1d->interface~gaussquad interface~integrate integrate interface~integrate->proc~integrate2d interface~integrate->proc~integrate1d proc~integrate_basis_1d_ie integrate_basis_1d_Ie proc~integrate_basis_1d_ie->interface~integrate proc~assembleelementalmatrix2d assembleElementalMatrix2D proc~assembleelementalmatrix2d->interface~integrate proc~assembleelementalmatrix1d assembleElementalMatrix1D proc~assembleelementalmatrix1d->proc~integrate_basis_1d_ie

Contents

Source Code


Source Code

    subroutine gaussquad_rosetta(n, r1, r2)

        ! This code was originally found at the following website:
        !  http://rosettacode.org/wiki/Numerical_integration/Gauss-Legendre_Quadrature#Fortran

        integer,  intent(in)    :: n
        real(wp), intent(out)   :: r1(n), r2(n)


        integer                 :: k
        real(wp), parameter     :: pi = 4._wp*atan(1._wp)
        real(wp)                :: x, f, df, dx
        integer                 :: i,  iter
        real(wp), allocatable   :: p0(:), p1(:), tmp(:)

        p0 = [1._wp]
        p1 = [1._wp, 0._wp]

        do k = 2, n
            tmp = ((2*k-1)*[p1,0._wp]-(k-1)*[0._wp, 0._wp,p0])/k
            p0 = p1; p1 = tmp
        enddo

        outer: do i = 1, n
            x = cos(pi*(i-0.25_wp)/(n+0.5_wp))
            inner: do iter = 1, 10
                f = p1(1); df = 0._wp
                deep: do k = 2, size(p1)
                    df = f + x*df
                    f  = p1(k) + x * f
                enddo deep
                dx =  f / df
                x = x - dx
                if (abs(dx)<10*epsilon(dx)) exit
            enddo inner
            r1(i) = x
            r2(i) = 2/((1-x**2)*df**2)
        enddo outer
        return
    end subroutine gaussquad_rosetta