# find which nodes are attached to each simplex int_idx = np.nonzero(smpid == -1)[0].tolist() roller_idx = np.nonzero((smpid >= 0) & (smpid <= 9))[0].tolist() free_idx = np.nonzero(smpid > 9)[0].tolist() # find normal vectors to each free surface node simplex_normals = simplex_outward_normals(vert,smp) free_normals = simplex_normals[smpid[free_idx]] # find the normal vectors to each roller node roller_normals = simplex_normals[smpid[roller_idx]] # find two orthogonal vectors that are parallel to the surface at each # roller node. This is used to determine the directions along which # traction forces will be constrained. Note that any two orthogonal # vectors that are parallel to the surface would do. roller_parallels1,roller_parallels2 = find_orthogonals(roller_normals) # add ghost nodes next to free and roller nodes dx = np.min(neighbors(nodes,2)[1][:,1]) nodes = np.vstack((nodes,nodes[free_idx] + dx*free_normals)) nodes = np.vstack((nodes,nodes[roller_idx] + dx*roller_normals)) # build the "left hand side" matrices for body force constraints A_body = elastic3d_body_force(nodes[int_idx+free_idx+roller_idx],nodes,lamb=lamb,mu=mu,n=n) A_body_x,A_body_y,A_body_z = (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.zeros_like(int_idx+free_idx+roller_idx) b_body_z = body_force*np.ones_like(int_idx+free_idx+roller_idx) # build the "left hand side" matrices for free surface constraints A_surf = elastic3d_surface_force(nodes[free_idx],free_normals,nodes,lamb=lamb,mu=mu,n=n) A_surf_x,A_surf_y,A_surf_z = (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)
''' import numpy as np from rbf.basis import mq from rbf.geometry import contains from rbf.nodes import menodes, neighbors import matplotlib.pyplot as plt # Define the problem domain with line segments. vert = np.array([[0.0, 0.0], [2.0, 0.0], [2.0, 1.0], [1.0, 1.0], [1.0, 2.0], [0.0, 2.0]]) smp = np.array([[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 0]]) N = 500 # total number of nodes nodes, smpid = menodes(N, vert, smp) # generate nodes edge_idx, = (smpid >= 0).nonzero() # identify edge nodes interior_idx, = (smpid == -1).nonzero() # identify interior nodes dx = np.mean(neighbors(nodes, 2)[1][:, 1]) # avg. distance to nearest neighbor eps = 0.5 / dx # shape parameter # create "left hand side" matrix A = np.empty((N, N)) A[interior_idx] = mq(nodes[interior_idx], nodes, eps=eps, diff=[2, 0]) A[interior_idx] += mq(nodes[interior_idx], nodes, eps=eps, diff=[0, 2]) A[edge_idx] = mq(nodes[edge_idx], nodes, eps=eps) # create "right hand side" vector d = np.empty(N) d[interior_idx] = -1.0 # forcing term d[edge_idx] = 0.0 # boundary condition # Solve for the RBF coefficients coeff = np.linalg.solve(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))