def spherical_point_projection_2(interpolation: str, X1: np.ndarray, X2: np.ndarray, s1: float, TOLER: float = 1e-8, MAXITER: int = 20) -> np.ndarray: n_nodes_1 = len(X1[0]) n_nodes_2 = len(X2[0]) x1 = (X1 @ intp.lagrange_polynomial(n_nodes_1 - 1, [s1])).flatten() dx1 = (X1 @ intp.lagrange_polynomial_derivative(n_nodes_1 - 1, [s1])).flatten() def R1(s): x2 = (X2 @ intp.lagrange_polynomial(n_nodes_2 - 1, [s])).flatten() dx2 = (X2 @ intp.lagrange_polynomial_derivative(n_nodes_2 - 1, [s])).flatten() d = x1 - x2 v = _triple(dx1, dx2, x1 - x2) return 1 / v * (np.dot(dx2, d) * np.cross(d, dx1) + 0.5 * np.dot(d, d) * np.cross(dx1, dx2)) def f(s): Rs = R1(s[0]) return Rs.dot(Rs) sol = optimize.brute(f, [(-1, 1)]) s2 = sol[0] x2 = (X2 @ intp.lagrange_polynomial(n_nodes_2 - 1, [s2])).flatten() R = R1(s2) return (s2, x2, R)
def circular_point_projection(interpolation: str, X1: np.ndarray, X2: np.ndarray, s1: float, TOLER: float = 1e-8, MAXITER: int = 100) -> np.ndarray: n_nodes_1 = len(X1[0]) n_nodes_2 = len(X2[0]) x1 = (X1 @ intp.lagrange_polynomial(n_nodes_1 - 1, [s1])).flatten() dx1 = (X1 @ intp.lagrange_polynomial_derivative(n_nodes_1 - 1, [s1])).flatten() x2a = (X2 @ intp.lagrange_polynomial(n_nodes_2 - 1, [s1 + 0.01])).flatten() x2b = (X2 @ intp.lagrange_polynomial(n_nodes_2 - 1, [s1 - 0.01])).flatten() u = np.zeros((5)) u[0] = s1 u[1:3] = (x1 - x2b) / 2 u[3:5] = (x2a - x1) / 2 R = np.ones((5)) i = 0 while np.linalg.norm(R) > TOLER and i < MAXITER: K = np.zeros((5, 5)) if interpolation == "Lagrange polynoms": s2 = u[0] v1 = u[1:3] v2 = u[3:5] x2 = (X2 @ intp.lagrange_polynomial(n_nodes_2 - 1, [s2])).flatten() dx2 = (X2 @ intp.lagrange_polynomial_derivative( n_nodes_2 - 1, [s2])).flatten() ddx2 = (X2 @ intp.lagrange_polynomial_2_derivative( n_nodes_2 - 1, [s2])).flatten() R[:2] = x1 - (x2 + v2 - v1) R[2] = 0 - (v2.dot(v2) - v1.dot(v1)) R[3] = 0 - (v1.dot(dx1)) R[4] = 0 - (v2.dot(dx2)) K[0, :2] = dx2 K[0, 2] = 0 K[0, 3] = 0 K[0, 4] = ddx2.dot(v2) K[1:3, :2] = -np.identity(2) K[1:3, 2] = -2 * v1 K[1:3, 3] = dx1 K[1:3, 4] = 0 K[3:5, :2] = np.identity(2) K[3:5, 2] = 2 * v2 K[3:5, 3] = 0 K[3:5, 4] = dx2 u += np.linalg.solve(K.T, R) i += 1 if i == MAXITER: print("No convergence") return False return u
def fprime(s): x2 = (X2 @ intp.lagrange_polynomial(n_nodes_2 - 1, [s])).flatten() dx2 = (X2 @ intp.lagrange_polynomial_derivative(n_nodes_2 - 1, [s])).flatten() ddx2 = (X2 @ intp.lagrange_polynomial_2_derivative(n_nodes_2 - 1, [s])).flatten() d3x2 = (X2 @ intp.lagrange_polynomial_3_derivative(n_nodes_2 - 1, [s])).flatten() d = x1 - x2 v = _triple(dx1, dx2, x1 - x2) dv = _triple(dx1, ddx2, d) ddv = _triple(dx1, d3x2, d) R1_ = 1 / v * (np.dot(dx2, d) * np.cross(d, dx1) + 0.5 * np.dot(d, d) * np.cross(dx1, dx2)) dR1_ = 1 / v * (1 / 2 * np.dot(d, d) * np.cross(dx1, ddx2) + (np.dot(ddx2, d) - np.dot(dx2, dx2) - dv / v * np.dot(dx2, d)) * np.cross(d, dx1) - 1 / 2 * dv / v * np.dot(d, d) * np.cross(dx1, dx2)) ddR1_ = (np.cross(dx1, dx2) * ((-(ddv * v) + dv * (2 * dv + v)) * np.dot(d, d) + 2 * v**2 * np.dot(d, ddx2) + 2 * v**2 * np.dot(dx2, dx2)) + 2 * np.cross(d, dx1) * ((-(ddv * v) + dv * (2 * dv + v)) * np.dot(d, dx2) + v * v * np.dot(d, d3x2) - 2 * v * dv * np.dot(d, ddx2) - 3 * v**2 * np.dot(dx2, ddx2) + 2 * v * dv * np.dot(dx2, dx2)) + v**2 * np.cross(dx1, d3x2) * np.dot(d, d) - 2 * v * np.cross(dx1, ddx2) * (dv * np.dot(d, d) + v * np.dot(d, dx2))) / (2 * v**3) return np.dot(ddR1_, R1_) + np.dot(dR1_, dR1_)
def __init__(self, parent_element: int, n_integration_points: int, possible_contact_partners: list, dual_basis_functions: bool): # -------------------------------------------------------------- # nodes self.parent = parent_element self.dof = np.zeros_like(self.parent.dof) self.dof[6] = True self.possible_contact_partners = possible_contact_partners # Lagrange multiplier interpolation if dual_basis_functions == True: self.Nlam = [ lambda x: intp.dual_basis_function(self.parent.n_nodes - 1, x) ] else: self.Nlam = [ lambda x: intp.lagrange_polynomial(self.parent.n_nodes - 1, x) ] lg = np.polynomial.legendre.leggauss(n_integration_points) self.int_pts = [ struct.IntegrationPoint(point_location=lg[0][g], weight=lg[1][g]) for g in range(len(lg[0])) ] # pre-computed values for efficiency if len(self.int_pts) > 0: self.N_displacement = self.parent.Ndis[0]( [self.int_pts[g].loc for g in range(len(self.int_pts))]) self.dN_displacement = self.parent.Ndis[1]( [self.int_pts[g].loc for g in range(len(self.int_pts))]) self.N_lagrange = self.Nlam[0]( [self.int_pts[g].loc for g in range(len(self.int_pts))])
def R1(s): x2 = (X2 @ intp.lagrange_polynomial(n_nodes_2 - 1, [s])).flatten() dx2 = (X2 @ intp.lagrange_polynomial_derivative(n_nodes_2 - 1, [s])).flatten() d = x1 - x2 v = _triple(dx1, dx2, x1 - x2) return 1 / v * (np.dot(dx2, d) * np.cross(d, dx1) + 0.5 * np.dot(d, d) * np.cross(dx1, dx2))
def f(s): x2 = (X2 @ intp.lagrange_polynomial(n_nodes_2 - 1, [s])).flatten() dx2 = (X2 @ intp.lagrange_polynomial_derivative(n_nodes_2 - 1, [s])).flatten() ddx2 = (X2 @ intp.lagrange_polynomial_2_derivative(n_nodes_2 - 1, [s])).flatten() d = x1 - x2 v = _triple(dx1, dx2, x1 - x2) R1_ = 1 / v * (np.dot(dx2, d) * np.cross(d, dx1) + 0.5 * np.dot(d, d) * np.cross(dx1, dx2)) dv = _triple(dx1, ddx2, d) dR1_ = 1 / v * (1 / 2 * np.dot(d, d) * np.cross(dx1, ddx2) + (np.dot(ddx2, d) - np.dot(dx2, dx2) - dv / v * np.dot(dx2, d)) * np.cross(d, dx1) - 1 / 2 * dv / v * np.dot(d, d) * np.cross(dx1, dx2)) return np.dot(dR1_, R1_)
def test_nearest_point_projection_1(self): correct = np.array([0, 0, 0, 5]) X = np.array([[0, 0, 0], [10, 0, 0]]).T P = np.array([5, 0, 5]) interpolation_d0 = lambda x: intp.lagrange_polynomial( degree=X.shape[1] - 1, eval_pts=x) interpolation_d1 = lambda x: intp.lagrange_polynomial_derivative( degree=X.shape[1] - 1, eval_pts=x) interpolation_d2 = lambda x: intp.lagrange_polynomial_2_derivative( degree=X.shape[1] - 1, eval_pts=x) u = proj.nearest_point_projection(interpolation_d0, interpolation_d1, interpolation_d2, X, P, s0=0, TOLER=1e-8, MAXITER=10) self.assertTrue(np.allclose(u, correct, rtol=1e-10))
def test_nearest_point_projection_2(self): correct = np.array([-0.23045933, 0.38268789, -0.0406458, -0.4820473]) X = np.array([[0, 0, 0], [1, 0, 0.4], [1.5, 0.4, 1.0], [1.2, 1.0, 1.7]]).T P = np.array([1.5, 0.0, 0.0]) interpolation_d0 = lambda x: intp.lagrange_polynomial( degree=X.shape[1] - 1, eval_pts=x) interpolation_d1 = lambda x: intp.lagrange_polynomial_derivative( degree=X.shape[1] - 1, eval_pts=x) interpolation_d2 = lambda x: intp.lagrange_polynomial_2_derivative( degree=X.shape[1] - 1, eval_pts=x) u = proj.nearest_point_projection(interpolation_d0, interpolation_d1, interpolation_d2, X, P, s0=0, TOLER=1e-8, MAXITER=10) self.assertTrue(np.allclose(u, correct, rtol=1e-10))
def lagrange_interpolation_order_n(N): # n: Number of points to use in interpolation x_ = symbols('x_0:' + str(N)) msg = "## Polinomio interpolante \nComo primer paso se construyen los polinomios de Lagrange asociados" \ + " a cada uno de los {} puntos $x_i$ solicitados para la interpolación. ".format(N) \ + "Tenga en cuenta que los polinomios serán de grado {}.".format(N-1) dmd(msg) msg = "L_{i,n}(x) = \\prod_{j=0 \\ j\\neq i}^n \\frac{x-x_j}{x_i-x_j}" dtx("$$" + msg + "$$") cont = 0 while cont < N: dtx(tex_cat(["L_{{" + str(cont) + "," + str(N) + "}}(x)=", \ lagrange_polynomial(x_, cont, x)])) cont += 1 msg = "Ahora, con los polinomios de Lagrange construidos y la evaluación de" \ + " la función en los puntos, construimos el polinomio interpolante de" \ + " grado {}, que suponemos como aproximación a la función.".format(N-1) dmd(msg) msg = "P_n(x) = \\sum_{i=0]^n f(x_i) L_{i,n}(x)" polynomial_approx = lagrange_interpolation(x_, f, x) dtx(tex_cat(["P_" + str(N) + "(x)=", polynomial_approx])) return polynomial_approx
plot_step = .001 X1 = list() Y1 = list() XC = list() YC = list() for i in np.arange(a, b, step): X1.append(i) Y1.append(f(i)) XC = interpolation.chebyshev_nodes(a, b, n) YC = list(map(f, XC)) L = interpolation.lagrange_polynomial(X1, Y1) L_func = sp.lambdify(sp.symbols('x'), L) L_c = interpolation.lagrange_polynomial(XC, YC) L_c_func = sp.lambdify(sp.symbols('x'), L_c) N = interpolation.new_newton_polynomial(X1, Y1) N_func = sp.lambdify(sp.symbols('x'), N) N_c = interpolation.new_newton_polynomial(XC, YC) N_c_func = sp.lambdify(sp.symbols('x'), N_c) Xs = list(np.arange(a, b, plot_step)) Y_f = list(map(f, Xs))
def spherical_point_projection_test(interpolation: str, X1: np.ndarray, X2: np.ndarray, s1: float, TOLER: float = 1e-8, MAXITER: int = 20) -> np.ndarray: n_nodes_1 = len(X1[0]) n_nodes_2 = len(X2[0]) x1 = (X1 @ intp.lagrange_polynomial(n_nodes_1 - 1, [s1])).flatten() dx1 = (X1 @ intp.lagrange_polynomial_derivative(n_nodes_1 - 1, [s1])).flatten() def R1(s): x2 = (X2 @ intp.lagrange_polynomial(n_nodes_2 - 1, [s])).flatten() dx2 = (X2 @ intp.lagrange_polynomial_derivative(n_nodes_2 - 1, [s])).flatten() d = x1 - x2 v = _triple(dx1, dx2, x1 - x2) return 1 / v * (np.dot(dx2, d) * np.cross(d, dx1) + 0.5 * np.dot(d, d) * np.cross(dx1, dx2)) def f(s): x2 = (X2 @ intp.lagrange_polynomial(n_nodes_2 - 1, [s])).flatten() dx2 = (X2 @ intp.lagrange_polynomial_derivative(n_nodes_2 - 1, [s])).flatten() ddx2 = (X2 @ intp.lagrange_polynomial_2_derivative(n_nodes_2 - 1, [s])).flatten() d = x1 - x2 v = _triple(dx1, dx2, x1 - x2) R1_ = 1 / v * (np.dot(dx2, d) * np.cross(d, dx1) + 0.5 * np.dot(d, d) * np.cross(dx1, dx2)) dv = _triple(dx1, ddx2, d) dR1_ = 1 / v * (1 / 2 * np.dot(d, d) * np.cross(dx1, ddx2) + (np.dot(ddx2, d) - np.dot(dx2, dx2) - dv / v * np.dot(dx2, d)) * np.cross(d, dx1) - 1 / 2 * dv / v * np.dot(d, d) * np.cross(dx1, dx2)) return np.dot(dR1_, R1_) def fprime(s): x2 = (X2 @ intp.lagrange_polynomial(n_nodes_2 - 1, [s])).flatten() dx2 = (X2 @ intp.lagrange_polynomial_derivative(n_nodes_2 - 1, [s])).flatten() ddx2 = (X2 @ intp.lagrange_polynomial_2_derivative(n_nodes_2 - 1, [s])).flatten() d3x2 = (X2 @ intp.lagrange_polynomial_3_derivative(n_nodes_2 - 1, [s])).flatten() d = x1 - x2 v = _triple(dx1, dx2, x1 - x2) dv = _triple(dx1, ddx2, d) ddv = _triple(dx1, d3x2, d) R1_ = 1 / v * (np.dot(dx2, d) * np.cross(d, dx1) + 0.5 * np.dot(d, d) * np.cross(dx1, dx2)) dR1_ = 1 / v * (1 / 2 * np.dot(d, d) * np.cross(dx1, ddx2) + (np.dot(ddx2, d) - np.dot(dx2, dx2) - dv / v * np.dot(dx2, d)) * np.cross(d, dx1) - 1 / 2 * dv / v * np.dot(d, d) * np.cross(dx1, dx2)) ddR1_ = (np.cross(dx1, dx2) * ((-(ddv * v) + dv * (2 * dv + v)) * np.dot(d, d) + 2 * v**2 * np.dot(d, ddx2) + 2 * v**2 * np.dot(dx2, dx2)) + 2 * np.cross(d, dx1) * ((-(ddv * v) + dv * (2 * dv + v)) * np.dot(d, dx2) + v * v * np.dot(d, d3x2) - 2 * v * dv * np.dot(d, ddx2) - 3 * v**2 * np.dot(dx2, ddx2) + 2 * v * dv * np.dot(dx2, dx2)) + v**2 * np.cross(dx1, d3x2) * np.dot(d, d) - 2 * v * np.cross(dx1, ddx2) * (dv * np.dot(d, d) + v * np.dot(d, dx2))) / (2 * v**3) return np.dot(ddR1_, R1_) + np.dot(dR1_, dR1_) s2array = np.linspace(-1, 1, 200) R1array = np.zeros_like(s2array) dR1array = np.zeros_like(s2array) ddR1array = np.zeros_like(s2array) for i in range(s2array.shape[0]): R1array[i] = np.linalg.norm(R1(s2array[i])) dR1array[i] = f(s2array[i]) ddR1array[i] = fprime(s2array[i]) return (s2array, R1array, dR1array, ddR1array)
def spherical_point_projection_3(interpolation: str, X1: np.ndarray, X2: np.ndarray, s1: float, TOLER: float = 1e-8, MAXITER: int = 20) -> np.ndarray: n_nodes_1 = len(X1[0]) n_nodes_2 = len(X2[0]) x1 = (X1 @ intp.lagrange_polynomial(n_nodes_1 - 1, [s1])).flatten() dx1 = (X1 @ intp.lagrange_polynomial_derivative(n_nodes_1 - 1, [s1])).flatten() def R1(s): x2 = (X2 @ intp.lagrange_polynomial(n_nodes_2 - 1, [s])).flatten() dx2 = (X2 @ intp.lagrange_polynomial_derivative(n_nodes_2 - 1, [s])).flatten() d = x1 - x2 v = _triple(dx1, dx2, x1 - x2) return 1 / v * (np.dot(dx2, d) * np.cross(d, dx1) + 0.5 * np.dot(d, d) * np.cross(dx1, dx2)) def f(s): x2 = (X2 @ intp.lagrange_polynomial(n_nodes_2 - 1, [s])).flatten() dx2 = (X2 @ intp.lagrange_polynomial_derivative(n_nodes_2 - 1, [s])).flatten() ddx2 = (X2 @ intp.lagrange_polynomial_2_derivative(n_nodes_2 - 1, [s])).flatten() d = x1 - x2 v = _triple(dx1, dx2, x1 - x2) R1_ = 1 / v * (np.dot(dx2, d) * np.cross(d, dx1) + 0.5 * np.dot(d, d) * np.cross(dx1, dx2)) dv = _triple(dx1, ddx2, d) dR1_ = 1 / v * (1 / 2 * np.dot(d, d) * np.cross(dx1, ddx2) + (np.dot(ddx2, d) - np.dot(dx2, dx2) - dv / v * np.dot(dx2, d)) * np.cross(d, dx1) - 1 / 2 * dv / v * np.dot(d, d) * np.cross(dx1, dx2)) return np.dot(dR1_, R1_) def fprime(s): x2 = (X2 @ intp.lagrange_polynomial(n_nodes_2 - 1, [s])).flatten() dx2 = (X2 @ intp.lagrange_polynomial_derivative(n_nodes_2 - 1, [s])).flatten() ddx2 = (X2 @ intp.lagrange_polynomial_2_derivative(n_nodes_2 - 1, [s])).flatten() d3x2 = (X2 @ intp.lagrange_polynomial_3_derivative(n_nodes_2 - 1, [s])).flatten() d = x1 - x2 v = _triple(dx1, dx2, x1 - x2) dv = _triple(dx1, ddx2, d) ddv = _triple(dx1, d3x2, d) R1_ = 1 / v * (np.dot(dx2, d) * np.cross(d, dx1) + 0.5 * np.dot(d, d) * np.cross(dx1, dx2)) dR1_ = 1 / v * (1 / 2 * np.dot(d, d) * np.cross(dx1, ddx2) + (np.dot(ddx2, d) - np.dot(dx2, dx2) - dv / v * np.dot(dx2, d)) * np.cross(d, dx1) - 1 / 2 * dv / v * np.dot(d, d) * np.cross(dx1, dx2)) ddR1_ = (np.cross(dx1, dx2) * ((-(ddv * v) + dv * (2 * dv + v)) * np.dot(d, d) + 2 * v**2 * np.dot(d, ddx2) + 2 * v**2 * np.dot(dx2, dx2)) + 2 * np.cross(d, dx1) * ((-(ddv * v) + dv * (2 * dv + v)) * np.dot(d, dx2) + v * v * np.dot(d, d3x2) - 2 * v * dv * np.dot(d, ddx2) - 3 * v**2 * np.dot(dx2, ddx2) + 2 * v * dv * np.dot(dx2, dx2)) + v**2 * np.cross(dx1, d3x2) * np.dot(d, d) - 2 * v * np.cross(dx1, ddx2) * (dv * np.dot(d, d) + v * np.dot(d, dx2))) / (2 * v**3) return np.dot(ddR1_, R1_) + np.dot(dR1_, dR1_) # find optimal intial start ninit = 20 s2 = np.linspace(-1, 1, ninit) Rs2 = np.zeros_like(s2) for i in range(len(s2)): Rs2[i] = np.linalg.norm(R1(s2[i])) i_min = np.argmin(Rs2) try: sol = optimize.newton(f, x0=s2[i_min], fprime=fprime, tol=1e-15) except RuntimeError: print(s2[i_min]) sol = 0 s2 = sol x2 = (X2 @ intp.lagrange_polynomial(n_nodes_2 - 1, [s2])).flatten() R = R1(s2) return (s2, x2, R)
def _spherical_point_projection(interpolation: str, X1: np.ndarray, X2: np.ndarray, s1: float, s2_0: float, TOLER: float, MAXITER: int) -> tuple: n_nodes_1 = len(X1[0]) n_nodes_2 = len(X2[0]) x1 = (X1 @ intp.lagrange_polynomial(n_nodes_1 - 1, [s1])).flatten() dx1 = (X1 @ intp.lagrange_polynomial_derivative(n_nodes_1 - 1, [s1])).flatten() s2 = s2_0 R = 1 n = 0 while abs(R) > TOLER and n < MAXITER: K = 0 if interpolation == "Lagrange polynoms": x2 = (X2 @ intp.lagrange_polynomial(n_nodes_2 - 1, [s2])).flatten() dx2 = (X2 @ intp.lagrange_polynomial_derivative( n_nodes_2 - 1, [s2])).flatten() ddx2 = (X2 @ intp.lagrange_polynomial_2_derivative( n_nodes_2 - 1, [s2])).flatten() dddx2 = (X2 @ intp.lagrange_polynomial_2_derivative( n_nodes_2 - 1, [s2])).flatten() Ai = A_(x1, x2, dx1, dx2) dAi = dA_(x1, x2, dx1, dx2, ddx2) ddAi = ddA_(x1, x2, dx1, dx2, ddx2, dddx2) Bi = B_(x1, x2, dx1, dx2) dBi = dB_(x1, x2, dx1, dx2, ddx2) ddBi = ddB_(x1, x2, dx1, dx2, ddx2, dddx2) dRR = np.zeros(3) ddRR = np.ones(3) for i in range(3): if Bi[i] != 0: dRR[i] = (dAi[i] * Ai[i] / Bi[i]**2 - Ai[i]**2 * dBi[i] / Bi[i]**3) ddRR[i] = (ddAi[i] * Ai[i] / Bi[i]**2 + dAi[i]**2 / Bi[i]**2 - 2 * dAi[i] * Ai[i] * dBi[i] / Bi[i]**3 - 2 * Ai[i] * dAi[i] * dBi[i] / Bi[i]**3 - Ai[i]**2 * ddBi[i] / Bi[i]**3 + 3 * Ai[i]**2 * dBi[i]**2 / Bi[i]**4) R = -(dRR).dot(dx1**2) K = (ddRR).dot(dx1**2) ds = R / K s2 += ds n += 1 if n == MAXITER: return False x2 = (X2 @ intp.lagrange_polynomial(n_nodes_2 - 1, [s2])).flatten() dx2 = (X2 @ intp.lagrange_polynomial_derivative(n_nodes_2 - 1, [s2])).flatten() ddx2 = (X2 @ intp.lagrange_polynomial_2_derivative(n_nodes_2 - 1, [s2])).flatten() dddx2 = (X2 @ intp.lagrange_polynomial_2_derivative(n_nodes_2 - 1, [s2])).flatten() Ai = A_(x1, x2, dx1, dx2) Bi = B_(x1, x2, dx1, dx2) R1 = np.zeros(3) for i in range(3): if Bi[i] != 0: R1[i] = Ai[i] / Bi[i] * dx1[i] return (s2, x2, R1)
def test_lagrange_polynomialnomial(self): correct = np.array([[0.195, -0.105], [0.91, 0.91], [-0.105, 0.195]]) u = intp.lagrange_polynomial(degree=2, eval_pts=[-0.3, 0.3]) self.assertTrue(np.allclose(u, correct, rtol=1e-10))
def __init__(self, nodes, mesh_dof_per_node: int, ref_vec: np.ndarray, coordinates: np.ndarray, beam=None, angular_velocities: np.ndarray = None, angular_accelerations: np.ndarray = None, distributed_load: np.ndarray = np.zeros(shape=(6)), area: float = 1.0, density: float = 0.0, elastic_modulus: float = 1.0, shear_modulus: float = 1.0, inertia_primary: float = 1.0, inertia_secondary: float = None, inertia_torsion: float = None, shear_coefficient: float = 1, contact_radius: float = 1): # -------------------------------------------------------------- # nodes dof = np.zeros(mesh_dof_per_node, dtype=np.bool) dof[:6] = True super().__init__(nodes, dof) # -------------------------------------------------------------- # defualt values if angular_velocities is None: angular_velocities = np.zeros(shape=(3, self.n_nodes)) if angular_accelerations is None: angular_accelerations = np.zeros(shape=(3, self.n_nodes)) if inertia_secondary is None: inertia_secondary = inertia_primary if inertia_torsion is None: inertia_torsion = inertia_primary # -------------------------------------------------------------- # displacement interpolation self.Ndis = [ lambda x: intp.lagrange_polynomial(self.n_nodes - 1, x), lambda x: intp.lagrange_polynomial_derivative(self.n_nodes - 1, x), lambda x: intp.lagrange_polynomial_2_derivative( self.n_nodes - 1, x), lambda x: intp.lagrange_polynomial_3_derivative( self.n_nodes - 1, x) ] # rotation interpolation self.Nrot = [ lambda x: intp.lagrange_polynomial(self.n_nodes - 1, x), lambda x: intp.lagrange_polynomial_derivative(self.n_nodes - 1, x), lambda x: intp.lagrange_polynomial_2_derivative( self.n_nodes - 1, x), lambda x: intp.lagrange_polynomial_3_derivative( self.n_nodes - 1, x) ] # integration points lgf = np.polynomial.legendre.leggauss(self.n_nodes) lgr = np.polynomial.legendre.leggauss(self.n_nodes - 1) self.int_pts = [ struct.BeamIntegrationPoint(displacement_interpolation=self.Ndis, rotation_interpolation=self.Nrot, points_location=lgf[0], weights=lgf[1]), struct.BeamIntegrationPoint(displacement_interpolation=self.Ndis, rotation_interpolation=self.Nrot, points_location=lgr[0], weights=lgr[1]) ] # Interpolation derivatives need to be corrected for # isoparametric formulation (inverse of jacobian). This is # done, when the element length is computed. # -------------------------------------------------------------- # initial element length dxds = coordinates @ self.int_pts[1].dN_displacement intg = np.zeros(shape=(3)) for i in range(len(intg)): intg[i] = np.dot(dxds[i], self.int_pts[1].wgt) L = np.linalg.norm(intg) self.jacobian = L / 2 # -------------------------------------------------------------- # initial rotation for i in range(len(self.int_pts)): self.int_pts[i].rot = np.zeros(shape=(3, 4, self.int_pts[i].n_pts)) dx = 1 / self.jacobian * coordinates @ self.int_pts[ i].dN_displacement for g in range(self.int_pts[i].n_pts): rotmat = np.zeros(shape=(3, 3)) rotmat[:, 0] = math.normalized(dx[:, g]) rotmat[:, 1] = math.normalized(np.cross(ref_vec, rotmat[:, 0])) rotmat[:, 2] = np.cross(rotmat[:, 0], rotmat[:, 1]) self.int_pts[i].rot[:, :, g] = math.rotmat_to_quat(rotmat) # -------------------------------------------------------------- # interpolate velocity, acceleration, load self.int_pts[0].w[2] = angular_velocities @ self.int_pts[0].N_rotation self.int_pts[0].a[ 2] = angular_accelerations @ self.int_pts[0].N_rotation self.int_pts[1].om[2] = np.zeros(shape=(3, self.int_pts[1].n_pts)) self.int_pts[1].q[2] = np.tile(distributed_load, reps=(self.int_pts[1].n_pts, 1)).T # -------------------------------------------------------------- # element properties self.prop = struct.BeamElementProperties( length=L, area=area, density=density, elastic_modulus=elastic_modulus, shear_modulus=shear_modulus, inertia_primary=inertia_primary, inertia_secondary=inertia_secondary, inertia_torsion=inertia_torsion, shear_coefficient=shear_coefficient, contact_radius=contact_radius)
def disp_shape_fun(int_points_locations): return intp.lagrange_polynomial(self.n_nodes - 1, int_points_locations)