def test_rotation(self):
        for make_atoms, calc in [ 
#            ( lambda a0,x : 
#              FaceCenteredCubic('He', size=[1,1,1],
#                                latticeconstant=3.5 if a0 is None else a0,
#                                directions=x),
#              LJCut(epsilon=10.2, sigma=2.28, cutoff=5.0, shift=True) ),
            ( lambda a0,x : FaceCenteredCubic('Au', size=[1,1,1],
                                              latticeconstant=a0, directions=x),
              EAM('Au-Grochola-JCP05.eam.alloy') ),
#            ( lambda a0,x : Diamond('Si', size=[1,1,1], latticeconstant=a0,
#                                    directions=x),
#              Kumagai() )
            #( lambda a0,x : FaceCenteredCubic('Au', size=[1,1,1],
            #                                  latticeconstant=a0, directions=x),
            #  EAM(potential='Au-Grochola-JCP05.eam.alloy') ),
            ]:

            a = make_atoms(None, [[1,0,0], [0,1,0], [0,0,1]])
            a.set_calculator(calc)
            FIRE(StrainFilter(a, mask=[1,1,1,0,0,0]), logfile=None) \
                .run(fmax=self.fmax)
            latticeconstant = np.mean(a.cell.diagonal())

            C6 = measure_triclinic_elastic_constants(a, delta=self.delta,
                                                     fmax=self.fmax)
            C11, C12, C44 = Voigt_6x6_to_cubic(C6)/GPa

            el = CubicElasticModuli(C11, C12, C44)

            C_m = measure_triclinic_elastic_constants(a, delta=self.delta,
                                                      fmax=self.fmax)/GPa
            self.assertArrayAlmostEqual(el.stiffness(), C_m, tol=0.01)

            for directions in [ [[1,0,0], [0,1,0], [0,0,1]],
                                [[0,1,0], [0,0,1], [1,0,0]],
                                [[1,1,0], [0,0,1], [1,-1,0]],
                                [[1,1,1], [-1,-1,2], [1,-1,0]] ]:
                a, b, c = directions

                directions = np.array([ np.array(x)/np.linalg.norm(x) 
                                        for x in directions ])
                a = make_atoms(latticeconstant, directions)
                a.set_calculator(calc)

                C = el.rotate(directions)
                C_check = el._rotate_explicit(directions)
                C_check2 = rotate_cubic_elastic_constants(C11, C12, C44,
                                                          directions)
                C_check3 = \
                    rotate_elastic_constants(cubic_to_Voigt_6x6(C11, C12, C44),
                                             directions)
                self.assertArrayAlmostEqual(C, C_check, tol=1e-6)
                self.assertArrayAlmostEqual(C, C_check2, tol=1e-6)
                self.assertArrayAlmostEqual(C, C_check3, tol=1e-6)

                C_m = measure_triclinic_elastic_constants(a, delta=self.delta,
                                                          fmax=self.fmax)/GPa

                self.assertArrayAlmostEqual(C, C_m, tol=1e-2)
Beispiel #2
0
    def __init__(self,
                 crack_surface,
                 crack_front,
                 C11=None,
                 C12=None,
                 C44=None,
                 stress_state=PLANE_STRAIN,
                 C=None,
                 Crot=None):
        """
        Initialize a crack in a cubic crystal with elastic constants C11, C12
        and C44 (or optionally a full 6x6 elastic constant matrix C).
        The crack surface is given by crack_surface, the cracks runs
        in the plane given by crack_front.
        """

        # x (third_dir) - direction in which the crack is running
        # y (crack_surface) - free surface that forms due to the crack
        # z (crack_front) - direction of the crack front
        third_dir = np.cross(crack_surface, crack_front)
        third_dir = np.array(third_dir) / np.sqrt(np.dot(third_dir, third_dir))
        crack_surface = np.array(crack_surface) / \
            np.sqrt(np.dot(crack_surface, crack_surface))
        crack_front = np.array(crack_front) / \
            np.sqrt(np.dot(crack_front, crack_front))

        A = np.array([third_dir, crack_surface, crack_front])
        if np.linalg.det(A) < 0:
            third_dir = -third_dir
        A = np.array([third_dir, crack_surface, crack_front])

        if Crot is not None:
            C6 = Crot
        elif C is not None:
            C6 = rotate_elastic_constants(C, A)
        else:
            C6 = rotate_cubic_elastic_constants(C11, C12, C44, A)

        self.crack = RectilinearAnisotropicCrack()
        S6 = inv(C6)

        self.C = C6
        self.S = S6

        if stress_state == PLANE_STRESS:
            self.crack.set_plane_stress(S6[0, 0], S6[1, 1], S6[0, 1], S6[0, 5],
                                        S6[1, 5], S6[5, 5])
        elif stress_state == PLANE_STRAIN:
            self.crack.set_plane_strain(S6[0, 0], S6[1, 1], S6[2, 2], S6[0, 1],
                                        S6[0, 2], S6[1, 2], S6[0, 5], S6[1, 5],
                                        S6[2, 5], S6[5, 5])
Beispiel #3
0
    def __init__(self, crack_surface, crack_front, C11=None, C12=None,
                 C44=None, stress_state=PLANE_STRAIN, C=None, Crot=None):
        """
        Initialize a crack in a cubic crystal with elastic constants C11, C12
        and C44 (or optionally a full 6x6 elastic constant matrix C).
        The crack surface is given by crack_surface, the cracks runs
        in the plane given by crack_front.
        """

        # x (third_dir) - direction in which the crack is running
        # y (crack_surface) - free surface that forms due to the crack
        # z (crack_front) - direction of the crack front
        third_dir = np.cross(crack_surface, crack_front)
        third_dir = np.array(third_dir) / np.sqrt(np.dot(third_dir,
                                                         third_dir))
        crack_surface = np.array(crack_surface) / \
            np.sqrt(np.dot(crack_surface, crack_surface))
        crack_front = np.array(crack_front) / \
            np.sqrt(np.dot(crack_front, crack_front))

        A = np.array([third_dir, crack_surface, crack_front])
        if np.linalg.det(A) < 0:
            third_dir = -third_dir
        A = np.array([third_dir, crack_surface, crack_front])

        if Crot is not None:
            C6 = Crot
        elif C is not None:
            C6 = rotate_elastic_constants(C, A)
        else:
            C6 = rotate_cubic_elastic_constants(C11, C12, C44, A)

        self.crack = RectilinearAnisotropicCrack()
        S6 = inv(C6)

        self.C = C6
        self.S = S6

        if stress_state == PLANE_STRESS:
            self.crack.set_plane_stress(S6[0, 0], S6[1, 1], S6[0, 1],
                                        S6[0, 5], S6[1, 5], S6[5, 5])
        elif stress_state == PLANE_STRAIN:
            self.crack.set_plane_strain(S6[0, 0], S6[1, 1], S6[2, 2],
                                        S6[0, 1], S6[0, 2], S6[1, 2],
                                        S6[0, 5], S6[1, 5], S6[2, 5],
                                        S6[5, 5])
Beispiel #4
0
                    size=(1, 1, 1),
                    symbol='Si',
                    pbc=True,
                    latticeconstant=a0)

if (hasattr(params, 'check_rotated_elastic_constants') and
        # Check that elastic constants of the rotated system
        # lead to same Young's modulus and Poisson ratio
        params.check_rotated_elastic_constants):
    unit_slab.set_calculator(params.calc)
    C_r1 = measure_triclinic_elastic_constants(unit_slab,
                                               optimizer=FIRE,
                                               fmax=params.bulk_fmax)

    R = np.array([np.array(x) / np.linalg.norm(x) for x in directions])
    C_r2 = rotate_elastic_constants(C, R)

    for C_r in [C_r1, C_r2]:
        S_r = np.linalg.inv(C_r)
        E_r = 1. / S_r[1, 1]
        print('Young\'s modulus from C_r: %.1f GPa' % (E_r / units.GPa))
        assert (abs(E_r - E) / units.GPa < 1e-3)

        nu_r = -S_r[1, 2] / S_r[1, 1]
        print('Possion ratio from C_r: %.3f' % (nu_r))
        assert (abs(nu_r - nu) < 1e-3)

print('Unit slab with %d atoms per unit cell:' % len(unit_slab))
print(unit_slab.cell)
print('')
                    pbc=True,
                    latticeconstant=a0)


if (hasattr(params, 'check_rotated_elastic_constants') and
    # Check that elastic constants of the rotated system
    # lead to same Young's modulus and Poisson ratio

    params.check_rotated_elastic_constants):
    unit_slab.set_calculator(params.calc)
    C_r1 = measure_triclinic_elastic_constants(unit_slab,
                                               optimizer=FIRE,
                                               fmax=params.bulk_fmax)

    R = np.array([ np.array(x)/np.linalg.norm(x) for x in directions ])
    C_r2 = rotate_elastic_constants(C, R)

    for C_r in [C_r1, C_r2]:
        S_r = np.linalg.inv(C_r)
        E_r = 1./S_r[1,1]
        print('Young\'s modulus from C_r: %.1f GPa' % (E_r / units.GPa))
        assert (abs(E_r - E)/units.GPa < 1e-3)

        nu_r = -S_r[1,2]/S_r[1,1]
        print('Possion ratio from C_r: %.3f' % (nu_r))
        assert (abs(nu_r - nu) < 1e-3)

print('Unit slab with %d atoms per unit cell:' % len(unit_slab))
print(unit_slab.cell)
print('')