Yes effectively, I made a mistake in the code that I sent you.
However, This still don’t work.
Have I to modifie “a” in the preconditioner ?
It’s very weird.
Thanks for your help.
My code without errors :
from netgen.occ import *
from ngsolve import *
# Variable
E = 210000
nu = 0.3
# Dirichlet Boundaries
Face_Dirichletx = 'Face4'
Face_Dirichlety = 'Face4'
Face_Dirichletz = 'Face4'
# Displacement boundary
FaceDisplacement = 'Face2'
# Degree of Element
EleDeg = 2
# Mesh the geometry and get the boundaries --------------------------------------------------
box = Box((0,-10,-10), (200,10,10))
box.faces.Max(X).name="Face4"
box.faces.Min(X).name="Face2"
geo = OCCGeometry(box)
mesh = Mesh(geo.GenerateMesh(maxh=6)).Curve(3)
boundaries = list(mesh.GetBoundaries())
# Stress Function ----------------------------------------------------------------------------
mu = E / 2 / (1 + nu)
lam = E * nu / ((1 + nu) * (1 - 2 * nu))
def Stress(strain):
return 2 * mu * strain + lam * Trace(strain) * Id(3)
# FE Space ---------------------------------------------------------------------------------
fes = VectorH1(mesh, order=EleDeg, dirichletx=Face_Dirichletx, dirichlety=Face_Dirichlety, dirichletz=Face_Dirichletz)
u, v = fes.TnT()
gfu = GridFunction(fes)
# Apply displacement boundary condition -----------------------------------------------------
displacement = CF((0, 0, 100))
gfu.Set(displacement, definedon=mesh.Boundaries(FaceDisplacement))
# Assemble a ----------------------------------------------------------------------------
with TaskManager():
a = BilinearForm(InnerProduct(Stress(Sym(Grad(u))), Sym(Grad(v))).Compile() * dx)
pre = Preconditioner(a, "bddc")
a.Assemble()
# Create zero force as there is no force applied -------------------------------------------
force = CF((0, 0, 1))
f = LinearForm(fes)
# f += force * v * ds(FaceDisplacement)
f.Assemble()
# Run the Solver --------------------------------------------------------------------------
from ngsolve.krylovspace import CGSolver
inv = CGSolver(a.mat, pre, printrates='\r', tol=1e-6, maxiter=500)
gfu.vec.data = inv * f.vec
# Print Result --------------------------------------------------------------------------
with TaskManager():
EFstress = MatrixValued(H1(mesh, order=EleDeg), symmetric=True)
VMstress = GridFunction(EFstress)
VMstress.Interpolate(Stress(Sym(Grad(gfu))))