In the following geometry, I wish to define periodic boundary conditions on the left and right boundary for a linear elasticity analysis. However, I have hard time implementing it. I have defined the left and right boundary with facet tags. While implementing I get error.
gmsh.initialize()
gmsh.model.add("Winding Pack-1")
gdim = 2
mesh_comm = MPI.COMM_WORLD
model_rank = 0
h = 1
lc = 1e-3
# Added Points in the geometry
gmsh.model.geo.addPoint(0,0,0,lc,1)
gmsh.model.geo.addPoint(1,0,0,lc,2)
gmsh.model.geo.addPoint(1.5,1,0,lc,3)
gmsh.model.geo.addPoint(-0.5,1,0,lc,4)
#gmsh.model.geo.addPoint(0.3,0.3,0,lc,5)
#gmsh.model.geo.addPoint(0.7,0.3,0,lc,6)
#gmsh.model.geo.addPoint(0.7,0.6,0,lc,7)
#gmsh.model.geo.addPoint(0.3,0.6,0,lc,8)
# Added Lines in the geometry
gmsh.model.geo.addLine(1,2,1)
gmsh.model.geo.addLine(2,3,2)
gmsh.model.geo.addLine(3,4,3)
gmsh.model.geo.addLine(4,1,4)
#gmsh.model.geo.addLine(5,6,5)
#gmsh.model.geo.addLine(6,7,6)
#gmsh.model.geo.addLine(7,8,7)
#gmsh.model.geo.addLine(8,5,8)
gmsh.model.geo.addCurveLoop([1,2,3,4],1)
gmsh.model.geo.addPlaneSurface([1],1)
gmsh.model.geo.synchronize()
gmsh.model.addPhysicalGroup(1, [1], name="bottom")
gmsh.model.addPhysicalGroup(1, [2], name="right")
gmsh.model.addPhysicalGroup(1, [3], name="top")
gmsh.model.addPhysicalGroup(1, [4], name="left")
gmsh.model.addPhysicalGroup(2, [1], name="my_surface")
gmsh.option.setNumber("Mesh.CharacteristicLengthMin", h)
gmsh.option.setNumber("Mesh.CharacteristicLengthMax", h)
gmsh.model.mesh.generate(gdim)
domain, cell_markers, facet_markers = gmshio.model_to_mesh(gmsh.model, mesh_comm, model_rank, gdim=gdim)
#facet_markers.name = "Facet markers"
gmsh.write("Winding Pack-1.msh")
gmsh.fltk.run()
gmsh.finalize()
import ufl
def strain(u, repr ="vectorial"):
eps_t = sym(grad(u))
if repr =="vectorial":
return as_vector([eps_t[0,0], eps_t[1,1], 2*eps_t[0,1]])
elif repr =="tensorial":
return eps_t
E = fem.Constant(domain, 200000000000.0)
nu = fem.Constant(domain,0.3)
lmbda = E*nu/(1+nu)/(1-2*nu)
mu = E/2/(1+nu)
C = as_matrix([[lmbda+2*mu, lmbda, 0.0],[lmbda, lmbda+2*mu, 0.0],[0.0, 0.0, mu]])
def stress(u, repr ="vectorial"):
sigv = dot(C, strain(u))
if repr =="vectorial":
return sigv
elif repr =="tensorial":
return as_matrix([[sigv[0], sigv[2]], [sigv[2], sigv[1]]])
# Define Function Space
degree = 2
V = fem.functionspace(domain, ("P",degree, (gdim,)))
#Define Variational Problem
du = TrialFunction(V)
u_ = TestFunction(V)
u = fem.Function(V, name = "Displacement")
a_form = inner(stress(du),strain(u_))*dx
# Applying a uniform pressure
#rho = 7850
#g = 9.81
T = fem.Constant(domain, 1000000.0)
#fg = fem.Constant(domain, np.array([0, -rho*g]))
#fg = fem.Constant(domain, 78500.0)
#Self-weight on the surface
n = FacetNormal(domain)
#L_form = dot(-fp*n,u_) * ds(5) + dot(fg*n,u_) * ds(5)
ds = ufl.Measure("ds", domain=domain, subdomain_data=facet_markers)
L_form = dot(T*n,u_) * ds(3)
#L_form = dot(-T*n,u_) * ds(5) + dot(fg*n,u_) * ds(5)
#Boundary Conditions (simply supported on top and bottom edges)
V_ux, _ = V.sub(0).collapse()
V_uy, _ = V.sub(1).collapse()
bottom_dofs = fem.locate_dofs_topological((V.sub(1), V_uy), gdim-1, facet_markers.find(1))
top_dofs = fem.locate_dofs_topological((V.sub(1), V_uy), gdim-1, facet_markers.find(3))
left_dofs = fem.locate_dofs_topological((V.sub(0), V_ux), gdim-1, facet_markers.find(4))
right_dofs = fem.locate_dofs_topological((V.sub(0), V_ux), gdim-1, facet_markers.find(2))
ux0 = fem.Function(V_ux)
uy0 = fem.Function(V_uy)
#bcs = [fem.dirichletbc(uy0, bottom_dofs, V.sub(1)),fem.dirichletbc(ux0, left_dofs, V.sub(0)),fem.dirichletbc(uy0, top_dofs, V.sub(1)), fem.dirichletbc(ux0, right_dofs, V.sub(0))]
bcs = [fem.dirichletbc(uy0, bottom_dofs, V.sub(1))]
#bcs = [fem.dirichletbc(uy0, bottom_dofs, V.sub(1)),fem.dirichletbc(ux0, left_dofs, V.sub(0))]
#------------------------------------------------------------------------------------------------------------------------------------------
periodic_boundary = facet_markers.find(2)
#Cyclic Symmetry Condition
def periodic_relation(x):
out_x = np.zeros(x.shape)
out_x[0] = 1 - x[0]
out_x[1] = x[1]
out_x[2] = x[2]
return out_x
# Periodic boundary - topological
facets = mesh.locate_entities_boundary(domain, gdim - 1, periodic_boundary)
arg_sort = np.argsort(facet_markers)
mt = mesh.meshtags(domain, gdim - 1, facet_markers[arg_sort], np.full(len(facet_markers), 2, dtype=np.int32))
with common.Timer("~~Periodic: Compute mpc condition"):
mpc = dolfinx_mpc.MultiPointConstraint(V)
mpc.create_periodic_constraint_topological(V, mt, 2, periodic_relation, bcs)
mpc.finalize()
#-------------------------------------------------------------------------------------------------------------------------------------------
WPsolve = LinearProblem(a_form, L_form, mpc, u=u, bcs=bcs, petsc_options={"ksp_type": "preonly", "pc_type": "lu"})
WPsolve.solve()
#WPsolve = fem.petsc.LinearProblem(a_form, L_form, u=u, bcs=bcs)
#WPsolve.solve()
V0 = fem.functionspace(domain, ("DG", 0, (3,)))
sig_exp = fem.Expression(stress(u), V0.element.interpolation_points())
sig = fem.Function(V0, name="Stress")
sig.interpolate(sig_exp)
import pyvista
from dolfinx import plot
pyvista.set_jupyter_backend("static")
topology, cell_types, geometry = plot.vtk_mesh(domain, 2)
grid = pyvista.UnstructuredGrid(topology, cell_types, geometry)
p = pyvista.Plotter()
p.add_mesh(grid,show_edges=True)
p.view_xy()
p.show_axes()
p.show()
vtk = io.VTKFile(domain.comm, "wpex3.pvd", "u")
vtk.write_function(u, 0)
vtk.write_function(sig, 0)
vtk.close()