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