Hi everyone,
I work with legacy FEniCS.
I’m trying to solve the Helmholtz equation (generalized eigenproblem Ax = lambda Bx) on a 2D surface which is not a plane (like a half-sphere or the lateral surface of a cylinder). An example of such a mesh is available here: Dropbox (.h5 file). The associated .xdmf file is here: Dropbox.
What i’am doing for now is the following code:
from dolfin import *
# Read the mesh
mesh = Mesh()
with XDMFFile(mesh.mpi_comm(), mesh_walls.xdmf) as file:
file.read(mesh)
fs = FunctionSpace(mesh, "CG", 1)
gdim = mesh.topology().dim()
global_num_vertices = mesh.num_entities_global(0)
global_num_cells = mesh.num_entities_global(gdim)
print(f" Number of vertices: {global_num_vertices}") # 27866
print(f" Number of cells: {global_num_cells}") # 55428
# Variational form
u = TrialFunction(fs)
v = TestFunction(fs)
a = inner(grad(u), grad(v)) * dx
b = inner(u, v) * dx
# Assembling
a_petsc = PETScMatrix(fs.mesh().mpi_comm())
assemble(a, tensor=a_petsc)
b_petsc = PETScMatrix(fs.mesh().mpi_comm())
assemble(b, tensor=b_petsc)
# Solving
eps = SLEPc.EPS().create(mesh.mpi_comm())
eps.setOperators(a_petsc.mat(), b_petsc.mat())
eps.setProblemType(eps.ProblemType.GHEP)
eps.setType(SLEPc.EPS.Type.KRYLOVSCHUR)
eps.setTolerances(1e-6, 100000)
eps.setConvergenceTest(SLEPc.EPS.Conv.REL)
eps.setWhichEigenpairs(eps.Which.SMALLEST_MAGNITUDE)
eps.setDimensions(20, 40, SLEPc.DECIDE)
eps.view()
eps.solve()
eps.errorView()
n_modes_converged = eps.getConverged()
# Create the results vectors
vr, vi = a_petsc.mat().getVecs()
for i in range(n_modes_converged):
k = eps.getEigenpair(i, vr, vi)
error = eps.computeError(i)
if k.real > 0:
print(k.real)
This code works well for 3D meshes or 2D planes meshes. However if I use it for 2D curved manifolds (like the mesh of the example), I don’t get any error but the results are false because the curvature of the surface is not taken into account. How can I account for the curvature?