Starting with initial guess by Parter Relation, a Newton method is used to find the roots of the Legendre Polynomial Lder_(N_in), which are the positions of Gauss-Lobatto points. Uses qAndLEvaluation subroutine. algorithm 25, Kopriva
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | N_in |
polynomial degree (N_in+1) Gausspoints |
||
| real(kind=wp), | intent(out) | :: | xGP(0:N_in) |
Gauss point positions for the reference interval [-1,1] |
||
| real(kind=wp), | intent(out), | optional | :: | wGP(0:N_in) |
Gauss point weights |
SUBROUTINE LegGaussLobNodesAndWeights(N_in,xGP,wGP) ! MODULES IMPLICIT NONE !---------------------------------------------------------------------------------------------------------------------------------- ! INPUT/OUTPUT VARIABLES INTEGER,INTENT(IN) :: N_in !! polynomial degree (N_in+1) Gausspoints REAL(wp),INTENT(OUT) :: xGP(0:N_in) !! Gauss point positions for the reference interval [-1,1] REAL(wp),INTENT(OUT),OPTIONAL :: wGP(0:N_in) !! Gauss point weights !---------------------------------------------------------------------------------------------------------------------------------- ! LOCAL VARIABLES INTEGER :: nIter = 10 ! max. number of newton iterations REAL(wp) :: Tol = 1.E-15_wp ! tolerance for Newton iteration : TODO: use variable tolerance here! INTEGER :: iGP,iter REAL(wp) :: q,qder,L ! \f$ q=L_{N_in+1}-L_{N_in-1} \f$ ,qder is derivative, \f$ L=L_{N_in} \f$ REAL(wp) :: dx ! Newton step REAL(wp) :: cont1,cont2 !temporary variable for evaluation of parter nodes positions !================================================================================================================================== xGP(0)=-1.0_wp xGP(N_in)= 1.0_wp IF(PRESENT(wGP))THEN wGP(0)= 2.0_wp/REAL(N_in*(N_in+1),wp) wGP(N_in)=wGP(0) END IF IF(N_in.GT.1)THEN cont1=PP_Pi/REAL(N_in,wp) ! pi/N_in cont2=3.0_wp/(REAL(8*N_in,wp)*PP_Pi) ! 3/(8*N_in*pi) DO iGP=1,(N_in+1)/2-1 !since points are symmetric, only left side is computed xGP(iGP)=-cos(cont1*(REAL(iGP,wp)+0.25_wp)-cont2/(REAL(iGP,wp)+0.25_wp)) !initial guess ! Newton iteration DO iter=0,nIter CALL qAndLEvaluation(N_in,xGP(iGP),q,qder,L) dx=-q/qder xGP(iGP)=xGP(iGP)+dx IF(abs(dx).LT.Tol*abs(xGP(iGP))) EXIT END DO ! iter IF(iter.GT.nIter) THEN WRITE(UNIT_stdout,*) 'maximum iteration steps >10 in Newton iteration for LGL point:' xGP(iGP)=-cos(cont1*(REAL(iGP,wp)+0.25)-cont2/(REAL(iGP,wp)+0.25_wp)) !initial guess ! Newton iteration DO iter=0,nIter WRITE(UNIT_stdout,*)'iter,x^i',iter,xGP(iGP) !DEBUG CALL qAndLEvaluation(N_in,xGP(iGP),q,qder,L) dx=-q/qder xGP(iGP)=xGP(iGP)+dx IF(abs(dx).LT.Tol*abs(xGP(iGP))) EXIT END DO ! iter CALL abort(__STAMP__, & 'ERROR: Legendre Gauss Lobatto nodes could not be computed up to desired precision. Code stopped!') END IF ! (iter.GT.nIter) CALL qAndLEvaluation(N_in,xGP(iGP),q,qder,L) xGP(N_in-iGP)=-xGP(iGP) IF(PRESENT(wGP))THEN wGP(iGP)=wGP(0)/(L*L) wGP(N_in-iGP)=wGP(iGP) END IF END DO ! iGP END IF !(N_in.GT.1) IF(mod(N_in,2) .EQ. 0) THEN xGP(N_in/2)=0.0_wp CALL qAndLEvaluation(N_in,xGP(N_in/2),q,qder,L) IF(PRESENT(wGP))wGP(N_in/2)=wGP(0)/(L*L) END IF ! (mod(N_in,2) .EQ. 0) END SUBROUTINE LegGaussLobNodesAndWeights