def solver(mesh_name, material, body_forces, traction_imposed, displacement_imposed, period, steps, u0, v0, plot_undeformed, plot_stress, plot_deformed): mesh = gmsh.parse(mesh_name) s = mesh.surfaces mat_dic = {s[i]: material[j] for i, j in enumerate(material)} k_ele = element2dof.stiffness(mesh, mat_dic) p0q_ele = element2dof.body_forces(mesh, body_forces) m_ele = element2dof.mass(mesh, mat_dic) k = assemble2dof.global_matrix(k_ele, mesh) m = assemble2dof.global_matrix(m_ele, mesh) p0q = assemble2dof.global_vector(p0q_ele, mesh) p0t = boundaryconditions2dof.neumann(mesh, traction_imposed) p0 = p0q + p0t km, p0m = boundaryconditions2dof.dirichlet(k, p0, mesh, displacement_imposed) mm, p0m = boundaryconditions2dof.dirichlet(m, p0, mesh, displacement_imposed) timestep.iterations(period, steps, u0, v0, mesh, mat_dic, km, mm, p0m, interval=1) '''
def neumann(mesh, traction): """Apply Neumann BC. Computes the integral from the weak form with the boundary term. .. note:: How its done: 1. Define an array with the Gauss points for each path, each path will have 2 sets of two gauss points. One of the gp is fixed, which indicates that its going over an specific boundary of the element. Gauss points are defines as:: gp = [gp, -1 1st path --> which has 2 possibilities for gp. 1, gp 2nd path gp, 1 3rd -1, gp] 4th 2. A loop over the elements on the boundary extracting also the side where the boundary is located on this element. .. note:: Edge elements are necessary because we need to extract the nodes from the connectivity. Then we can create a T for this element. Args: traction: Function with the traction and the line where the traction is applied. mesh: Object with the mesh attributes. Returns: T: Traction vector with size equals the dof. """ Tele = np.zeros((8, mesh.num_ele)) gp = np.array([[[-1.0/math.sqrt(3), -1.0], [1.0/math.sqrt(3), -1.0]], [[1.0, -1.0/math.sqrt(3)], [1.0, 1.0/math.sqrt(3)]], [[-1.0/math.sqrt(3), 1.0], [1.0/math.sqrt(3), 1.0]], [[-1.0, -1.0/math.sqrt(3)], [-1.0, 1.0/math.sqrt(3)]]]) for line in traction(1,1).keys(): if line[0] == 'line': for ele, side, l in mesh.boundary_elements: if l == line[1]: for w in range(2): mesh.basisFunction2D(gp[side, w]) mesh.eleJacobian(mesh.nodes_coord[mesh.ele_conn[ele, :]]) x1_o_e1e2, x2_o_e1e2 = mesh.mapping(ele) t = traction(x1_o_e1e2, x2_o_e1e2) dL = mesh.ArchLength[side] Tele[0, ele] += mesh.phi[0]*t[line][0]*dL Tele[1, ele] += mesh.phi[0]*t[line][1]*dL Tele[2, ele] += mesh.phi[1]*t[line][0]*dL Tele[3, ele] += mesh.phi[1]*t[line][1]*dL Tele[4, ele] += mesh.phi[2]*t[line][0]*dL Tele[5, ele] += mesh.phi[2]*t[line][1]*dL Tele[6, ele] += mesh.phi[3]*t[line][0]*dL Tele[7, ele] += mesh.phi[3]*t[line][1]*dL T = assemble2dof.global_vector(Tele, mesh) for n in traction(1, 1).keys(): if n[0] == 'node': t = traction(1,1) T[2*n[1]] = t[n][0] T[2*n[1]+1] = t[n][1] return T