Exchanging the mesh in fenics

Hello,

I wanted to know if it is possible to exchange the mesh in fenics without having to reinstantiate everything. Basically, the problem boils down to: Can I use one mesh, define a function space, functions and variational forms, (perhaps solve them), then exchange the underlying mesh, and solve the same equations again, but on the new mesh without having to define everything again?

What I want to do is not (necessarily) to change the geometry, but to change the number of nodes and cells.

I provide a MWE below, which shows that my naive approach of using a MeshEditor on an already defined mesh does not yield the desired results.

import numpy as np
from fenics import *

mesh = UnitSquareMesh(3, 3)
V = FunctionSpace(mesh, "CG", 1)
print(V.dim())  # 16
print(mesh.num_vertices())  # 16
print(hex(id(mesh)))  # memory location

u = Function(V)
x = SpatialCoordinate(mesh)
u.vector()[:] = project(x[0], V).vector()[:]

editor = MeshEditor()
editor.open(mesh, "triangle", 2, 2)
editor.init_vertices(4)
editor.init_cells(2)
editor.add_vertex(0, np.array([0.0, 0.0]))
editor.add_vertex(1, np.array([1.0, 0.0]))
editor.add_vertex(2, np.array([0.0, 1.0]))
editor.add_vertex(3, np.array([1.0, 1.0]))
editor.add_cell(0, np.array([0, 1, 3], dtype=np.uintp))
editor.add_cell(1, np.array([0, 2, 3], dtype=np.uintp))
editor.close()

print(V.dim())  # still 16
print(mesh.num_vertices())  # 4
print(hex(id(mesh)))  # same memory location as before

When you run the script, you can see that the memory location of the mesh stays the same, that the number of mesh vertices changes as desired, but the dimension of the corresponding CG1 function space V does not.

So is there any way to make fenics do what I want?
Thanks a lot for the help and best regards,
Sebastian

No, this is not possible. A FunctionSpace needs to be reinitialized, as you change the dofmap when changing the nesh.

Similarly all data dependent on the FunctionSpace had to be reinitialized. However, certain things (such as code generation) is cached and reused

Okay, thanks a lot for clarifying this.

A brief follow up: So I would have to call

V.__init__(mesh, 'CG', 1)

in order to reinitialize the function space, and it would be necessary to define a new function u, etc. In particular, if I have defined a form, say

a = dot(grad(u), grad(u))*dx

I cannot reuse this, but have to re-define the entire form for the new function on the reinitialized space?
I mean, maybe I could exchange the form arguments with ufl.replace, but this would still be bad for my application…

Yes, you would have to redefine the form, but under the hood it will use the cache for the generated code, and should therefore not be expensive.

Okay, thanks a lot for your quick replies.