Hello,
I’m currently trying to interpolate the solution of my (nonlinear) problem U into a higher order function space U_target. I therefore created a class which contains the solution U and a function which evaluates U at positions x. This function was indented as input for creating U_target but - even if the evaluated nodal values of U are what they should be - the interpolation fails. I attached a minimum working example where a expression is interpolated into a function space of order 2 while this function should be subsequently interpolated into a higher order functionspace.
import numpy as np
from mpi4py import MPI
from petsc4py import PETSc
import dolfinx
import dolfinx.geometry
import dolfinx.io
import ufl
from dolfinx.cpp.mesh import CellType
class RefSol:
def __init__(self, t):
self.t = t
def interpol_displacement(self, x):
u = np.zeros((2, x.shape[1]), dtype=PETSc.ScalarType)
u[0] = np.exp(-self.t) * (- np.cos(np.pi * x[0]) * np.sin(np.pi * x[1]))
u[1] = np.exp(-self.t) * (- np.cos(np.pi * x[0]) * np.sin(np.pi * x[1]))
return u
class Interpol_PointValue:
def __init__(self, mesh, function):
self.function = function
self.mesh = mesh
def eval_pointvalue(self, x):
"Code from https://jorgensd.github.io/dolfinx-tutorial/chapter1/membrane_code.html"
# Create searchable data structure of current mesh
bb_tree = dolfinx.geometry.BoundingBoxTree(self.mesh, self.mesh.topology.dim)
# Initialize subset arrays
cells = []
points_on_proc = []
# Select points on current processor
for point in x.T:
# Find cells that are close to the point
cell_candidates = dolfinx.geometry.compute_collisions_point(bb_tree, point)
# Choose one of the cells that contains the point
cell = dolfinx.geometry.select_colliding_cells(self.mesh, cell_candidates, point, 1)
# Only use evaluate for points on current processor
if len(cell) == 1:
points_on_proc.append(point)
cells.append(cell[0])
# Interpolate values at points on current processor
points_on_proc = np.array(points_on_proc, dtype=np.float64)
values = self.function.eval(points_on_proc, cells)
# DEBUG: Compare output of evaluation of Expression with values from function
#IntFunc = RefSol(0.5)
#values_ref = IntFunc.interpol_displacement(x)
#error = values_ref - values.transpose()
return values.transpose()
# Set mesh
mesh = dolfinx.RectangleMesh(MPI.COMM_WORLD, [[0, 0, 0], [1, 1, 0]], [10, 10], cell_type=CellType.triangle)
# Function spaces
Pu = ufl.VectorElement('CG', mesh.ufl_cell(), 2)
Pu_t = ufl.VectorElement('CG', mesh.ufl_cell(), 4)
V = dolfinx.FunctionSpace(mesh, Pu)
V_target = dolfinx.FunctionSpace(mesh, Pu_t)
uh = dolfinx.Function(V_target)
u_target = dolfinx.Function(V_target)
# Interpolate functions
IntFunc = RefSol(0.5)
uh.interpolate(IntFunc.interpol_displacement)
uh.x.scatter_forward()
PointVal = Interpol_PointValue(mesh, uh)
u_target.interpolate(PointVal.eval_pointvalue)
u_target.x.scatter_forward()
with dolfinx.io.XDMFFile(MPI.COMM_WORLD, "test_uint-uh.xdmf", "w") as xdmf:
xdmf.write_mesh(mesh)
xdmf.write_function(uh)
with dolfinx.io.XDMFFile(MPI.COMM_WORLD, "test_uint-utarget.xdmf", "w") as xdmf:
xdmf.write_mesh(mesh)
xdmf.write_function(u_target)
Thanks!
Best wishes,
Maximilian