# 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) b_surf_z = np.zeros_like(free_idx) # build the "left hand side" matrices for roller constraints # constrain displacements in the surface normal direction A_roller = elastic3d_displacement(nodes[roller_idx],nodes,lamb=lamb,mu=mu,n=1) A_roller_x,A_roller_y,A_roller_z = (hstack(i) for i in A_roller) normals_x = diags(roller_normals[:,0]) normals_y = diags(roller_normals[:,1]) normals_z = diags(roller_normals[:,2]) A_roller_n = (normals_x.dot(A_roller_x) + normals_y.dot(A_roller_y) + normals_z.dot(A_roller_z))
G_yz = add_rows(G_yz, out['yz'], groups['ghosts:' + k]) G_zx = add_rows(G_zx, out['zx'], groups['ghosts:' + k]) G_zy = add_rows(G_zy, out['zy'], groups['ghosts:' + k]) G_zz = add_rows(G_zz, out['zz'], groups['ghosts:' + k]) # build the "left hand side" matrices for traction force constraints # on the surface and the sides. These are used to enforce a free # surface and tectonic stresses for k in ['surface', 'sides']: out = elastic3d_surface_force( nodes[groups['boundary:' + k]], normals[groups['boundary:' + k]], nodes, lamb=lamb, mu=mu, n=stencil_size, basis=basis, order=poly_order) G_xx = add_rows(G_xx, out['xx'], groups['boundary:' + k]) G_xy = add_rows(G_xy, out['xy'], groups['boundary:' + k]) G_xz = add_rows(G_xz, out['xz'], groups['boundary:' + k]) G_yx = add_rows(G_yx, out['yx'], groups['boundary:' + k]) G_yy = add_rows(G_yy, out['yy'], groups['boundary:' + k]) G_yz = add_rows(G_yz, out['yz'], groups['boundary:' + k]) G_zx = add_rows(G_zx, out['zx'], groups['boundary:' + k]) G_zy = add_rows(G_zy, out['zy'], groups['boundary:' + k])
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_xz = add_rows(G_xz, out['xz'], 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']) G_yz = add_rows(G_yz, out['yz'], idx['ghosts:free']) G_zx = add_rows(G_zx, out['zx'], idx['ghosts:free']) G_zy = add_rows(G_zy, out['zy'], idx['ghosts:free']) G_zz = add_rows(G_zz, out['zz'], idx['ghosts:free']) out = elastic3d_surface_force(nodes[idx['boundary:free']], normals[idx['boundary:free']], nodes, lamb=lamb, mu=mu, n=n) G_xx = add_rows(G_xx, out['xx'], idx['boundary:free']) G_xy = add_rows(G_xy, out['xy'], idx['boundary:free']) G_xz = add_rows(G_xz, out['xz'], idx['boundary:free']) G_yx = add_rows(G_yx, out['yx'], idx['boundary:free']) G_yy = add_rows(G_yy, out['yy'], idx['boundary:free']) G_yz = add_rows(G_yz, out['yz'], idx['boundary:free']) G_zx = add_rows(G_zx, out['zx'], idx['boundary:free']) G_zy = add_rows(G_zy, out['zy'], idx['boundary:free']) G_zz = add_rows(G_zz, out['zz'], idx['boundary:free']) out = elastic3d_displacement(nodes[idx['boundary:fix']], nodes, lamb=lamb,
normals = simplex_normals[smpid[free_idx]] # add ghost nodes next to free surface nodes dx = np.min(neighbors(nodes, 2)[1][:, 1]) nodes = np.vstack((nodes, nodes[free_idx] + dx * normals)) # The "left hand side" matrices are built with the convenience # functions from *rbf.fdbuild*. Read the documentation for these # functions to better understand this step. A = elastic3d_body_force(nodes[int_idx + free_idx], nodes, lamb=lamb, mu=mu, n=n) A += elastic3d_surface_force(nodes[free_idx], normals, nodes, lamb=lamb, mu=mu, n=n) A += elastic3d_displacement(nodes[fix_idx], nodes, lamb=lamb, mu=mu, n=1) A = vstack(hstack(i) for i in A).tocsr() # Create the "right hand side" vector components for body forces f_x = np.zeros(len(int_idx + free_idx)) f_y = np.zeros(len(int_idx + free_idx)) f_z = body_force * np.ones( len(int_idx + free_idx)) # THIS IS WHERE GRAVITY IS ADDED f = np.hstack((f_x, f_y, f_z)) # Create the "right hand side" vector components for surface tractions # constraints fix_x = np.zeros(len(fix_idx)) fix_y = np.zeros(len(fix_idx)) fix_z = np.zeros(len(fix_idx))