# case). Larger values may improve accuracy # generate nodes nodes, groups, _ = min_energy_nodes(N, vert, smp) # create the "left hand side" matrix. # create the component which evaluates the PDE A_interior = weight_matrix(nodes[groups['interior']], nodes, diffs=[[2, 0], [0, 2]], n=n, basis=basis, order=order) # create the component for the fixed boundary conditions A_boundary = weight_matrix(nodes[groups['boundary:all']], nodes, diffs=[0, 0]) # Add the components to the corresponding rows of `A` A = csc_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) # interpolate the solution on a grid xg, yg = np.meshgrid(np.linspace(-0.05, 2.05, 400), np.linspace(-0.05, 2.05, 400)) points = np.array([xg.flatten(), yg.flatten()]).T u_itp = LinearNDInterpolator(nodes, u_soln)(points)
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,
# 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, diffs_xx, coeffs=coeffs_xx, n=n) D_xy = weight_matrix(nodes[groups['interior']], nodes, diffs_xy, coeffs=coeffs_xy, n=n) D_yx = weight_matrix(nodes[groups['interior']], nodes, diffs_yx, coeffs=coeffs_yx, n=n) D_yy = weight_matrix(nodes[groups['interior']], nodes, diffs_yy, coeffs=coeffs_yy, n=n) 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, diffs_xx, coeffs=coeffs_xx, n=n) D_xy = weight_matrix(nodes[groups['boundary:free']], nodes, diffs_xy, coeffs=coeffs_xy, n=n) D_yx = weight_matrix(nodes[groups['boundary:free']], nodes, diffs_yx, coeffs=coeffs_yx, n=n) D_yy = weight_matrix(nodes[groups['boundary:free']], nodes, diffs_yy, coeffs=coeffs_yy, n=n) 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
# update `N` to include ghosts N = nodes.shape[0] # allocate the left-hand-side matrix components G_xx = sp.csc_matrix((N, N)) G_xy = sp.csc_matrix((N, N)) G_yx = sp.csc_matrix((N, N)) G_yy = sp.csc_matrix((N, N)) # build the "left hand side" matrices for body force constraints out = elastic2d_body_force(nodes[idx['interior']], nodes, lamb=lamb, mu=mu, n=n) G_xx = add_rows(G_xx, out['xx'], idx['interior']) G_xy = add_rows(G_xy, out['xy'], idx['interior']) G_yx = add_rows(G_yx, out['yx'], idx['interior']) G_yy = add_rows(G_yy, out['yy'], idx['interior']) out = elastic2d_body_force(nodes[idx['boundary:free']], nodes, lamb=lamb, mu=mu, n=n) G_xx = add_rows(G_xx, out['xx'], idx['ghosts:free']) G_xy = add_rows(G_xy, out['xy'], idx['ghosts:free']) G_yx = add_rows(G_yx, out['yx'], idx['ghosts:free']) G_yy = add_rows(G_yy, out['yy'], idx['ghosts:free']) out = elastic2d_body_force(nodes[idx['boundary:roller']],
G_xz = sp.csr_matrix((N, N)) G_yx = sp.csr_matrix((N, N)) G_yy = sp.csr_matrix((N, N)) G_yz = sp.csr_matrix((N, N)) G_zx = sp.csr_matrix((N, N)) G_zy = sp.csr_matrix((N, N)) G_zz = sp.csr_matrix((N, N)) out = elastic3d_body_force(nodes[idx['interior']], nodes, lamb=lamb, mu=mu, n=n) 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, lamb=lamb, mu=mu, n=n) G_xx = add_rows(G_xx, out['xx'], idx['ghosts:free'])
# derivative with respect to x and y with the x and y components of # 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=n, diffs=[[1, 0], [0, 1]], coeffs=[ normals[groups['boundary:free'], 0], normals[groups['boundary:free'], 1] ], basis=basis, order=order) # Add the components to the corresponding rows of `A` A = csc_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))
G_xy = sp.csc_matrix((N, N)) G_xz = sp.csc_matrix((N, N)) G_yx = sp.csc_matrix((N, N)) G_yy = sp.csc_matrix((N, N)) G_yz = sp.csc_matrix((N, N)) G_zx = sp.csc_matrix((N, N)) G_zy = sp.csc_matrix((N, N)) G_zz = sp.csc_matrix((N, N)) # add the body force constraints out = elastic3d_body_force(nodes[idx['interior']], nodes, lamb=lamb, mu=mu, n=n) 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']) # use the ghost nodes to enforce the body force constraints on the # free boundary out = elastic3d_body_force(nodes[idx['boundary:free']], nodes, lamb=lamb, mu=mu,
G_zx = sp.csc_matrix((node_count, node_count)) G_zy = sp.csc_matrix((node_count, node_count)) G_zz = sp.csc_matrix((node_count, node_count)) # build the "left hand side" matrices for body force constraints on # the interior nodes out = elastic3d_body_force( nodes[groups['interior']], nodes, lamb=lamb, mu=mu, n=stencil_size, basis=basis, order=poly_order) G_xx = add_rows(G_xx, out['xx'], groups['interior']) G_xy = add_rows(G_xy, out['xy'], groups['interior']) G_xz = add_rows(G_xz, out['xz'], groups['interior']) G_yx = add_rows(G_yx, out['yx'], groups['interior']) G_yy = add_rows(G_yy, out['yy'], groups['interior']) G_yz = add_rows(G_yz, out['yz'], groups['interior']) G_zx = add_rows(G_zx, out['zx'], groups['interior']) G_zy = add_rows(G_zy, out['zy'], groups['interior']) G_zz = add_rows(G_zz, out['zz'], groups['interior']) # enforce body force constraints at the boundaries using the rows # corresponding to the ghost nodes for k in ['surface', 'sides', 'bottom']: out = elastic3d_body_force(
plt.show() # allocate the left-hand-side matrix components G_xx = sp.csc_matrix((node_count, node_count)) G_xy = sp.csc_matrix((node_count, node_count)) G_yx = sp.csc_matrix((node_count, node_count)) G_yy = sp.csc_matrix((node_count, node_count)) # build the "left hand side" matrices for body force constraints out = elastic2d_body_force(nodes[idx['interior']], nodes, lamb=lamb, mu=mu, n=stencil_size, order=poly_order) G_xx = add_rows(G_xx, out['xx'], idx['interior']) G_xy = add_rows(G_xy, out['xy'], idx['interior']) G_yx = add_rows(G_yx, out['yx'], idx['interior']) G_yy = add_rows(G_yy, out['yy'], idx['interior']) out = elastic2d_body_force(nodes[idx['boundary:top']], nodes, lamb=lamb, mu=mu, n=stencil_size, order=poly_order) G_xx = add_rows(G_xx, out['xx'], idx['ghosts:top']) G_xy = add_rows(G_xy, out['xy'], idx['ghosts:top']) G_yx = add_rows(G_yx, out['yx'], idx['ghosts:top']) G_yy = add_rows(G_yy, out['yy'], idx['ghosts:top'])