buildLegendreVdm Subroutine

public subroutine buildLegendreVdm(N_In, xi_In, Vdm_Leg, sVdm_Leg)

Uses

  • proc~~buildlegendrevdm~~UsesGraph proc~buildlegendrevdm buildLegendreVdm module~modgvec_linalg MODgvec_LinAlg proc~buildlegendrevdm->module~modgvec_linalg module~modgvec_globals MODgvec_Globals module~modgvec_linalg->module~modgvec_globals iso_fortran_env iso_fortran_env module~modgvec_globals->iso_fortran_env

Build a 1D Vandermonde matrix from an orthonormal Legendre basis to a nodal basis and reverse

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: N_In

input polynomial degree

real(kind=wp), intent(in) :: xi_In(0:N_In)

nodal positions [-1,1]

real(kind=wp), intent(out) :: Vdm_Leg(0:N_In,0:N_In)

Vandermonde from Legendre to nodal basis

real(kind=wp), intent(out) :: sVdm_Leg(0:N_In,0:N_In)

Vandermonde from nodal basis to Legendre


Calls

proc~~buildlegendrevdm~~CallsGraph proc~buildlegendrevdm buildLegendreVdm interface~legendrepolynomialandderivative LegendrePolynomialAndDerivative proc~buildlegendrevdm->interface~legendrepolynomialandderivative proc~inv INV proc~buildlegendrevdm->proc~inv interface~legendrepolynomialandderivative->interface~legendrepolynomialandderivative dgetrf dgetrf proc~inv->dgetrf dgetri dgetri proc~inv->dgetri

Source Code

SUBROUTINE buildLegendreVdm(N_In,xi_In,Vdm_Leg,sVdm_Leg)
! MODULES
USE MODgvec_LinAlg, ONLY:INV
IMPLICIT NONE
!----------------------------------------------------------------------------------------------------------------------------------
! INPUT/OUTPUT VARIABLES
INTEGER,INTENT(IN) :: N_In                    !! input polynomial degree
REAL(wp),INTENT(IN)    :: xi_In(0:N_In)           !! nodal positions [-1,1]
REAL(wp),INTENT(OUT)   ::  Vdm_Leg(0:N_In,0:N_In) !! Vandermonde from Legendre to nodal basis
REAL(wp),INTENT(OUT)   :: sVdm_Leg(0:N_In,0:N_In) !! Vandermonde from nodal basis to Legendre
!----------------------------------------------------------------------------------------------------------------------------------
! LOCAL VARIABLES
INTEGER            :: i,j
REAL(wp)               :: dummy
!REAL(wp)               :: wBary_Loc(0:N_In)
!REAL(wp)               :: xGauss(0:N_In),wGauss(0:N_In)
!==================================================================================================================================
! Alternative to matrix inversion: Compute inverse Vandermonde directly
! Direct inversion seems to be more accurate

!CALL BarycentricWeights(N_In,xi_in,wBary_loc)
!! Compute first the inverse (by projection)
!CALL LegendreGaussNodesAndWeights(N_In,xGauss,wGauss)
!!Vandermonde on xGauss
!DO i=0,N_In
!  DO j=0,N_In
!    CALL LegendrePolynomialAndDerivative(j,xGauss(i),Vdm_Leg(i,j),dummy)
!  END DO !i
!END DO !j
!Vdm_Leg=TRANSPOSE(Vdm_Leg)
!DO j=0,N_In
!  Vdm_Leg(:,j)=Vdm_Leg(:,j)*wGauss(j)
!END DO
!!evaluate nodal basis (depends on NodeType, for Gauss: unity matrix)
!CALL InitializeVandermonde(N_In,N_In,wBary_Loc,xi_In,xGauss,sVdm_Leg)
!sVdm_Leg=MATMUL(Vdm_Leg,sVdm_Leg)

!compute the Vandermonde on xGP (Depends on NodeType)
DO i=0,N_In; DO j=0,N_In
  CALL LegendrePolynomialAndDerivative(j,xi_In(i),Vdm_Leg(i,j),dummy)
END DO; END DO !j
sVdm_Leg=INV(Vdm_Leg)
!check (Vdm_Leg)^(-1)*Vdm_Leg := I
dummy=ABS(SUM(ABS(MATMUL(sVdm_Leg,Vdm_Leg)))/REAL(N_In+1,wp)-1.0_wp)
IF(dummy.GT.10.0_wp*PP_RealTolerance) CALL abort(__STAMP__, &
                                         'problems in MODAL<->NODAL Vandermonde ')
END SUBROUTINE buildLegendreVdm