def equibiaxial_deformation(): constitutive_model = constitutive_models.Neohookean() # fem.material = materials.TitaniumAlloy() material = materials.Custom('custom material', first_lame_parameter=5, shear_modulus=3) random_deformation = operations.generate_random_deformation_gradient(plane_stress=True, equibiaxial=True) # For a range of F11 values, compute the first Piola-Kirchhoff stress f11_values = numpy.arange(.2, 1.6, .2) p11_values = [] for f11_value in f11_values: random_deformation[0][0] = f11_value random_deformation[1][1] = f11_value deformation_gradient.update_F(new_F=random_deformation, material=fem.material, constitutive_model=fem.constitutive_model, enforce_plane_stress=True) first_piola_kirchhoff_stress = fem.constitutive_model.first_piola_kirchhoff_stress( material=fem.material, deformation_gradient=deformation_gradient.F, dimension=2, test=True) p11_values.append(first_piola_kirchhoff_stress[0][0]) plt.figure() plt.plot(f11_values, p11_values, 'b', label='P11') plt.xlabel('F11') plt.ylabel('P') plt.title('Stress-strain plot for ' + fem.material.name) plt.legend(loc='best') plt.show()
def material_frame_indifference(): """Check for frame indifference of the material model by verifying that the strain energy density, first Piola-Kirchhoff stress, and numerical_differentiation_tangent_moduli all remain unchanged under a random rotation. """ # Generate a random deformation gradient random_deformation = operations.generate_random_deformation_gradient() # Choose a material and constitutive model to test material = materials.AluminumAlloy() constitutive_model = constitutive_models.Neohookean() # Compute quantities for the material model w = constitutive_model.strain_energy_density(material=material, deformation_gradient=random_deformation) p = constitutive_model.first_piola_kirchhoff_stress(material=material, deformation_gradient=random_deformation, test=True) c = constitutive_model.tangent_moduli(material=material, deformation_gradient=random_deformation, test=True) # Generate a random rotation matrix (call a separate function from operations.py) random_rotation = operations.generate_random_rotation_matrix() rotated_deformation = numpy.dot(random_rotation, random_deformation) # Compute quantities for the rotated deformation gradient w_rotated = constitutive_model.strain_energy_density(material=material, deformation_gradient=rotated_deformation) p_rotated = constitutive_model.first_piola_kirchhoff_stress(material=material, deformation_gradient=rotated_deformation, test=True) c_rotated = constitutive_model.tangent_moduli(material=material, deformation_gradient=rotated_deformation, test=True) # Test that each element is within tolerance of its original value w_error = abs(w - w_rotated) if w_error > constants.FLOATING_POINT_TOLERANCE: raise exceptions.MaterialFrameIndifferenceError(constitutive_model=constitutive_model, quantity='strain energy density', difference=w_error, tolerance=constants.FLOATING_POINT_TOLERANCE) p_errors = [] p_comparison = numpy.dot(random_rotation, p) for i in range(3): for j in range(3): p_error = abs(p_rotated[i][j] - p_comparison[i][j]) p_errors.append(p_error) p_max_error = max(p_errors) if p_max_error > constants.FLOATING_POINT_TOLERANCE: raise exceptions.MaterialFrameIndifferenceError(constitutive_model=constitutive_model, quantity='first Piola-Kirchhoff stress', difference=p_max_error, tolerance=constants.FLOATING_POINT_TOLERANCE) c_errors = [] for i in range(3): for j in range(3): for k in range(3): for l in range(3): c_comparison = 0 for m in range(3): for n in range(3): c_comparison += random_rotation[i][m] * random_rotation[k][n] * c[m][j][n][l] c_error = abs(c_rotated[i][j][k][l] - c_comparison) c_errors.append(c_error) c_max_error = max(c_errors) if c_max_error > constants.FLOATING_POINT_TOLERANCE: raise exceptions.MaterialFrameIndifferenceError(constitutive_model=constitutive_model, quantity='tangent moduli', difference=c_max_error, tolerance=constants.FLOATING_POINT_TOLERANCE)
def plane_stress(): fem = model.Model() fem.constitutive_model = constitutive_models.Neohookean() fem.material = materials.Custom(name='test', first_lame_parameter=5, shear_modulus=3) random_deformation = operations.generate_random_deformation_gradient(plane_stress=True) deformation_gradient = DeformationGradient() deformation_gradient.update_F(new_F=random_deformation, material=fem.material, constitutive_model=fem.constitutive_model, enforce_plane_stress=True)
def error_testing(): # NOTE: this test will result in an error for the default tolerance value, because this function is intended # to violate the tolerance for the purposes of showing the behavior of the error as a function of h. deformation_gradient = operations.generate_random_deformation_gradient() # uncomment for "bad" F: - numpy.eye(3) material = materials.Custom(name='custom material', first_lame_parameter=5, shear_modulus=3) constitutive_model = constitutive_models.Neohookean() (strain_energy_density, first_piola_kirchhoff_stress, tangent_moduli) = constitutive_model.calculate_all(material=material, deformation_gradient=deformation_gradient) h_values = list(numpy.logspace(-2, -10, 100)) p_errors = [] c_errors = [] for h_value in h_values: # NOTE these functions don't normally return these values p_error = tests.numerical_differentiation_first_piola_kirchhoff_stress(constitutive_model=constitutive_model, material=material, deformation_gradient=deformation_gradient, first_piola_kirchhoff_stress=first_piola_kirchhoff_stress, h=h_value) c_error = tests.numerical_differentiation_tangent_moduli(constitutive_model=constitutive_model, material=material, deformation_gradient=deformation_gradient, tangent_moduli=tangent_moduli, h=h_value) p_errors.append(p_error) c_errors.append(c_error) plt.figure() plt.plot(h_values, p_errors, 'b', label='P error') plt.plot(h_values, c_errors, 'r', label='C error') plt.xscale('log') plt.yscale('log') plt.ylim(10e-10, 10e-3) plt.title('3-point formula errors for "good" deformation gradient') plt.xlabel('h') plt.ylabel('error') plt.legend(loc='best') plt.show()
def homework1_part2(): """Plane Stress Nonlinear Elasticity: Create random deformation and calculate the material response. Check that the response satisfies a tests against numerical differentiation. """ # Initialize a new finite element model fem = model.Model() # Select constitutive model and state assumptions fem.constitutive_model = constitutive_models.Neohookean() # Create a material for the body # fem.material = materials.Custom(name='custom material', first_lame_parameter=5, shear_modulus=3) fem.material = materials.TitaniumAlloy() # Make a set of elements to add to model for i in range(100): # Initialize a random deformation gradient (with positive determinant) from which to compute other quantities random_deformation = operations.generate_random_deformation_gradient() deformation_gradient = DeformationGradient() deformation_gradient.update_F(new_F=random_deformation, material=fem.material, constitutive_model=fem.constitutive_model, enforce_plane_stress=False) (strain_energy_density, first_piola_kirchhoff_stress, tangent_moduli) = fem.constitutive_model.calculate_all(material=fem.material, deformation_gradient=random_deformation, test=True)