Skip to content

trulsmoholt/masterthesis

Repository files navigation

masterthesis

This repo contains discretization methods for the elliptic PDE

,

in two spatial dimensions that handle general quadrilateral grids. In particular, the MPFA-O and MPFA-L methods are implemented, they yield locally mass conservative discretizations that are consistent for rough grids. The MPFA-L method has particulary good monotonicity properties, i.e., the maximum principle is respected for a wide range of grids. It's therefore considered as the state of the art method for porous media flow problems on quadrilatereal grids.

The code requires numpy for assembling discretization matrices, for running the convergence tests one also needs scipy and sympy.

Quick tutorial

The way to define a domain and discretize it into control volumes, is to discretize the unit square with rectangles, then perturb the grid points. This approach is very flexible and alows for complicated domains and control volume discretizations.

from discretization.mesh import Mesh
import numpy as np

nx = ny = 6 #Number of grid points in x and y direction on the unit square
perturbation = lambda p:np.array([p[0],0.5*p[0]+p[1]]) #perturbation on every grid point p
mesh = Mesh(nx,ny,perturbation,ghostboundary=True) #Creates a mesh object with a strip of ghostcells for boundary handling
mesh.plot()

This would result in the parallelogram discretization, note that we have 8 grid points (in orange) in each direction, 2 more than 6, as we have a strip of ghost cells.

Figure_2_small

For solving the Poisson equation on this, one would define the problem data with numpy arrays and python functions, then pass it to the compute_matrix and compute_vector functions, together with the mesh object. In this example we have a homogeneous domain (permeability is a matrix of ones), and a isotropic medium (tensor is diagonal).

from discretization.FVML import compute_matrix,compute_vector
import math

source = lambda x , y : math.sin(y)*math.cos(x)
boundary_condition = lambda x , y :0
tensor = np.eye(2)
permeability = np.ones(( mesh.num_unknowns,mesh.num_unknowns))

A = np.zeros((mesh.num_unknowns,mesh.num_unknowns))# stiffness matrix
f = np.zeros(mesh . num_unknowns)# load vector

compute_matrix(mesh,A,tensor,permeability)
compute_vector(mesh,f,source,boundary_condition)

u = np.linalg.solve(A,f)
mesh.plot_vector(u)

This would result in the solution

Figure_2_solution

For more interesting equations, such as the time dependent, non-linear Richards' equation, see this file.