scipy中的插值函数转换成FEniCS中的函数

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

你可能感兴趣的:(scipy中的插值函数转换成FEniCS中的函数)