Motivation
For studying inverse problems of PDEs by employing Bayesian inference method, we usually assume the inverse of the covarianc operator in the prior measure be a fractional Laplacian like differential operator. For implementing the prior measure, it is convenient to use Karhunen-Loeve expansion with some orthonormal basis (for Besov prior, wavelet basis is necessary). However, finite element method is one of the most powerfull method for dealing with PDEs. Using wavelet basis to solve PDEs seems to be not a conventional method. Based on these considerations, it is crucial to transform functions between prior measures and PDEs calculations.
Ideas
The idea is simple, we just need to calculate each node values in the FEM approach. We need to find out the coordinates of each node, and then calculate the values of the functions generated by the prior measure.
Program
Firstly, we import some necessary packages.
import fenics as fe
import numpy as np
from scipy import interpolate
import matplotlib.pyplot as plt
Then, define the mesh and function space as follow
mesh = fe.UnitSquareMesh(100, 100)
V = fe.FunctionSpace(mesh, 'CG', 1)
Construct an example for testing
x = np.linspace(0, 1, 100)
y = np.linspace(0, 1, 100)
xx, yy = np.meshgrid(x, y)
z = np.sin(2*np.pi*xx)*np.cos(2*np.pi*yy)
f = interpolate.interp2d(x, y, z, kind='cubic')
Extracting the node coordinates from the FunctionSpace defined before
node_coordinates = V.tabulate_dof_coordinates()
Evaluating the function values of the nodes in FEM approach and constructing the function object in FEniCS
f_val = [f(*node) for node in node_coordinates]
f_val = np.array(f_val).flatten()
f_FEM = fe.Function(V)
f_FEM.vector()[:] = f_val
Lastly, we test the evaluations are correct by evaluating some points of the functions defined by interp2 in scipy and functions defined in FEniCS.
yyy = 0.8
a = np.array([f(xv, yyy) for xv in x]).flatten()
b = np.array([f_FEM(xv, yyy) for xv in x]).flatten()
c = a - b
print('error = %f' % max(np.abs(c)))
plt.figure()
plt.plot(c, label='error')
plt.plot(a, '-.',linewidth=3 ,label='interpolate fun')
plt.plot(b, linewidth=1.5,label='fun transfer to FEM')
plt.legend()
plt.show()
All the programs are tested with FEniCS 2019.
2020