Build a 1D Vandermonde matrix from an orthonormal Legendre basis to a nodal basis and reverse
| Type | Intent | Optional | 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 |
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