B = sp.vstack((sp.hstack((B_xx, B_xy)), sp.hstack((B_yx, B_yy)))).tocsc() B += 1000.0 * sp.eye(B.shape[0]) Binv = np.linalg.inv(B.A) # construct a matrix that maps the displacements everywhere to the # body force D_xx = sp.csc_matrix((n, n)) D_xy = sp.csc_matrix((n, n)) D_yx = sp.csc_matrix((n, n)) D_yy = sp.csc_matrix((n, n)) components = elastic2d_body_force(nodes[idx['interior']], nodes, lamb=lamb, mu=mu, n=stencil_size, order=order, basis=basis) D_xx = add_rows(D_xx, components['xx'], idx['interior']) D_xy = add_rows(D_xy, components['xy'], idx['interior']) D_yx = add_rows(D_yx, components['yx'], idx['interior']) D_yy = add_rows(D_yy, components['yy'], idx['interior']) components = elastic2d_body_force(nodes[idx['boundary:all']], nodes, lamb=lamb, mu=mu, n=stencil_size, order=order, basis=basis)
boundary_groups=groups, boundary_groups_with_ghosts=['roller', 'free'], rho=node_density) # 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'])
plt.plot(nodes[v, 0], nodes[v, 1], 'o', label=k, ms=5) plt.quiver(nodes[v, 0], nodes[v, 1], normals[v, 0], normals[v, 1]) plt.legend() 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'])
(smpid == 299)))[0].tolist() # interior nodes int_idx = np.nonzero(smpid == -1)[0].tolist() # find normal vectors for each simplex simplex_normals = simplex_outward_normals(vert,smp) # find normal vectors for each boundary node roller_normals = simplex_normals[smpid[roller_idx]] free_normals = simplex_normals[smpid[free_idx]] # surface parallel vectors roller_parallels = find_orthogonals(roller_normals) # add ghost nodes next to free surface and roller nodes dx = np.min(neighbors(nodes,2)[1][:,1]) nodes = np.vstack((nodes,nodes[roller_idx] + dx*roller_normals)) nodes = np.vstack((nodes,nodes[free_idx] + dx*free_normals)) # build the "left hand side" matrices for body force constraints A_body = elastic2d_body_force(nodes[int_idx+free_idx+roller_idx],nodes,lamb=lamb,mu=mu,n=n) A_body_x,A_body_y = (hstack(i) for i in A_body) # build the "right hand side" vectors for body force constraints b_body_x = np.zeros_like(int_idx+free_idx+roller_idx) b_body_y = np.ones_like(int_idx+free_idx+roller_idx) # THIS IS WHERE GRAVITY IS IMPOSED # build the "left hand side" matrices for free surface constraints A_surf = elastic2d_surface_force(nodes[free_idx],free_normals,nodes,lamb=lamb,mu=mu,n=n) A_surf_x,A_surf_y = (hstack(i) for i in A_surf) # build the "right hand side" vectors for free surface constraints b_surf_x = np.zeros_like(free_idx) b_surf_y = np.zeros_like(free_idx) # build the "left hand side" matrices for roller constraints # constrain displacements in the surface normal direction A_roller_disp = elastic2d_displacement(nodes[roller_idx],nodes,lamb=lamb,mu=mu,n=1) A_roller_disp_x,A_roller_disp_y = (hstack(i) for i in A_roller_disp) normals_x = diags(roller_normals[:,0])
N = 5000 # total number of nodes nodes, smpid = menodes(N, vert, smp) # generate nodes interior = np.nonzero(smpid == -1)[0].tolist() # identify boundary nodes boundary = np.nonzero(smpid >= 0)[0].tolist() # identify boundary nodes Nint, Nbnd = len(boundary), len(boundary) # calculate surface normal vector for each boundary node normals = simplex_outward_normals(vert, smp)[smpid[boundary]] # dx is the shortest distance between any two nodes dx = np.min(neighbors(nodes, 2)[1][:, 1]) # add ghost nodes to greatly improve accuracy at the free surface nodes = np.vstack((nodes, nodes[boundary] + 0.5 * dx * normals)) ghost = range(N, N + len(boundary)) # ghost node indices # create differentiation matrices for the interior and boundary nodes D = elastic2d_body_force(nodes[interior + boundary], nodes, lamb=lamb, mu=mu, n=30) D = vstack([hstack(d) for d in D]) dD = elastic2d_surface_force(nodes[boundary], normals, nodes, lamb=lamb, mu=mu, n=30) dD_fuck = vstack([hstack(d) for d in dD]).tocsr() dD1 = vstack([hstack([i[:, ghost] for i in j]) for j in dD]).tocsr() dD2 = vstack([hstack([i[:, interior + boundary] for i in j]) for j in dD]).tocsr() # create initial and boundary conditions r = np.sqrt((nodes[interior + boundary, 0] - 0.5)**2 +