def calculate_stiffness_matrix(self, test=False, rank=False): """Computes the 4th order stiffness tensor for the element using Gauss quadrature. Runs for each deformed configuration in the analysis. Uses the 2D effective covariant tangent moduli, deformed midsurface basis vectors, kirchhoff stress, and differential area to account for the curvilinear coordinate system. :param bool test: whether to perform numerical differentiation check on the result :param bool rank: whether to check the rank of the stiffness matrix """ # Initialize stiffness matrix to be computed using Gauss quadrature dimensions = (self.degrees_of_freedom, self.node_quantity, self.degrees_of_freedom, self.node_quantity) stiffness_matrix = numpy.zeros(dimensions) # Sum over quadrature points for quadrature_point in self.quadrature_points: # Initialize integrand to be computed for this quadrature point integrand = numpy.zeros(dimensions) for dof_1 in range(self.degrees_of_freedom): for node_index_1 in range(self.node_quantity): for dof_2 in range(self.degrees_of_freedom): for node_index_2 in range(self.node_quantity): # Sum over repeated indices for coordinate_index_1 in range(self.dimension): for coordinate_index_2 in range(self.dimension): for coordinate_index_3 in range(self.dimension): for coordinate_index_4 in range(self.dimension): integrand[dof_1][node_index_1][dof_2][node_index_2] += ( (2 * quadrature_point.tangent_moduli_effective_2d[coordinate_index_1][ coordinate_index_2][coordinate_index_3][coordinate_index_4] * numpy.outer(quadrature_point.current_configuration.midsurface_basis[ coordinate_index_2], quadrature_point.current_configuration.midsurface_basis[ coordinate_index_4])[dof_1][dof_2] + .5 * quadrature_point.kirchhoff_stress[coordinate_index_1][ coordinate_index_2] * (dof_1 == dof_2) * (coordinate_index_2 == coordinate_index_3) ) * self.shape_function_derivatives(node_index=node_index_1, position=quadrature_point.position, coordinate_index=coordinate_index_1) * self.shape_function_derivatives(node_index=node_index_2, position=quadrature_point.position, coordinate_index=coordinate_index_3) ) # Weight the integrand integrand *= quadrature_point.weight # Add the integrand to the stiffness matrix stiffness_matrix += integrand # Scale the stiffness matrix for isoparametric triangle and multiply by the thickness and differential area stiffness_matrix *= .5 * self.thickness * self.reference_configuration.differential_area if test: tests.numerical_differentiation_stiffness_matrix(element=self, stiffness_matrix=stiffness_matrix) if rank: tests.rank_stiffness_matrix(element=self, stiffness_matrix=stiffness_matrix) return stiffness_matrix
def calculate_stiffness_matrix_old(self, test=False, rank=True): """Computes the 4th order stiffness tensor for the element using Gauss quadrature. Runs for each deformed configuration in the analysis. OLD: uses inverse jacobian and 2D tangent moduli C_iJkL. :param bool test: whether to perform numerical differentiation check on the result :param bool rank: whether to check the rank of the stiffness matrix """ # Initialize stiffness matrix to be computed using Gauss quadrature dimensions = (self.degrees_of_freedom, self.node_quantity, self.degrees_of_freedom, self.node_quantity) stiffness_matrix = numpy.zeros(dimensions) # Sum over quadrature points for quadrature_point in self.quadrature_points: # Initialize integrand to be computed for this quadrature point integrand = numpy.zeros(dimensions) for dof_1 in range(self.degrees_of_freedom): for node_index_1 in range(self.node_quantity): for dof_3 in range(self.degrees_of_freedom): for node_index_2 in range(self.node_quantity): # Sum over repeated indices for dof_2 in range(self.degrees_of_freedom): for dof_4 in range(self.degrees_of_freedom): for coordinate_index_1 in range(self.dimension): for coordinate_index_2 in range(self.dimension): integrand[dof_1][node_index_1][dof_3][node_index_2] += ( quadrature_point.tangent_moduli[dof_1][dof_2][dof_3][dof_4] * self.shape_function_derivatives( node_index=node_index_1, position=quadrature_point.position, coordinate_index=coordinate_index_1) * self.shape_function_derivatives( node_index=node_index_2, position=quadrature_point.position, coordinate_index=coordinate_index_2) * self.jacobian_matrix_inverse[coordinate_index_1][dof_2] * self.jacobian_matrix_inverse[coordinate_index_2][dof_4]) # Weight the integrand integrand *= quadrature_point.weight # Add the integrand to the stiffness matrix stiffness_matrix += integrand # Scale the stiffness matrix for isoparametric triangle and multiply by the thickness (assumed to be constant) stiffness_matrix *= .5 * self.thickness if test: tests.numerical_differentiation_stiffness_matrix(element=self, stiffness_matrix=stiffness_matrix) if rank: tests.rank_stiffness_matrix(element=self, stiffness_matrix=stiffness_matrix) return stiffness_matrix