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()
Exemplo n.º 2
0
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)