# x component of force resulting from displacement in the y direction. coeffs_xy = [lamb, mu] diffs_xy = [(1, 1), (1, 1)] # y component of force resulting from displacement in the x direction. coeffs_yx = [mu, lamb] diffs_yx = [(1, 1), (1, 1)] # y component of force resulting from displacement in the y direction. coeffs_yy = [lamb+2*mu, mu] diffs_yy = [(0, 2), (2, 0)] # make the differentiation matrices that enforce the PDE on the # interior nodes. D_xx = weight_matrix(nodes[groups['interior']], nodes, n, diffs_xx, coeffs=coeffs_xx) D_xy = weight_matrix(nodes[groups['interior']], nodes, n, diffs_xy, coeffs=coeffs_xy) D_yx = weight_matrix(nodes[groups['interior']], nodes, n, diffs_yx, coeffs=coeffs_yx) D_yy = weight_matrix(nodes[groups['interior']], nodes, n, diffs_yy, coeffs=coeffs_yy) G_xx = add_rows(G_xx, D_xx, groups['interior']) G_xy = add_rows(G_xy, D_xy, groups['interior']) G_yx = add_rows(G_yx, D_yx, groups['interior']) G_yy = add_rows(G_yy, D_yy, groups['interior']) # use the ghost nodes to enforce the PDE on the boundary D_xx = weight_matrix(nodes[groups['boundary:free']], nodes, n, diffs_xx, coeffs=coeffs_xx) D_xy = weight_matrix(nodes[groups['boundary:free']], nodes, n, diffs_xy, coeffs=coeffs_xy) D_yx = weight_matrix(nodes[groups['boundary:free']], nodes, n, diffs_yx, coeffs=coeffs_yx) D_yy = weight_matrix(nodes[groups['boundary:free']], nodes, n, diffs_yy, coeffs=coeffs_yy) G_xx = add_rows(G_xx, D_xx, groups['ghosts:free']) G_xy = add_rows(G_xy, D_xy, groups['ghosts:free']) G_yx = add_rows(G_yx, D_yx, groups['ghosts:free']) G_yy = add_rows(G_yy, D_yy, groups['ghosts:free']) ## Enforce fixed boundary conditions
# functions to better understand this step. N = nodes.shape[0] G_xx = sp.coo_matrix((N, N)) G_xy = sp.coo_matrix((N, N)) G_xz = sp.coo_matrix((N, N)) G_yx = sp.coo_matrix((N, N)) G_yy = sp.coo_matrix((N, N)) G_yz = sp.coo_matrix((N, N)) G_zx = sp.coo_matrix((N, N)) G_zy = sp.coo_matrix((N, N)) G_zz = sp.coo_matrix((N, N)) out = elastic3d_body_force(nodes[idx['interior']], nodes, n, lamb=lamb, mu=mu) G_xx = add_rows(G_xx, out['xx'], idx['interior']) G_xy = add_rows(G_xy, out['xy'], idx['interior']) G_xz = add_rows(G_xz, out['xz'], idx['interior']) G_yx = add_rows(G_yx, out['yx'], idx['interior']) G_yy = add_rows(G_yy, out['yy'], idx['interior']) G_yz = add_rows(G_yz, out['yz'], idx['interior']) G_zx = add_rows(G_zx, out['zx'], idx['interior']) G_zy = add_rows(G_zy, out['zy'], idx['interior']) G_zz = add_rows(G_zz, out['zz'], idx['interior']) out = elastic3d_body_force(nodes[idx['boundary:free']], nodes, n, lamb=lamb, mu=mu) G_xx = add_rows(G_xx, out['xx'], idx['ghosts:free'])
z_init = np.hstack((u_init.T.flatten(), v_init.T.flatten())) # construct a matrix that maps the displacements everywhere to the # displacements at the interior and the boundary conditions B_xx = sp.csc_matrix((n, n)) B_xy = sp.csc_matrix((n, n)) B_yx = sp.csc_matrix((n, n)) B_yy = sp.csc_matrix((n, n)) components = elastic2d_displacement(nodes[idx['interior']], nodes, lamb=lamb, mu=mu, n=stencil_size) B_xx = add_rows(B_xx, components['xx'], idx['interior']) B_yy = add_rows(B_yy, components['yy'], idx['interior']) components = elastic2d_displacement(nodes[idx['boundary:all']], nodes, lamb=lamb, mu=mu, n=stencil_size) B_xx = add_rows(B_xx, components['xx'], idx['boundary:all']) B_yy = add_rows(B_yy, components['yy'], idx['boundary:all']) components = elastic2d_surface_force(nodes[idx['boundary:all']], normals[idx['boundary:all']], nodes, lamb=lamb, mu=mu,
# create the "left hand side" matrix. # create the component which evaluates the PDE A_interior = weight_matrix(nodes[groups['interior']], nodes, n, diffs=[[2, 0], [0, 2]], phi=phi, order=order) # create the component for the fixed boundary conditions A_boundary = weight_matrix(nodes[groups['boundary:all']], nodes, 1, diffs=[0, 0]) # Add the components to the corresponding rows of `A` A = coo_matrix((N, N)) A = add_rows(A, A_interior, groups['interior']) A = add_rows(A, A_boundary, groups['boundary:all']) # create "right hand side" vector d = np.zeros((N, )) d[groups['interior']] = -1.0 d[groups['boundary:all']] = 0.0 # find the solution at the nodes u_soln = spsolve(A, d) # Create a grid for interpolating the solution xg, yg = np.meshgrid(np.linspace(0.0, 2.02, 100), np.linspace(0.0, 2.02, 100)) points = np.array([xg.flatten(), yg.flatten()]).T # We can use any method of scattered interpolation (e.g.,
# normal vectors on the free surface (i.e., n_x * du/dx + n_y * du/dy) A_free = weight_matrix(nodes[groups['boundary:free']], nodes, n, diffs=[[1, 0], [0, 1]], coeffs=[ normals[groups['boundary:free'], 0], normals[groups['boundary:free'], 1] ], phi=phi, order=order) # Add the components to the corresponding rows of `A` N = nodes.shape[0] A = coo_matrix((N, N)) A = add_rows(A, A_interior, groups['interior']) A = add_rows(A, A_ghost, groups['ghosts:free']) A = add_rows(A, A_fixed, groups['boundary:fixed']) A = add_rows(A, A_free, groups['boundary:free']) # create "right hand side" vector d = np.zeros((N, )) d[groups['interior']] = -1.0 d[groups['ghosts:free']] = -1.0 d[groups['boundary:fixed']] = 0.0 d[groups['boundary:free']] = 0.0 # find the solution at the nodes u_soln = spsolve(A, d) error = np.abs(u_soln - series_solution(nodes))