I need to adapt a shape optimization example for my use case. The unknown solution field is complex and hence I need to work with the complex build. While porting to the recent version, I run into errors that I do not encounter in the real mode. I would appreciate if someone could point out the mistake.
Below is an MWE evaluated on complex build of 0.10 installed from conda:
import dolfinx, ufl, gmsh, mpi4py
gmsh.initialize()
gmsh.clear()
gmsh.option.setNumber("General.Terminal", 0)
occ = gmsh.model.occ
gdim = 2
b1 = occ.addRectangle(0, 0, 0, 1, 1)
occ.synchronize()
# add_sub physical tags
all_doms = occ.getEntities(gdim)
for j, dom in enumerate(all_doms):
gmsh.model.addPhysicalGroup(dom[0], [dom[1]], j + 1) # create the main group/node
# number all boundaries
all_edges = occ.getEntities(gdim-1)
for j, edge in enumerate(all_edges):
gmsh.model.addPhysicalGroup(edge[0], [edge[1]], edge[1]) # create the main group/node
gmsh.model.mesh.generate(gdim)
mpi_rank = 0
mesh_data = dolfinx.io.gmsh.model_to_mesh(gmsh.model, mpi4py.MPI.COMM_WORLD, mpi_rank, gdim)
mesh, ct, ft = mesh_data.mesh, mesh_data.cell_tags, mesh_data.facet_tags
fem_order = 2
Omega = dolfinx.fem.functionspace(mesh, ("CG", fem_order))
u = ufl.TrialFunction(Omega)
ut = ufl.TestFunction(Omega)
dx = ufl.Measure("dx", domain=mesh, subdomain_data=ct)
ds = ufl.Measure("ds", domain=mesh, subdomain_data=ft)
R = ufl.inner(ufl.grad(u), ufl.grad(ut))*dx
zero = dolfinx.fem.Constant(mesh, dolfinx.default_scalar_type(0.0))
R += ufl.inner(zero, ut)*dx
u_sol = dolfinx.fem.Function(Omega)
petsc_options = {"ksp_type": "preonly", "pc_type": "lu", "pc_factor_mat_solver_type": "mumps"}
import dolfinx.fem.petsc
dbc = []
fwd_solver = dolfinx.fem.petsc.LinearProblem(ufl.lhs(R), ufl.rhs(R), u=u_sol, bcs=dbc, petsc_options_prefix="fwd_",petsc_options=petsc_options)
fwd_solver.solve()
lmbda = dolfinx.fem.Function(Omega)
J = ufl.inner(u_sol, u_sol) * dx
L = ufl.replace(ufl.action(R, u_sol), {ut: lmbda}) + J
dRdu = ufl.derivative(ufl.action(R, u_sol), u_sol, u)
dRdu_adj = ufl.adjoint(dRdu)
dJdu = ufl.derivative(J, u_sol, ufl.conj(ut))
dbc_adj = []
# This gives error
adj_solver = dolfinx.fem.petsc.LinearProblem(ufl.replace(dRdu_adj, {u_sol: ut}), -dJdu, u=lmbda, bcs=dbc_adj,
petsc_options_prefix="adj_", petsc_options=petsc_options)
adj_solver.solve()
X = ufl.SpatialCoordinate(mesh)
W = dolfinx.fem.functionspace(mesh, mesh.ufl_domain().ufl_coordinate_element())
dL = ufl.derivative(L, X, ufl.TestFunction(W))
dLf = dolfinx.fem.form(dL) # this gives error too in complex mode