Hello, everybody,
I am trying to solve a system of PDEs with a weak formulation like this:
and
where I should find X_{h}, H_{h} and a_{h} each time.
My MWE is as follows:
# +
import os
from mpi4py import MPI
from petsc4py import PETSc
import numpy as np
import math
import ufl
from basix.ufl import element, mixed_element
from dolfinx import default_real_type, log, mesh
from dolfinx.fem import Function, functionspace, Expression, form
from dolfinx.fem.petsc import NonlinearProblem, LinearProblem,assemble_matrix,assemble_vector, apply_lifting
from dolfinx.io import XDMFFile, gmshio
from dolfinx.mesh import CellType, GhostMode
from dolfinx.nls.petsc import NewtonSolver
from ufl import dx, grad, inner, div,dot
# Save all logging to file
log.set_output_file("log.txt")
# -
# Next, various model parameters are defined:
dt = 5.0e-04 # time step
try:
import gmsh # type: ignore
except ImportError:
import sys
print("This demo requires gmsh to be installed")
sys.exit(0)
def gmsh_circle(model: gmsh.model, name: str) -> gmsh.model:
"""Create a Gmsh model of a circle.
"""
model.add(name)
model.setCurrent(name)
gmsh.option.setNumber("Mesh.CharacteristicLengthFactor", 0.2)
circle = model.occ.addCircle(0, 0, 0, 1, tag=1)
# Synchronize OpenCascade representation with gmsh model
model.occ.synchronize()
# Add physical marker for cells. It is important to call this
# function after OpenCascade synchronization
model.add_physical_group(dim=1, tags=[circle])
# Generate the mesh
model.mesh.generate(dim=1)
model.mesh.setOrder(2)
return model
def create_mesh(comm: MPI.Comm, model: gmsh.model, name: str, filename: str, mode: str):
"""Create a DOLFINx from a Gmsh model and output to file.
"""
msh, ct, ft = gmshio.model_to_mesh(model, comm, rank=0,gdim=2)
msh.name = name
ct.name = f"{msh.name}_cells"
ft.name = f"{msh.name}_facets"
with XDMFFile(msh.comm, filename, mode) as file:
msh.topology.create_connectivity(0, 1)
file.write_mesh(msh)
file.write_meshtags(ct, msh.geometry, geometry_xpath=f"/Xdmf/Domain/Grid[@Name='{msh.name}']/Geometry")
file.write_meshtags(ft, msh.geometry, geometry_xpath=f"/Xdmf/Domain/Grid[@Name='{msh.name}']/Geometry")
gmsh.initialize()
gmsh.option.setNumber("General.Terminal", 0)
# Create model
model = gmsh.model()
model = gmsh_circle(model, "circle")
model.setCurrent("circle")
create_mesh(MPI.COMM_SELF, model, "circle", f"out_gmsh/mesh_rankCircle_{MPI.COMM_WORLD.rank}.xdmf", "w")
with XDMFFile(MPI.COMM_WORLD, "out_gmsh/mesh_rankCircle_0.xdmf", "r") as xdmf:
mesh = xdmf.read_mesh(name="circle")
mesh.topology.create_connectivity(mesh.topology.dim-1, mesh.topology.dim)
gmsh.finalize
P1 = element("Lagrange", mesh.basix_cell(), 2, gdim=2)
ME = functionspace(mesh, mixed_element([P1, P1],gdim=2))
n = ufl.CellNormal(mesh)
x = ufl.SpatialCoordinate(mesh)
r = x/ufl.sqrt(ufl.dot(x, x))
sign = ufl.sign(ufl.dot(n, r))
n_oriented = sign*n
V1 = element("Lagrange", mesh.basix_cell(), 2, shape=(mesh.geometry.dim,), gdim=2)
V2 = element("Lagrange", mesh.basix_cell(), 2, gdim=2)
ME2 = functionspace(mesh, mixed_element([V1, V2],gdim=2))
# Trial and test functions of the space `ME` are now defined:
q, v = ufl.TestFunctions(ME)
Xi, phi = ufl.TestFunctions(ME2)
# ```{index} split functions
# ```
# +
u = Function(ME) # current solution
u0 = Function(ME) # solution from previous converged step
X = Function(ME2) # current solution
X0 = Function(ME2) # solution from previous converged step
(Xh, H) = ufl.TrialFunctions(ME2) # current solution
(Xh0, H0) = ufl.TrialFunctions(ME2) # solution from previous converged step
# Split mixed functions
u1, u2 = ufl.split(u)
u10, u20 = ufl.split(u0)
au = 0.9
bu = 1.1
av = 0.8
bv = 0.95
# Interpolate initial condition
u.sub(0).interpolate(lambda x: (bu-au)*np.random.rand(x.shape[1]) +au)
u.sub(1).interpolate(lambda x: (bv-av)*np.random.rand(x.shape[1]) +av)
u.x.scatter_forward()
V01, _ = ME2.sub(0).collapse()
V02, _ = ME2.sub(1).collapse()
x_exp = Expression(x, V01.element.interpolation_points())
H_exp = Expression(div(sign*n), V02.element.interpolation_points())
X.sub(0).interpolate(x_exp)
X.sub(1).interpolate(H_exp)
# -
u0.x.array[:] = u.x.array
X0.x.array[:] = X.x.array
u_vec = ufl.as_vector([u1, u2])
kp = ufl.as_vector([1.5, 0])
Xh0
# Weak statement of the equations
k = dt
d = 8.8676
gamma = 379.2100
a = 0.1
b = 0.9
tol = 1e-4
d1 = 1.0
d2 = d
ks = 25
kb = 3
F = ((u1 - u10) / k)*q*dx + d1*inner(grad(u1), grad(q))*dx\
-(gamma*(u1*u1*u2-u1+a))*q*dx \
+ ((u2 - u20) / k)*v*dx + d2*inner(grad(u2), grad(v))*dx\
-(gamma*(-u1*u1*u2+b))*v*dx
#F_x = inner(((Xh - Xh0) / k),n_oriented)*phi*dx + ks*H*phi*dx \
# +kb*inner(grad(H),grad(phi))*dx - dot(kp,u_vec)*phi*dx \
# + inner(H*n_oriented,Xi)*dx - inner(grad(Xh),grad(Xi))*dx
ax = inner((Xh / k),
n_oriented)*phi*dx + ks*H*phi*dx \
+ kb*inner(grad(H),grad(phi))*dx \
+ inner(H*n_oriented,Xi)*dx - inner(grad(Xh),grad(Xi))*dx
Lx = inner((Xh0 / k),n_oriented)*phi*dx + dot(kp,u_vec)*phi*dx
# Create nonlinear problem and Newton solver
problem = NonlinearProblem(F, u)
solver = NewtonSolver(MPI.COMM_WORLD, problem)
solver.convergence_criterion = "incremental"
solver.rtol = np.sqrt(np.finfo(default_real_type).eps) * 1e-2
# We can customize the linear solver
ksp = solver.krylov_solver
opts = PETSc.Options() # type: ignore
option_prefix = ksp.getOptionsPrefix()
opts[f"{option_prefix}ksp_type"] = "preonly"
opts[f"{option_prefix}pc_type"] = "lu"
ksp.setFromOptions()
problemX = LinearProblem(ax, Lx)
...
The nonlinear problem works well, but I cannot define the Linear Problem for the second system. I have already tried to implement the problem with different formulations but am not able to find what produces the error. I think I’m confusing the use of ‘Function’ and ‘TrialFunction’ because I’m not sure if I’ve defined the initial conditions correctly either.
The error I obtain is something like this:
Traceback (most recent call last):
File "/home/sdcardozof/anaconda3/envs/fenicsx-env/lib/python3.12/site-packages/ffcx/codegeneration/jit.py", line 68, in get_cached_module
open(c_filename, "x")
FileExistsError: [Errno 17] File exists: '/home/sdcardozof/.cache/fenics/libffcx_forms_04fbc351847d98607131abeed21bfe8eee7e567f.c'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/mnt/d/Universidad/UBC/CodesFenics/SchnakenbergFx2D_circle_moving_V2.py", line 196, in <module>
problemX = LinearProblem(ax, Lx)
^^^^^^^^^^^^^^^^^^^^^
...
File "/home/sdcardozof/anaconda3/envs/fenicsx-env/lib/python3.12/site-packages/dolfinx/fem/petsc.py", line 627, in __del__
self._solver.destroy()
^^^^^^^^^^^^
AttributeError: 'LinearProblem' object has no attribute '_solver'
Thanks in advance