I want to solve a Stokes problem in a unit square but now I get the wrong results.My code is as follows
from dolfinx import mesh,fem,plot,io
from mpi4py import MPI
from petsc4py import PETSc
from ufl import (dx,inner,dot,grad,div,sym,Identity,sin,pi,Measure,
VectorElement,FiniteElement,MixedElement,as_vector,
TrialFunction,TestFunction,split,SpatialCoordinate)
import numpy as np
domain=mesh.create_unit_square(MPI.COMM_WORLD,64,64,cell_type=mesh.CellType.triangle)
mu=fem.Constant(domain,1.0)
k=2 #degree of function space
Ve=VectorElement("CG",domain.ufl_cell(),k)
Pe=FiniteElement("CG",domain.ufl_cell(),k-1)
We=MixedElement([Ve,Pe])
W=fem.FunctionSpace(domain,We)
#boundary conditons
def no_slip(x):
return np.logical_or(np.logical_or(np.isclose(x[0],0),np.isclose(x[0],1)),
np.logical_or(np.isclose(x[1],0),np.isclose(x[1],1)))
V,_=W.sub(0).collapse()
noslip_v=fem.Function(V)
noslip_v.x.set(0)
facets=mesh.locate_entities_boundary(domain,1,no_slip)
bc=fem.dirichletbc(noslip_v,fem.locate_dofs_topological((W.sub(0),V),1,facets),W.sub(0))
#Exact solution
x=SpatialCoordinate(domain)
u3=(sin(pi*x[0])*sin(pi*x[1]))**2
u_exact=as_vector([u3.dx(1),-u3.dx(0)])
p_exact=sin(2.0*pi*x[0])*sin(3.0*pi*x[1])
I=Identity(domain.geometry.dim)
def sigma(u,p):
return 2.0*mu*sym(grad(u))-p*I
f=-div(sigma(u_exact,p_exact))
#Numerical solution
w=TrialFunction(W)
u,p=split(w)
ww=TestFunction(W)
v,q=split(ww)
a=inner(sigma(u,p),grad(v))*dx+div(u)*q*dx
L=inner(f,v)*dx
solution=fem.Function(W)
problem=fem.petsc.LinearProblem(a,L,bcs=[bc],petsc_options={"ksp_type":"preonly","pc_type":"lu"})
solution=problem.solve()
u,p=split(solution)
H1_error=np.sqrt(fem.assemble_scalar(fem.form(inner(grad(u-u_exact),grad(u-u_exact))*dx)))
print(H1_error)
The result I get is H1_error = nan.So I doubt that there is something wrong when I use LinearProblem in this mixed FEM scheme ,maybe the ksp_type and pc_type involved here but I am not sure.
Also, I have some other questions:
1.when writing u3, I import ufl.sin,ufl.pi, but when I use
u3=(np.sin(np.pi*x[0])*np.sin(np.pi*x[1]))**2
,it sends
AttributeError: 'Product' object has no attribute 'sin'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
u3=(np.sin(np.pi*x[0])*np.sin(np.pi*x[1]))**2
TypeError: loop of ufunc does not support argument 0 of type Product which has no callable sin method
2.If I want to know the matrix A from the bilinear form a and vector b from linear form L after assembling the system, is there something to show the values of them ,maybe in a list form, or array-like form? And is there a way to import them to matlab?
Thanks in advance!