ExampleΒΆ
Note
You can download the complete python script
dirichleBcs.py
1import numpy as np
2import ufl
3import dolfinx.fem.petsc
4
5from dolfinx import fem, mesh, default_scalar_type
6from mpi4py import MPI
7
8print("--------------------------------------------------------------")
9print("-------- ILLUSTRATING DIRICHLET BC'S --------------------")
10print("--------------------------------------------------------------")
11
12L0, L1, L2 = 10., 5., 1.
13n0, n1, n2 = 10, 5, 4
14my_mesh = mesh.create_box( comm=MPI.COMM_WORLD, # creating mesh
15 points=((0.0, 0.0, 0.0),
16 (L0, L1, L2)),
17 n=(n0, n1, n2),
18 cell_type= mesh.CellType.hexahedron)
19
20gdim = my_mesh.geometry.dim
21tdim = my_mesh.geometry.dim
22print(f"gdim {gdim}, t_dim {tdim}")
23
24V = fem.functionspace(my_mesh, ("Lagrange", 1, (gdim, ))) # creating
25 # function space
26print(f"V.element {type(V.element)}")
27print(f"V.dofmap {type(V.dofmap)}")
28
29#--------------------------------------------------------------------
30# BOUNDARY CONDITIONS
31#
32# I) block all displacements on the x[0]=0 plane
33#--------------------------------------------------------------------
34def True_if_x0_is_zero(x):
35 """ locate if on the x0 = 0.0 plane """
36 #print(x.T) # turns out to be just to be a node-coordinate list
37 #print(np.isclose(x[0], 0.0))
38 return np.isclose(x[0], 0.0)
39
40dof_g_list = fem.locate_dofs_geometrical(V, True_if_x0_is_zero) # finds all points but
41 # cannot work with
42 # subspace V.sub(i)
43
44boundary_facets = mesh.locate_entities_boundary(my_mesh, gdim-1, True_if_x0_is_zero)
45boundary_edges = mesh.locate_entities_boundary(my_mesh, gdim-2, True_if_x0_is_zero)
46boundary_nodes = mesh.locate_entities_boundary(my_mesh, gdim-3, True_if_x0_is_zero)
47
48print(f"Dirichlet I")
49print(f"boundary facets on X[0] = 0 plane: {boundary_facets}")
50print(f"boundary edges on X[0] = 0 plane: {boundary_edges}")
51print(f"boundary nodes on X[0] = 0 plane: {boundary_nodes}")
52
53facets_dofs = fem.locate_dofs_topological(V, gdim-1, boundary_facets)
54
55my_mesh.topology.create_connectivity(gdim-2, gdim)
56
57edge_dofs = fem.locate_dofs_topological(V, gdim-2, boundary_edges)
58
59my_mesh.topology.create_connectivity(gdim-3, gdim)
60
61node_dofs = fem.locate_dofs_topological(V, gdim-3, boundary_nodes)
62
63print("\nAll four methods give the same dofs")
64print(f"geom_dofs on X[0] = 0 plane: {dof_g_list}")
65print(f"facets_dofs on X[0] = 0 plane: {facets_dofs}")
66print(f"edge_ dofs on X[0] = 0 plane: {edge_dofs}")
67print(f"node _dofs on X[0] = 0 plane: {node_dofs}")
68
69u_bcI = np.array([0, 0, 0], dtype=default_scalar_type)
70
71# The following four methods lead the same result
72#bcI = fem.dirichletbc(u_bcI,dof_g_list, V)
73#bcI = fem.dirichletbc(u_bcI,bcI_dofs, V)
74#bcI = fem.dirichletbc(u_bcI,dof_g_list, V)
75bcI = fem.dirichletbc(u_bcI,dof_g_list, V)
76#--------------------------------------------------------------------
77# II) prescribe u[2]= 0.0 at the edge with coordinates (L0, x[1], 0)
78#--------------------------------------------------------------------
79def True_if_on_edge(x):
80 """ locates if on the edge with (L0, x[1], 0) """
81 return np.logical_and(np.isclose(x[0], L0), np.isclose(x[2], 0.0))
82
83edge_nodes = mesh.locate_entities_boundary(my_mesh, gdim-2, True_if_on_edge)
84
85my_mesh.topology.create_connectivity(gdim-2, gdim)
86
87edge_dofs = fem.locate_dofs_topological(V, gdim-2, edge_nodes)
88edge_dofs2 = fem.locate_dofs_topological(V.sub(2), gdim-2, edge_nodes)
89
90print(f"\nDirichlet II")
91print(f"edge_dofs {edge_dofs}")
92print(f"edge_dofs2 {edge_dofs2}")
93
94u_bc_edge = 0.0
95bc_edge = fem.dirichletbc(u_bc_edge,edge_dofs2, V.sub(2))
96#--------------------------------------------------------------------
97# III) prescribe u[0], u[1] and u[2] at corner node (L0,L1,L2)
98#--------------------------------------------------------------------
99def True_if_corner(x):
100 """ locates if corner point (L0, L1, L2) """
101 check = np.logical_and(
102 np.logical_and(np.isclose(x[0], L0), np.isclose(x[1], L1)),
103 np.isclose(x[2], L2))
104 #print(f"check {check}\n")
105 return(check)
106
107corner_node = mesh.locate_entities_boundary(my_mesh, gdim-3, True_if_corner)
108
109dg_corner = fem.locate_dofs_geometrical(V, True_if_corner)
110
111corner_dof0 = fem.locate_dofs_topological(V.sub(0), gdim-3, dg_corner)
112corner_dof1 = fem.locate_dofs_topological(V.sub(1), gdim-3, dg_corner)
113corner_dof2 = fem.locate_dofs_topological(V.sub(2), gdim-3, dg_corner)
114
115print(f"\nDirichlet III")
116print(f"\ncorner_node {corner_node}")
117print(f"dg_corner {dg_corner}")
118print(f"corner_dof0 {corner_dof0}")
119print(f"corner_dof1 {corner_dof1}")
120print(f"corner_dof2 {corner_dof2}")
121
122u0_corner = 1.0*L2
123u1_corner = 1.0*L2
124u2_corner = 1.0*L2
125
126bc_corner_0 = fem.dirichletbc(u0_corner,corner_dof0, V.sub(0))
127bc_corner_1 = fem.dirichletbc(u1_corner,corner_dof1, V.sub(1))
128bc_corner_2 = fem.dirichletbc(u2_corner,corner_dof2, V.sub(2))
129#--------------------------------------------------------------------
130# CONSTITUTIVE LAW
131#--------------------------------------------------------------------
132mu = 1000.
133lamda = 1000.
134rho = 1.0
135gravity = 9.0
136
137def epsilon(u):
138 return ufl.sym(ufl.grad(u))
139
140def sigma(u):
141 return lamda * ufl.nabla_div(u) * ufl.Identity(len(u)) + 2 * mu * epsilon(u)
142#--------------------------------------------------------------------
143# VARIATIONAL PROBLEM
144#--------------------------------------------------------------------
145u = ufl.TrialFunction(V)
146v = ufl.TestFunction(V)
147ff = fem.Constant(my_mesh, default_scalar_type((0, 0, -rho*gravity)))
148a = ufl.inner(sigma(u), epsilon(v)) * ufl.dx
149L = ufl.dot(ff, v) * ufl.dx
150
151petsc_opts={"ksp_type": "preonly", "pc_type": "lu"}
152
153bcs = [bcI , bc_edge, bc_corner_0, bc_corner_1, bc_corner_2]
154problem = fem.petsc.LinearProblem(a, L, bcs=bcs, petsc_options=petsc_opts)
155uh = problem.solve()
156uh.name = "Displacement"
157#--------------------------------------------------------------------
158# OUTPUT FOR PARAVIEW
159#--------------------------------------------------------------------
160xdmffile = dolfinx.io.XDMFFile(MPI.COMM_WORLD, "Results.xdmf", "w")
161
162xdmffile.write_mesh(my_mesh)
163xdmffile.write_function(uh)
164xdmffile.close()
165