/PME-LDG-Limiters

To compare several limiters by using Runge-Kutta Discontinous Galerkin Finite Element Method to solve the following Porous Medium Equation with periodic boundary condition and different initial conditions.

Primary LanguageMATLAB

PME-LDG-Limiters

To compare several limiters by using Runge-Kutta Local Discontinous Galerkin Finite Element Method to solve the following Porous Medium Equation with periodic boundary condition and different initial conditions.

u_t = (u^m)_xx - c * u^p

Flow Chart

main_xx.m
  - Define the paths of data and report.
  - Define the parameters of problem (equation, boundary, initial).
  - Define the parameters of method (cells, basis, limiter).
  - Call PME.m to solve the problem.
      - Extract parameters.
      - Call Quadrature_Set.m to set up quadrature.
      - Call Mesh_Set.m to generate mesh.
      - Define space and time step
        according to the pre-stored CFL condition number.
      - Call Basis_Set.m to set up basis.
      - Initialize the variables to track limiter.
      - Set up the initial condition.
      - Execute the for loop to solve the problem
        > Using 3rd order Runge-Kutta time marching.
        > For applications, the moments of solutions will be saved.
        - Call L_pme.m to march.
            - Call H_pme.m to calculate the flux.
        - Call Limiter.m to adjust the solution.
      - If using limiter, save the trackers and other variables.

Data Structure

Parameters

Parameters for solving the problem.

Parameters				| Description
----------------------- | -----------
m, c, p					| Parameters of equation.
R_left, R_right         | Region is [R_left, R_right].
dT                      | Time duration.
uI                      | Initial value of solution.
J                       | Number of cells.
basis_order             | Basis order.
type_problem            | 0: CFL test (call main_test).
                        | 1: Experiment (call main_ex).
                        | 2: Application (call main_app).
type_limiter            | Correspond to different limiter combinations.
                        | The value is 100*a+10*b+c.
                        | a is corresponding to the cell average limiter
                        | a = 0: do not adjust the cell averages
                        |     1: set negative cell averages to zero
                        |     2: recompute flux to adjust the cell averages
                        | b is corresponding to the oscillation limiter
                        | b = 0: do not attenuate the oscillation
                        |     1: target space is linear
                        |     2: target space is quadratic
                        |     3: target space is the same as the space of the solution
                        | c is corresponding to the positive limiter
                        | c = 0: do not adjust the solution
                        |     1: target space is linear
                        |     2: target space is the same as the space of the solution
CFL                     | In CFL test, CFL is given outside PME.m.
mu = 1                  | Parameter of the threshold in the limiter
                        | who attenuates the oscillation.
num_fig = 200           | Number of figures of the solution.

Variables

Variables during solving the PME problem.

Variables				| Description
----------------------- | -----------
PARA                    | PARA = [m, c, p;
                        |         R_left, R_right, dT;
                        |         J, basis_order, 0;
                        |         type_problem, type_limiter, CFL;];
                        | Scripts use PARA to transmit parameters.
points, weights         | size(points) = (7, 1)
                        | size(weights) = (1, 7)
                        | The gauss points in [-1, 1] and the corresponding weights.
                        | (Using five points Gauss�Legendre quadrature.)
grid                    | size(grid) = (2, J)
                        | grid(1, j) stores the center of the j-th cell.
                        | grid(2, j) stores half of the length of the j-th cell.
X                       | size(X) = (7, J)
                        | X(:, j) stores the guass points in the j-th cell.
dx                      | Space step.
dt                      | Time step.
loops                   | Number of loops.
psi                     | size(psi) = (7, basis_order + 1)
                        | psi(:, i + 1) stores the values of the i-th degree Legendre polynomial
                        | on the gauss points.
psi_z                   | size(psi_z) = (7, basis_order + 1)
                        | psi_z(:, i + 1) stores the values of the drivative
                        | of the i-th degree Legendre polynomial on the gauss points.
u                       | size(u) = (7, J)
                        | u = u(X), X(:, j) stores the values of solution on the guass points in the j-th cell.
u_coord                 | size(u_coord) = (basis_order + 1, J)
                        | u_coord(i + 1, j) stores the weights of the i-th degree Legendre polynomial.
track_mean              | size(track_mean) = (J, loops), it's a sparse matrix.
                        | track_mean(j, loop) = cell average
                        | if the cell average of the j-th cell is negative, otherwise it equals 0.
track_osc               | size(track_osc) = (J, loops), it's a sparse matrix.
                        | track_osc(j, loop) ~= 0, if there's oscillation in the j-th cell.
track_pos               | size(track_pos) = (J, loops), it's a sparse matrix.
                        | track_pos(j, loop) ~= 0, if there's negative value in the j-th cell.

Scripts

main_test.m

Objective:  Test the CFL condition.
Output:     CFL_table, which stores the minimum CFL number.
Problem:    PME.
Initial:    Barenblatt Solutison.
Solution:   Barenblatt Solution.

main_ex.m

Objective:  Computes the error table.
Output:     err_table.
Problem:    PME.
Initial:    Barenblatt Solution.
Solution:   Barenblatt Solution.

When writing new limiters, we can use this script to test if the limiter works and how the limiter works.

main_app1.m

Objective:  Stores the moments of the numerical solution.
Output:     Screenshots of the solution.
Problem:    PME.
Initial:    Two box solutions.
Solution:   Unknown.

main_app2.m

Objective:  Stores the moments of the numerical solution.
Output:     Screenshots of the solution.
Problem:    PME.
Initial:    cos(x).
Solution:   Unknown.

main_app3.m

Objective:  Stores the moments of the numerical solution.
Output:     Screenshots of the solution.
Problem:    PME with absorption.
Initial:    |Sin(x)| with platform.
Solution:   Unknown.

Data_Process.m

Objective:  Plots the trackers to learn where and how the limiter works.
Output:     The locations of cells where the limiter is used.
            The min and mean of the negative cell averages.

Functions

PME.m

function [err] = PME(PARA, uI, path_data, path_report)

This function is the solver of PME and it returns the error. When type_problem = 0 or 1, it returns the error, otherwise it returns -1.

This function also saves the moments of the solution to observe the movement of the solution and it saves three global variables which tracks the limiters.

  • track_mean records the cells where the cell average is negative.
  • track_osc records the cells where the oscillation exist.
  • track_pos records the cells where the negative value exist.

L_pme.m

function [ut_coord] = L_pme(u_coord, loop, type_limiter)

This function is to solve the L(u) where u_t = L(u) is the first order ODE system.

If needed, this function will call twice H_pme.m and use the combination of the flux to adjust the cell average and make sure the cell average is non-negative. (Sometimes there are some extreme small negative values due to the machine error. Those values will be replaced with zero and it won't affect the accuracy.)

H_pme.m

function [flux_ur, q] = H_pme(u, loop, psi, psi_z)

This function is to calculate the flux according to the given basis.

Limiter.m

function [u_coord] = Limiter(u_coord, loop, type_limiter)

This function calls the corresponding limiter to adjust the solution.

limiter_osc.m

function [u_coord] = limiter_osc(u_coord, loop, index_osc)

This limiter uses different ways to attenuate the oscillation.

limiter_pos.m

function [u_coord] = limiter_pos(u_coord, loop, index_pos)

This limiter uses different ways to keep solution positive.

Quadrature_Set.m

function [points, weights] = Quadrature_Set()

This function generates the gauss points and the corresponding weights for the quadrature.

points is column vector and weights is row vector.

\int\limits_{-1}^{1}f(x)dx = weights * f(points)

Mesh_Set.m

function [grid,X] = Mesh_Set(points,R_left,R_right,J)

This function generates the mesh. (mesh is a reserved word in Matlab.)

grid stores the center and half length of each cell. X is the mesh.

Basis_Set.m

function [psi,psi_z] = Basis_Set(points,basis_order)

This function returns the values of basis on the gauss points according to the order of basis.

BarenblattSolution.m

function [y] = BarenblattSolution(x, t, m)

This function is the famous Barenblatt Solution which is the exact solution of Porous Medium Equation.

minmod.m

function [a, flag] = minmod(a1, a2, a3, threshold)

This minmod function is used in limiters. The principle is:

minmod(a1, a2, a3, threshold)
    = a1                            if abs(a1) <= threshold
      s * min(abs([a1, a2, a3]))    if s = sign(ai), i = 1, 2, 3
      0                             otherwise