Pk(Ij) denotes the set of Orthnogonal Legendre polynomials of degree at the most k over Ij interval.
If k=0, the scheme formulated below problated below reduces to a first order SL finite volumme scheme.
Introduce the test function ψ(x,t), satisfying the boundary conditions ψ(x,tn+1)=Ψ(x∈Pk(Ij), yields the following expression:
ψt+a(x,t)ψx=0,t∈[tn,tn+1]
The preceding equations (2), presented in adjective form, maintain a constant solution along a characteristic trajectory. Subsequently, as demonstrated in, it can be established that:
dtd∫Ij(t)u(x,t)ψ(x,t)dx=0
where Ij(t) is a dynamic intervel bounded by characteristcs emanating from cell boundaries of Ij at t=tn+1.
Prove for (3) One-dimentional Reynolds transport theorem
According to one-dimentional Reynolds transport theorem,
Given un∈Vhk, we seek un+1∈Vhk, such that for ∀Ψ∈Pk(Ij),j=1,...,k。 An SL time discretization of equation(3) leads to
∫Ijun+1(x,t)Ψdx=∫Ij∗u(x,tn)ψ(x.tn)dx
where Ij∗=[xj−21∗,xj+21∗] with xj±21∗ being the foots of trajectory emanating from (xj±21∗,tn+1) at the time tn. Then, update the numerical solution un+1.
Initially, we select k+1 interpolation points xj,p, where p=0,...,k(此时0到k就正好是k+1个), empolying methods like Gauss-Lobatto points within the interval Ij.
Gauss-Lobatto
Utilizing Gaussian quadrature with a weighting function W(x)=1, encompassing the endpoints of the interval [−1,1], involves a total of n abscissas, resulting in r=n−2 free abscissas. The abscissas are symmetric about the origin, and the general formula is given by:
∫−11f(x)dx=w1f(−1)+wnf(1)+i=2∑n−1wif(xi).
The unrestricted abscissas xi for i=2,...,n−1 correspond to the roots of the derivative Pn−1′(x), where P(x) represents a Legendre polynomial. The weights associated with these unrestricted abscissas are:
Subsequencetly, we determine the footpoints xj,q∗ through numerical solutions to the trajectory equation.
dtdx(t)=a(x(t),t), with x(tn+1)=xj,q
! assemble gauss lobatto of an upstream element
! prepare for interpolating the test function.
do i = 1,nx
! consider an upstream element
p => element_star(i)
pe => element(i)
if( nk>0 )then
p%xgl_star(1) = vertex_star(i)%coor
p%xgl_star(nk+1) = vertex_star(i+1)%coor
!
if( nk>1 )then
pe%xgl(1) = vertex(i)%coor
pe%xgl(nk+1) = vertex(i+1)%coor
do ii = 2,nk
pe%xgl(ii) = pe%xgl(1)+( 1.0/2. + gau_lob(ii,1) )*( pe%xgl(nk+1)-pe%xgl(1) )
call runge_kutta( pe%xgl(ii) , p%xgl_star(ii) ,dt)
enddo
endif
endif
enddo
Runge-Kutta 4
Achieved using the Runge-Kutta method as follow,
⎩⎨⎧xj,q∗=xj,q−6Δt(k1+2k2+2k3+k4)k1=a(xj,q,tn+1),k2=a(xj,q−2Δtk1,tn+21), where tn+21=tn+21Δtk3=a(xj,q−2Δtk2,tn+21), where tn+21=tn+21Δtk4=a(xj,q−Δtk3,tn)
ahieves fifth-order accuracy O(h5). Since for RK4, the local truncation error is on the order of O(h5), where h is the step size.
Recalling that the test function ψ(x,t) resolves the final-value problem and consequently remains constant along the characteristics i.e., ψ(xj,q∗)=Ψ(xj,q). Our next step is to ascertain the unique polynomial ψ∗(x) of degree k. This polynomial is chosen such that it interpolates ψ(x,tn) with the pairs (xj,q∗,Ψ(xj,q)) for q=0,…,k.
we assume that ψ∗(x)=a0+a1x+a2x2+…+akxk, and ψ∗(x) satisfies,
Detect interval/sub-intervals within Ij∗=∪lIj,l∗, which are the intersections bewteen Ij∗ and the grid elements(l is the index for sub-interval). Here l serves as the index for the sub-interval. For each interval, there may exist two sub-intervals: Ij,1∗=[xj−21∗,xj−21] and Ij,2=[xj−21,xj+21∗], Like the picture below.
Firstly, for each result of xj−21∗ or xj+21∗ we record the distance with the original start point. Then, we calculate the number of subinterval by (vertex_star(i)%coor-xleft)/dx.
do i = 1 ,nx+1
call runge_kutta( vertex(i)%coor , vertex_star(i)%coor ,dt)
!ceiling 是向上取整
vertex_star(i)%id = ceiling( (vertex_star(i)%coor-xleft)/dx )
enddo
And in the implementation, we use a new data structure and create a pointer to obtain all x∗.
do i = 1,nx
! consider an upstream element
p => element_star(i)
p%point_origin = vertex_star(i)
p%point_end = vertex_star(i+1)
call search_segment(p)
enddo
After that, we use the sgement_search function, to get all subinterval of an upstream element.
mx = p%point_end%id - p%point_origin%id ! mx也表示x*中有几个点
p%point_inter(0) = p%point_origin !x* 的起始点
p%point_inter(1+mx) = p%point_end !如果x* 都在一个interval里,那么mx = 0, 点就是 p%point_inter(1)
p%nsub = mx+1 !x* 有几个subinterval
if(mx .ne. 0)then
do kk = 1 , mx
inter = p%point_origin%id + kk !是第几个x
p%point_inter(kk)%coor = xgrid( inter ) !通过xgrid找到x的值
p%point_inter(kk)%id = inter !记录起始点对应的位置
enddo
endif
!记录每一个subinterval起始点,终点&起始点对应的位置
do kk = 1 , 1 + mx
p%segment(kk)%porigin = p%point_inter(kk-1)
p%segment(kk)%pend = p%point_inter(kk)
p%segment(kk)%id = p%point_inter(kk-1)%id
enddo