Пример #1
0
def strain_energy():
    C_al3Mg = np.array([[0.64, 0.24, 0.24, 0,   0,   0],
                        [0.24, 0.64, 0.24, 0,   0,   0],
                        [0.24, 0.24, 0.64, 0,   0,   0],
                        [0,   0,   0,   0.65, 0,   0],
                        [0,   0,   0,   0,   0.65, 0],
                        [0,   0,   0,   0,   0,   0.65]])

    C_al = np.array([[0.63, 0.41, 0.41, 0,   0,   0],
                     [0.41, 0.63, 0.41, 0,   0,   0],
                     [0.41, 0.41, 0.63, 0,   0,   0],
                     [0,   0,   0,   0.43, 0,   0],
                     [0,   0,   0,   0,   0.43, 0],
                     [0,   0,   0,   0,   0,   0.43]])
    C_al = np.array([[0.62639459, 0.41086487, 0.41086487, 0, 0, 0],
            [0.41086487, 0.62639459, 0.41086487, 0, 0, 0],
            [0.41086487, 0.41086487, 0.62639459, 0, 0, 0],
            [0, 0, 0, 0.42750351, 0, 0],
            [0, 0, 0, 0, 0.42750351, 0],
            [0, 0, 0, 0, 0, 0.42750351]])


    eigenstrain = [0.023, 0.023, 0.023, 0.0, 0.0, 0.0]
    mu_al = 0.34876
    mu_al3mg = 0.20835377082353254
    poisson = 0.5*(mu_al + mu_al3mg)
    poisson = mu_al
    strain_energy = StrainEnergy(eigenstrain=eigenstrain, poisson=poisson)
    print(strain_energy.is_isotropic(C_al))
    energy = strain_energy.strain_energy(C_matrix=C_al, C_prec=C_al3Mg)
    v_per_atom = 16.60753125
    print(energy*1000.0*v_per_atom)
    print(energy*1000.0)
Пример #2
0
def explore_orientations():
    from cemc.tools import StrainEnergy
    from matplotlib import pyplot as plt
    mu = 0.27155342515650893
    C_al = C_al = np.array([[0.62639459, 0.41086487, 0.41086487, 0, 0, 0],
                            [0.41086487, 0.62639459, 0.41086487, 0, 0, 0],
                            [0.41086487, 0.41086487, 0.62639459, 0, 0, 0],
                            [0, 0, 0, 0.42750351, 0, 0],
                            [0, 0, 0, 0, 0.42750351, 0],
                            [0, 0, 0, 0, 0, 0.42750351]])
    C_al = np.loadtxt("data/C_al.csv", delimiter=",")
    C_mgsi = np.loadtxt("data/C_MgSi100_225.csv", delimiter=",")
    misfit = np.array([[0.0440222, 0.00029263, 0.0008603],
                       [0.00029263, -0.0281846, 0.00029263],
                       [0.0008603, 0.00029263, 0.0440222]])

    strain_eng = StrainEnergy(poisson=mu, misfit=misfit)
    ellipsoid = {
        "aspect": [10.0, 1.0, 1.0],
        "C_prec": C_mgsi
        #"scale_factor": 0.8
    }
    res = strain_eng.explore_orientations(
        ellipsoid,
        C_al,
        step=5,
        phi_ax="z",
        fname="data/mgsi100_orientation_needle_iso.csv")
    strain_eng.plot_explore_result(res)
    plt.show()
Пример #3
0
 def test_equiv_strain_needle(self):
     """Test the equivalent strains for a needle."""
     if not available:
         self.skipTest(reason)
     mu = 0.3
     misfit = [0.05, 0.04, 0.03, 0.03, 0.02, 0.01]
     strain_eng = StrainEnergy(aspect=[50000.0, 5.0, 5.0],
                               eigenstrain=misfit, poisson=mu)
     f = 9.0
     eq_strain = strain_eng.equivalent_eigenstrain(f)
     kato = kato_et_al_needle(f, mu, misfit)
     self.assertTrue(np.allclose(eq_strain, kato, atol=1E-3))
Пример #4
0
    def plot(self,
             princ_misfit=[0.1, 0.1, 0.1],
             theta=0.0,
             phi=0.0,
             show=True):
        from matplotlib import pyplot as plt
        from cemc.tools import rot_matrix_spherical_coordinates
        from cemc.tools import rotate_tensor
        scale_factors = np.logspace(-3, 3, 100)

        # Sphere
        aspects = {
            "Sphere": [1.0, 1.0, 1.0],
            "Needle": [10000.0, 1.0, 1.0],
            "Plate": [10000.0, 10000.0, 1.0]
        }

        fig = plt.figure()
        ax1 = fig.add_subplot(1, 1, 1)
        colors = ["#5D5C61", "#7395AE", "#B1A296"]
        color_count = 0
        for k, v in aspects.items():
            strain_tensor = np.diag(princ_misfit)

            rot_matrix = rot_matrix_spherical_coordinates(phi, theta)
            strain_tensor = rotate_tensor(strain_tensor, rot_matrix)

            strain = StrainEnergy(aspect=v,
                                  misfit=strain_tensor,
                                  poisson=self.poisson)

            energy = [
                strain.strain_energy(C_matrix=self.tensor, scale_factor=f)
                for f in scale_factors
            ]

            ax1.plot(scale_factors,
                     energy,
                     label=k,
                     color=colors[color_count % 3])
            color_count += 1

        ax1.set_xscale("log")
        ax1.set_yscale("log")
        ax1.spines["right"].set_visible(False)
        ax1.spines["top"].set_visible(False)
        ax1.set_xlabel("Scale factor")
        ax1.set_ylabel("Strain energy")
        ax1.legend(frameon=False)

        if show:
            plt.show()
Пример #5
0
 def test_equiv_strain_plate(self):
     """Test the equivalent strains for a plate."""
     if not available:
         self.skipTest(reason)
     mu = 0.3
     misfit = [0.05, 0.04, 0.03, 0.03, 0.02, 0.01]
     strain_eng = StrainEnergy(aspect=[200000000.0, 51200000.0, 0.001],
                               misfit=misfit,
                               poisson=mu)
     f = 4.0
     eq_strain = strain_eng.equivalent_eigenstrain(C_matrix=C_al,
                                                   scale_factor=f)
     kato = kato_et_al_plate(f, mu, misfit)
     self.assertTrue(np.allclose(eq_strain, kato, atol=1E-3))
Пример #6
0
    def test_equiv_strain_sphere(self):
        """Test the equivalent eigenstrain against analytic results.

        Kato, M.; Fujii, T. & Onaka, S.
        Elastic strain energies of sphere, plate and needle inclusions
        Materials Science and Engineering: A,
        Elsevier, 1996, 211, 95-103
        """
        if not available:
            self.skipTest(reason)
        mu = 0.3
        misfit = [0.05, 0.04, 0.03, 0.03, 0.02, 0.01]
        strain_eng = StrainEnergy(aspect=[2.0, 2.0, 2.0],
                                  eigenstrain=misfit, poisson=mu)
        f = 5.0
        eq_strain = strain_eng.equivalent_eigenstrain(f)
        kato_et_al = kato_et_al_sphere(f, mu, misfit)
        self.assertTrue(np.allclose(eq_strain, kato_et_al, atol=1E-5))
def explore_orientations():
    from cemc.tools import StrainEnergy
    from matplotlib import pyplot as plt
    mu = 0.27155342515650893
    C_al = np.loadtxt("data/C_al.csv", delimiter=",")
    C_mgsi = np.loadtxt("data/C_beta_eye.csv", delimiter=",")
    misfit = np.array([[ 6.31232839e-02,  2.96796703e-07,  0.00000000e+00],
                       [ 2.96796703e-07,  6.31232839e-02,  0.00000000e+00],
                       [ 0.00000000e+00,  0.00000000e+00, -6.80589135e-05]])


    strain_eng = StrainEnergy(poisson=mu, misfit=misfit)
    ellipsoid = {
        "aspect": [10000.0, 1.0, 1.0],
        "C_prec": C_mgsi
        #"scale_factor": 0.8
    }
    res = strain_eng.explore_orientations(
        ellipsoid, C_al, step=5, phi_ax="z")
    strain_eng.plot_explore_result(res)
    plt.show()
Пример #8
0
    def __call__(self, system_changes):
        self.cov_obs(system_changes)

        inertia_tensor = np.trace(
            self.cov_obs.cov_matrix) * np.eye(3) - self.cov_obs.cov_matrix
        principal, rot_matrix = np.linalg.eigh(inertia_tensor)

        # The rotation to be applied to the material properties
        # and the misfit, is the transpose of the eigenvector
        # matrix
        C_mat = rotate_rank4_mandel(self.C_matrix, rot_matrix.T)
        C_prec = rotate_rank4_mandel(self.C_prec, rot_matrix.T)
        misfit = rotate_tensor(self.misfit, rot_matrix.T)

        axes = self.ellipsoid_axes(principal)
        str_eng = StrainEnergy(aspect=axes,
                               misfit=misfit,
                               poisson=self.poisson)
        str_energy = str_eng.strain_energy(C_matrix=C_mat, C_prec=C_prec)

        # Bias potential should not alter the observer
        # The MC object will handle this
        self.cov_obs.undo_last()
        return str_energy * ellipsoid_volume(axes)
    G = el.shear_modulus(mode=mode) / GPa
    E = el.youngs_modulus(mode=mode) / GPa
    mu = el.poisson_ratio

    print("Bulk modulus: {} GPa".format(B))
    print("Shear modulus: {} GPa".format(G))
    print("Poisson ratio: {}".format(mu))
    print("Young's modulus {} GPa".format(E))

    eigenstrain_princ = [-0.06497269, -0.06497269, 0.09606948, 0.0, 0.0, 0.0]
    #eigenstrain_princ = [-0.06497269, -0.06497269, 0.04, 0.0, 0.0, 0.0]
    eigenstrain = [
        -0.01129197, -0.01129197, -0.01129197, 0.05368072, 0.05368072,
        0.05368072
    ]
    strain_eng = StrainEnergy(poisson=mu, eigenstrain=eigenstrain)
    ellipsoid = {"aspect": [1000.0, 1.0, 1.0], "scale_factor": 0.83}
    # strain_eng.explore_aspect_ratios(0.83, C)
    res = strain_eng.explore_orientations(ellipsoid, C, step=5)
    # opt_res = strain_eng.optimize_rotation(ellipsoid, C, res[0]["rot_seq"])
    # strain_eng.show_ellipsoid(ellipsoid, res[0]["rot_seq"])
    strain_eng.plot_explore_result(res)
    # print(opt_res)
    # fig = strain_eng.plot(0.83, C, rot_seq=res[0]["rot_seq"])
    # fig = strain_eng.plot(0.83, C, rot_seq=res[0]["rot_seq"], latex=True)
    plt.show()
elif eigenstrain:
    ref_atoms = bulk("Al")
    ref_atoms *= (2, 2, 2)
    ref_cell = ref_atoms.get_cell().T
    strained_cell = atoms.get_cell().T
Пример #10
0
    def optimal_orientation(self,
                            princ_misfit=[0.1, 0.1, 0.1],
                            aspect=[1.0, 1.0, 1.0],
                            scale=1.0,
                            show_map=True):
        """Find the optimial orientation of the ellipsoid."""
        from itertools import product
        from cemc.tools import rot_matrix_spherical_coordinates
        from cemc.tools import rotate_tensor
        from scipy.interpolate import griddata
        from matplotlib import pyplot as plt

        # Quick exploration of the space
        theta = np.linspace(0.0, np.pi / 2.0, 100)
        phi = np.linspace(0.0, np.pi / 2.0, 100)
        energy = []
        all_theta = []
        all_phi = []
        for ang in product(phi, theta):
            strain_tensor = np.diag(princ_misfit)
            rot_matrix = rot_matrix_spherical_coordinates(ang[0], ang[1])
            strain_tensor = rotate_tensor(strain_tensor, rot_matrix)

            strain = StrainEnergy(aspect=aspect,
                                  misfit=strain_tensor,
                                  poisson=self.poisson)
            new_energy = strain.strain_energy(C_matrix=self.tensor,
                                              scale_factor=scale)
            energy.append(new_energy)
            all_theta.append(ang[1])
            all_phi.append(ang[0])

        # Locate the minimal energy
        min_indx = np.argmin(energy)
        theta_min = all_theta[min_indx]
        phi_min = all_phi[min_indx]

        if theta_min > np.pi / 2.0:
            theta_min = np.pi - theta_min

        print("Min. energy: {}. Theta: {} Phi. {}"
              "".format(energy[min_indx], int(theta_min * 180 / np.pi),
                        int(phi_min * 180 / np.pi)))
        print("Poisson ratio: {}".format(self.poisson))

        T, P = np.meshgrid(theta, phi)
        data = griddata(np.vstack((all_theta, all_phi)).T, energy, (T, P))
        fig = plt.figure()
        ax = fig.add_subplot(1, 1, 1)
        im = ax.imshow(data.T,
                       origin="lower",
                       aspect="auto",
                       cmap="inferno",
                       extent=[0, 90, 0, 90])
        cbar = fig.colorbar(im)
        cbar.set_label("Strain energy")
        ax.set_xlabel("Polar angle (deg)")
        ax.set_ylabel("Azimuthal angle (deg)")

        if show_map:
            plt.show()