def testcubic_relaxed(self):
     C, C_err = fit_elastic_constants(self.at0, 'cubic',
                                      optimizer=FIRE, fmax=self.fmax,
                                      verbose=False, graphics=False)
     self.assertArrayAlmostEqual(C/units.GPa, self.C_ref_relaxed, tol=1e-2)
     if abs(C_err).max() > 0.:
         self.assertArrayAlmostEqual(C_err/units.GPa, self.C_err_ref_relaxed, tol=1e-2)
Exemple #2
0
def get_elastic_constants(pot_path=None,
                          calculator=None,
                          delta=1e-2,
                          symbol="W"):
    """
    return lattice parameter, and cubic elastic constants: C11, C12, 44
    using matscipy function
    pot_path - path to the potential

    symbol : string
        Symbol of the element to pass to ase.lattuce.cubic.SimpleCubicFactory
        default is "W" for tungsten
    """

    unit_cell = bulk(symbol)

    if (pot_path is not None) and (calculator is None):
        # create lammps calculator with the potential
        lammps = LAMMPSlib(lmpcmds=["pair_style eam/fs",
                           "pair_coeff * * %s W" % pot_path],
                           atom_types={'W': 1}, keep_alive=True)
        calculator = lammps

    unit_cell.set_calculator(calculator)

#   simple calculation to get the lattice constant and cohesive energy
#    alat0 = W.cell[0][1] - W.cell[0][0]
    sf = StrainFilter(unit_cell)  # or UnitCellFilter(W) -> to minimise wrt pos, cell
    opt = FIRE(sf)
    opt.run(fmax=1e-4)  # max force in eV/A
    alat = unit_cell.cell[0][1] - unit_cell.cell[0][0]
#    print("a0 relaxation %.4f --> %.4f" % (a0, a))
#    e_coh = W.get_potential_energy()
#    print("Cohesive energy %.4f" % e_coh)

    Cij, Cij_err = fit_elastic_constants(unit_cell,
                                         symmetry="cubic",
                                         delta=delta)

    Cij = Cij/GPa  # unit conversion to GPa

    elasticMatrix3x3 = Cij[:3, :3]
    # average of diagonal elements: C11, C22, C33
    C11 = elasticMatrix3x3.diagonal().mean()
    # make mask to extract non diagonal elements
    mask = np.ones((3, 3), dtype=bool)
    np.fill_diagonal(mask, False)

    # average of all non diagonal elements from 1 to 3
    C12 = elasticMatrix3x3[mask].mean()

    # average of diagonal elements from 4 till 6: C44, C55, C66,
    C44 = Cij[3:, 3:].diagonal().mean()

    # A = 2.*C44/(C11 - C12)

    if (pot_path is not None) and (calculator is None):
        lammps.lmp.close()

    return alat, C11, C12, C44
Exemple #3
0
 def test_Grochola(self):
     a = FaceCenteredCubic('Au', size=[2,2,2])
     calc = EAM('Au-Grochola-JCP05.eam.alloy')
     a.set_calculator(calc)
     FIRE(StrainFilter(a, mask=[1,1,1,0,0,0]), logfile=None).run(fmax=0.001)
     a0 = a.cell.diagonal().mean()/2
     self.assertTrue(abs(a0-4.0701)<2e-5)
     self.assertTrue(abs(a.get_potential_energy()/len(a)+3.924)<0.0003)
     C, C_err = fit_elastic_constants(a, symmetry='cubic', verbose=False)
     C11, C12, C44 = Voigt_6x6_to_cubic(C)
     self.assertTrue(abs((C11-C12)/GPa-32.07)<0.7)
     self.assertTrue(abs(C44/GPa-45.94)<0.5)
Exemple #4
0
ncryst = len(cryst)

# Double check elastic constants. We're just assuming this is really a periodic
# system. (True if it comes out of the cluster routines.)

compute_elastic_constants = parameter('compute_elastic_constants', False)
elastic_fmax = parameter('elastic_fmax', 0.05)
elastic_symmetry = parameter('elastic_symmetry', 'triclinic')
fmax = parameter('fmax', 0.01)

if compute_elastic_constants:
    cryst.set_calculator(params.calc)
    log_file = open('elastic_constants.log', 'w')
    C, C_err = fit_elastic_constants(cryst, verbose=False,
                                     symmetry=elastic_symmetry,
                                     optimizer=ase.optimize.FIRE,
                                     logfile=log_file,
                                     fmax=elastic_fmax)
    log_file.close()
    print('Measured elastic constants (in GPa):')
    print(np.round(C*10/GPa)/10)

    crk = crack.CubicCrystalCrack(params.crack_surface, params.crack_front,
                                  Crot=C/GPa)
else:
    if hasattr(params, 'C'):
        crk = crack.CubicCrystalCrack(params.crack_surface, params.crack_front,
                                      C=params.C)
    else:    
        crk = crack.CubicCrystalCrack(params.crack_surface, params.crack_front,
                                      params.C11, params.C12, params.C44)
Exemple #5
0
        def test_embedding_size_convergence(self):
            calc = Tersoff(**Tersoff_PRB_39_5566_Si_C)

            el = 'C'
            a0 = 3.566
            surface_energy = 2.7326 * 10
            crack_surface = [1, 1, 1]
            crack_front = [1, -1, 0]
            skin_x, skin_y = 1, 1

            cryst = bulk(el, cubic=True)
            cryst.set_calculator(calc)
            FIRE(UnitCellFilter(cryst), logfile=None).run(fmax=1e-6)
            a0 = cryst.cell.diagonal().mean()
            bondlength = cryst.get_distance(0, 1)
            #print('a0 =', a0, ', bondlength =', bondlength)

            cryst = diamond(el, a0, [1, 1, 1], crack_surface, crack_front)
            cryst.set_pbc(True)
            cryst.set_calculator(calc)
            cryst.set_cell(cryst.cell.diagonal(), scale_atoms=True)

            C, C_err = fit_elastic_constants(cryst,
                                             verbose=False,
                                             symmetry='cubic',
                                             optimizer=FIRE,
                                             fmax=1e-6)
            #print('Measured elastic constants (in GPa):')
            #print(np.round(C*10/units.GPa)/10)

            bondlengths = []
            refcell = None
            reftip_x = None
            reftip_y = None
            #[41, 39, 1],
            for i, n in enumerate([[21, 19, 1], [11, 9, 1], [6, 5, 1]]):
                #print(n)
                cryst = diamond(el, a0, n, crack_surface, crack_front)
                set_groups(cryst, n, skin_x, skin_y)
                cryst.set_pbc(True)
                cryst.set_calculator(calc)
                FIRE(UnitCellFilter(cryst), logfile=None).run(fmax=1e-6)
                cryst.set_cell(cryst.cell.diagonal(), scale_atoms=True)

                ase.io.write('cryst_{}.xyz'.format(i), cryst, format='extxyz')

                crk = crack.CubicCrystalCrack(crack_surface,
                                              crack_front,
                                              Crot=C / units.GPa)
                k1g = crk.k1g(surface_energy)

                tip_x = cryst.cell.diagonal()[0] / 2
                tip_y = cryst.cell.diagonal()[1] / 2

                a = cryst.copy()
                a.set_pbc([False, False, True])

                k1 = 1.0
                ux, uy = crk.displacements(cryst.positions[:, 0],
                                           cryst.positions[:, 1], tip_x, tip_y,
                                           k1 * k1g)

                a.positions[:, 0] += ux
                a.positions[:, 1] += uy

                # Center notched configuration in simulation cell and ensure enough vacuum.
                oldr = a[0].position.copy()
                if refcell is None:
                    a.center(vacuum=10.0, axis=0)
                    a.center(vacuum=10.0, axis=1)
                    refcell = a.cell.copy()
                    tip_x += a[0].x - oldr[0]
                    tip_y += a[0].y - oldr[1]
                    reftip_x = tip_x
                    reftip_y = tip_y
                else:
                    a.set_cell(refcell)

                # Shift tip position so all systems are exactly centered at the same spot
                a.positions[:, 0] += reftip_x - tip_x
                a.positions[:, 1] += reftip_y - tip_y

                refpositions = a.positions.copy()

                # Move reference crystal by same amount
                cryst.set_cell(a.cell)
                cryst.set_pbc([False, False, True])
                cryst.translate(a[0].position - oldr)

                bond1, bond2 = crack.find_tip_coordination(
                    a, bondlength=bondlength * 1.2)

                # Groups mark the fixed region and the region use for fitting the crack tip.
                g = a.get_array('groups')
                gcryst = cryst.get_array('groups')

                ase.io.write('cryst_{}.xyz'.format(i), cryst)

                a.set_calculator(calc)
                a.set_constraint(FixAtoms(mask=g == 0))
                FIRE(a, logfile=None).run(fmax=1e-6)

                dpos = np.sqrt((
                    (a.positions[:, 0] - refpositions[:, 0]) / ux)**2 + (
                        (a.positions[:, 1] - refpositions[:, 1]) / uy)**2)
                a.set_array('dpos', dpos)

                distance_from_tip = np.sqrt((a.positions[:, 0] - reftip_x)**2 +
                                            (a.positions[:, 1] - reftip_y)**2)

                ase.io.write('crack_{}.xyz'.format(i), a)

                # Compute average bond length per atom
                neighi, neighj, neighd = neighbour_list('ijd',
                                                        a,
                                                        cutoff=bondlength *
                                                        1.2)
                coord = np.bincount(neighi)
                assert coord.max() == 4

                np.savetxt(
                    'dpos_{}.out'.format(i),
                    np.transpose(
                        [distance_from_tip[coord == 4], dpos[coord == 4]]))

                # Compute distances from tipcenter
                neighdist = np.sqrt((
                    (a.positions[neighi, 0] + a.positions[neighj, 0]) / 2 -
                    reftip_x)**2 + (
                        (a.positions[neighi, 1] + a.positions[neighj, 1]) / 2 -
                        reftip_y)**2)

                np.savetxt('bl_{}.out'.format(i),
                           np.transpose([neighdist, neighd]))

                bondlengths += [a.get_distance(bond1, bond2)]
            print(bondlengths, np.diff(bondlengths),
                  bondlengths / bondlengths[-1] - 1)
            assert np.all(np.diff(bondlengths) > 0)
            assert np.max(bondlengths / bondlengths[0] - 1) < 0.01
Exemple #6
0
precon = parameter('precon', False)
prerelax = parameter('prerelax', False)
traj_file = parameter('traj_file', 'x_traj.h5')
restart_file = parameter('restart_file', traj_file)
traj_interval = parameter('traj_interval', 1)
direction = parameter('direction', +1)
lbfgs = parameter('lbfgs', False)
preconlbfgs = parameter('preconlbfgs', True)
ds_min = parameter('ds_min', 1e-5)

# compute elastic constants
cryst = params.cryst.copy()
cryst.pbc = True
cryst.calc = calc
C, C_err = fit_elastic_constants(cryst,
                                 symmetry=parameter('elastic_symmetry',
                                                    'triclinic'))

crk = CubicCrystalCrack(parameter('crack_surface'),
                        parameter('crack_front'),
                        Crot=C / GPa)

# Get Griffith's k1.
k1g = crk.k1g(parameter('surface_energy'))
print('Griffith k1 = %f' % k1g)

cluster = params.cluster.copy()

if continuation and not os.path.exists(restart_file):
    continuation = False
Exemple #7
0
cryst.set_pbc(True)

# Double check elastic constants. We're just assuming this is really a periodic
# system. (True if it comes out of the cluster routines.)

compute_elastic_constants = parameter('compute_elastic_constants', False)
elastic_fmax = parameter('elastic_fmax', 0.01)
elastic_symmetry = parameter('elastic_symmetry', 'triclinic')
fmax = parameter('fmax', 0.01)

if compute_elastic_constants:
    cryst.set_calculator(calc)
    log_file = open('elastic_constants.log', 'w')
    C, C_err = fit_elastic_constants(cryst,
                                     verbose=False,
                                     symmetry=elastic_symmetry,
                                     optimizer=ase.optimize.FIRE,
                                     logfile=log_file,
                                     fmax=elastic_fmax)
    log_file.close()
    print('Measured elastic constants (in GPa):')
    print(np.round(C * 10 / GPa) / 10)

    crk = crack.CubicCrystalCrack(params.crack_surface,
                                  params.crack_front,
                                  Crot=C / GPa)
else:
    if hasattr(params, 'C'):
        crk = crack.CubicCrystalCrack(params.crack_surface,
                                      params.crack_front,
                                      C=params.C)
    else:
Exemple #8
0
 def testtriclinic_unrelaxed(self):
     C, C_err = fit_elastic_constants(self.at0,
                                      'triclinic',
                                      verbose=False,
                                      graphics=False)
     self.assertArrayAlmostEqual(C / units.GPa, self.C_ref, tol=0.2)
Exemple #9
0
        def test_embedding_size_convergence(self):
            calc = Tersoff(**Tersoff_PRB_39_5566_Si_C)

            el = 'C'
            a0 = 3.566
            surface_energy = 2.7326 * 10
            crack_surface = [1, 1, 1]
            crack_front = [1, -1, 0]
            skin_x, skin_y = 1, 1

            cryst = bulk(el, cubic=True)
            cryst.set_calculator(calc)
            FIRE(UnitCellFilter(cryst), logfile=None).run(fmax=1e-6)
            a0 = cryst.cell.diagonal().mean()
            bondlength = cryst.get_distance(0, 1)
            #print('a0 =', a0, ', bondlength =', bondlength)

            cryst = diamond(el, a0, [1,1,1], crack_surface, crack_front)
            cryst.set_pbc(True)
            cryst.set_calculator(calc)
            cryst.set_cell(cryst.cell.diagonal(), scale_atoms=True)

            C, C_err = fit_elastic_constants(cryst, verbose=False,
                                             symmetry='cubic',
                                             optimizer=FIRE,
                                             fmax=1e-6)
            #print('Measured elastic constants (in GPa):')
            #print(np.round(C*10/units.GPa)/10)

            bondlengths = []
            refcell = None
            reftip_x = None
            reftip_y = None
            #[41, 39, 1], 
            for i, n in enumerate([[21, 19, 1], [11, 9, 1], [6, 5, 1]]):
                #print(n)
                cryst = diamond(el, a0, n, crack_surface, crack_front)
                set_groups(cryst, n, skin_x, skin_y)
                cryst.set_pbc(True)
                cryst.set_calculator(calc)
                FIRE(UnitCellFilter(cryst), logfile=None).run(fmax=1e-6)
                cryst.set_cell(cryst.cell.diagonal(), scale_atoms=True)

                ase.io.write('cryst_{}.xyz'.format(i), cryst, format='extxyz')

                crk = crack.CubicCrystalCrack(crack_surface,
                                              crack_front,
                                              Crot=C/units.GPa)
                k1g = crk.k1g(surface_energy)

                tip_x = cryst.cell.diagonal()[0]/2
                tip_y = cryst.cell.diagonal()[1]/2

                a = cryst.copy()
                a.set_pbc([False, False, True])

                k1 = 1.0
                ux, uy = crk.displacements(cryst.positions[:,0], cryst.positions[:,1],
                                           tip_x, tip_y, k1*k1g)

                a.positions[:, 0] += ux
                a.positions[:, 1] += uy

                # Center notched configuration in simulation cell and ensure enough vacuum.
                oldr = a[0].position.copy()
                if refcell is None:
                    a.center(vacuum=10.0, axis=0)
                    a.center(vacuum=10.0, axis=1)
                    refcell = a.cell.copy()
                    tip_x += a[0].x - oldr[0]
                    tip_y += a[0].y - oldr[1]
                    reftip_x = tip_x
                    reftip_y = tip_y
                else:
                    a.set_cell(refcell)

                # Shift tip position so all systems are exactly centered at the same spot
                a.positions[:, 0] += reftip_x - tip_x
                a.positions[:, 1] += reftip_y - tip_y

                refpositions = a.positions.copy()

                # Move reference crystal by same amount
                cryst.set_cell(a.cell)
                cryst.set_pbc([False, False, True])
                cryst.translate(a[0].position - oldr)

                bond1, bond2 = crack.find_tip_coordination(a, bondlength=bondlength*1.2)

                # Groups mark the fixed region and the region use for fitting the crack tip.
                g = a.get_array('groups')
                gcryst = cryst.get_array('groups')

                ase.io.write('cryst_{}.xyz'.format(i), cryst)

                a.set_calculator(calc)
                a.set_constraint(FixAtoms(mask=g==0))
                FIRE(a, logfile=None).run(fmax=1e-6)

                dpos = np.sqrt(((a.positions[:, 0]-refpositions[:, 0])/ux)**2 + ((a.positions[:, 1]-refpositions[:, 1])/uy)**2)
                a.set_array('dpos', dpos)

                distance_from_tip = np.sqrt((a.positions[:, 0]-reftip_x)**2 + (a.positions[:, 1]-reftip_y)**2)

                ase.io.write('crack_{}.xyz'.format(i), a)

                # Compute average bond length per atom
                neighi, neighj, neighd = neighbour_list('ijd', a, cutoff=bondlength*1.2)
                coord = np.bincount(neighi)
                assert coord.max() == 4

                np.savetxt('dpos_{}.out'.format(i), np.transpose([distance_from_tip[coord==4], dpos[coord==4]]))

                # Compute distances from tipcenter
                neighdist = np.sqrt(((a.positions[neighi,0]+a.positions[neighj,0])/2-reftip_x)**2 +
                                    ((a.positions[neighi,1]+a.positions[neighj,1])/2-reftip_y)**2)

                np.savetxt('bl_{}.out'.format(i), np.transpose([neighdist, neighd]))

                bondlengths += [a.get_distance(bond1, bond2)]
            print(bondlengths, np.diff(bondlengths), bondlengths/bondlengths[-1]-1)
            assert np.all(np.diff(bondlengths) > 0)
            assert np.max(bondlengths/bondlengths[0]-1) < 0.01
Exemple #10
0
def setup_crack(logger=screen):
    calc = parameter('calc')

    cryst = parameter('cryst').copy()
    cryst.set_pbc(True)

    # Double check elastic constants. We're just assuming this is really a periodic
    # system. (True if it comes out of the cluster routines.)

    compute_elastic_constants = parameter('compute_elastic_constants', False)
    elastic_fmax = parameter('elastic_fmax', 0.01)
    elastic_symmetry = parameter('elastic_symmetry', 'triclinic')
    elastic_optimizer = parameter('elastic_optimizer', ase.optimize.FIRE)

    if compute_elastic_constants:
        cryst.set_calculator(calc)
        log_file = open('elastic_constants.log', 'w')
        C, C_err = fit_elastic_constants(cryst, verbose=False,
                                         symmetry=elastic_symmetry,
                                         optimizer=elastic_optimizer,
                                         logfile=log_file,
                                         fmax=elastic_fmax)
        log_file.close()
        logger.pr('Measured elastic constants (in GPa):')
        logger.pr(np.round(C*10/GPa)/10)

        crk = crack.CubicCrystalCrack(parameter('crack_surface'),
                                      parameter('crack_front'),
                                      Crot=C/GPa)
    else:
        if has_parameter('C'):
            crk = crack.CubicCrystalCrack(parameter('crack_surface'),
                                          parameter('crack_front'),
                                          C=parameter('C'))
        else:
            crk = crack.CubicCrystalCrack(parameter('crack_surface'),
                                          parameter('crack_front'),
                                          parameter('C11'), parameter('C12'),
                                          parameter('C44'))


    logger.pr('Elastic constants used for boundary condition (in GPa):')
    logger.pr(np.round(crk.C*10)/10)

    # Get Griffith's k1.
    k1g = crk.k1g(parameter('surface_energy'))
    logger.pr('Griffith k1 = %f' % k1g)

    # Apply initial strain field.
    tip_x = parameter('tip_x', cryst.cell.diagonal()[0]/2)
    tip_y = parameter('tip_y', cryst.cell.diagonal()[1]/2)

    bondlength = parameter('bondlength', 2.7)
    bulk_nn = parameter('bulk_nn', 4)

    a = cryst.copy()
    a.set_pbc([False, False, True])

    hydrogenate_flag = parameter('hydrogenate', False)
    hydrogenate_crack_face_flag = parameter('hydrogenate_crack_face', True)

    if hydrogenate_flag and not hydrogenate_crack_face_flag:
        # Get surface atoms of cluster with crack
        a = hydrogenate(cryst, bondlength, parameter('XH_bondlength'), b=a)
        g = a.get_array('groups')
        g[a.numbers==1] = -1
        a.set_array('groups', g)
        cryst = a.copy()

    k1 = parameter('k1')
    try:
      k1 = k1[0]
    except:
      pass
    ux, uy = crk.displacements(cryst.positions[:,0], cryst.positions[:,1],
                               tip_x, tip_y, k1*k1g)
    a.positions[:len(cryst),0] += ux
    a.positions[:len(cryst),1] += uy

    # Center notched configuration in simulation cell and ensure enough vacuum.
    oldr = a[0].position.copy()
    vacuum = parameter('vacuum')
    a.center(vacuum=vacuum, axis=0)
    a.center(vacuum=vacuum, axis=1)
    tip_x += a[0].x - oldr[0]
    tip_y += a[0].y - oldr[1]

    # Choose which bond to break.
    bond1, bond2 = \
        parameter('bond', crack.find_tip_coordination(a, bondlength=bondlength, bulk_nn=bulk_nn))

    if parameter('center_crack_tip_on_bond', False):
        tip_x, tip_y, dummy = (a.positions[bond1]+a.positions[bond2])/2

    # Hydrogenate?
    coord = np.bincount(neighbour_list('i', a, bondlength), minlength=len(a))
    a.set_array('coord', coord)

    if parameter('optimize_full_crack_face', False):
        g = a.get_array('groups')
        gcryst = cryst.get_array('groups')
        coord = a.get_array('coord')
        g[coord!=4] = -1
        gcryst[coord!=4] = -1
        a.set_array('groups', g)
        cryst.set_array('groups', gcryst)

    if hydrogenate_flag and hydrogenate_crack_face_flag:
        # Get surface atoms of cluster with crack
        exclude = np.logical_and(a.get_array('groups')==1, coord!=4)
        a.set_array('exclude', exclude)
        a = hydrogenate(cryst, bondlength, parameter('XH_bondlength'), b=a,
                        exclude=exclude)
        g = a.get_array('groups')
        g[a.numbers==1] = -1
        a.set_array('groups', g)
        basename = parameter('basename', 'energy_barrier')
        ase.io.write('{0}_hydrogenated.xyz'.format(basename), a,
                     format='extxyz')

    # Move reference crystal by same amount
    cryst.set_cell(a.cell)
    cryst.set_pbc([False, False, True])
    cryst.translate(a[0].position - oldr)

    # Groups mark the fixed region and the region use for fitting the crack tip.
    g = a.get_array('groups')
    gcryst = cryst.get_array('groups')

    logger.pr('Opening bond {0}--{1}, initial bond length {2}'.
          format(bond1, bond2, a.get_distance(bond1, bond2, mic=True)))

    # centre vertically on the opening bond
    if parameter('center_cell_on_bond', True):
      a.translate([0., a.cell[1,1]/2.0 -
                      (a.positions[bond1, 1] +
                       a.positions[bond2, 1])/2.0, 0.])

    a.info['bond1'] = bond1
    a.info['bond2'] = bond2

    return a, cryst, crk, k1g, tip_x, tip_y, bond1, bond2, g==0, gcryst==0, g==1
Exemple #11
0
 def testtriclinic_relaxed(self):
     C, C_err = fit_elastic_constants(self.at0, 'triclinic',
                                      optimizer=FIRE, fmax=self.fmax,
                                      verbose=False, graphics=False)
     self.assertArrayAlmostEqual(C/units.GPa, self.C_ref_relaxed, tol=0.2)
Exemple #12
0
 def testcubic_unrelaxed(self):
     C, C_err = fit_elastic_constants(self.at0, 'cubic', verbose=False, graphics=False)
     self.assertArrayAlmostEqual(C/units.GPa, self.C_ref, tol=1e-2)
     if abs(C_err).max() > 0.:
         self.assertArrayAlmostEqual(C_err/units.GPa, self.C_err_ref, tol=1e-2)
    bulk_at.set_calculator(model.calculator)
    bulk_at = relax_config(bulk_at,
                           relax_pos=True,
                           relax_cell=True,
                           tol=1.0e-4,
                           traj_file=None)
    a0 = bulk_at.get_cell_lengths_and_angles()[0] * np.sqrt(2.0)
    bulk_at = bulk("Si", "diamond", a0)

    from matscipy import elasticity
    from ase.optimize import BFGS

    bulk_at.set_calculator(model.calculator)
    opt = BFGS
    b = elasticity.fit_elastic_constants(bulk_at,
                                         symmetry='cubic',
                                         optimizer=opt)
    bulk_modulus = elasticity.elastic_moduli(b[0])[3]

try:
    with open("../model-{}-test-phonon_diamond-properties.json".format(
            model.name)) as f:
        j = json.load(f)

    f0 = j["phonon_diamond_frequencies"]
    bf0 = j["phonon_diamond_band_frequencies"]
    band_distances = j["phonon_diamond_band_distances"]
    weights = j["phonon_diamond_weights"]
except:
    phonon_properties = phonons(model,
                                bulk_at,
fit_elastic_constants = CP(fit_elastic_constants)

###

cryst = params.cryst.copy()

# Double check elastic constants. We're just assuming this is really a periodic
# system. (True if it comes out of the cluster routines.)

compute_elastic_constants = param('compute_elastic_constants', False)

if compute_elastic_constants:
    pbc = cryst.pbc.copy()
    cryst.set_pbc(True)
    cryst.set_calculator(params.calc)
    C, C_err = fit_elastic_constants(cryst, verbose=False,
                                     optimizer=ase.optimize.FIRE)
    cryst.set_pbc(pbc)

    logger.pr('Measured elastic constants (in GPa):')
    logger.pr(np.round(C*10/GPa)/10)

    crk = crack.CubicCrystalCrack(params.crack_surface, params.crack_front,
                                  Crot=C/GPa)
else:
    if hasattr(params, 'C'):
        crk = crack.CubicCrystalCrack(params.crack_surface, params.crack_front,
                                      C=params.C)
    else:    
        crk = crack.CubicCrystalCrack(params.crack_surface, params.crack_front,
                                      params.C11, params.C12, params.C44)
 def testtriclinic_relaxed(self):
     C, C_err = fit_elastic_constants(self.at0, 'triclinic',
                                      optimizer=FIRE, fmax=self.fmax,
                                      verbose=False, graphics=False)
     self.assertArrayAlmostEqual(C/units.GPa, self.C_ref_relaxed, tol=0.2)
 def testtriclinic_unrelaxed(self):
     C, C_err = fit_elastic_constants(self.at0, 'triclinic',
                                      verbose=False, graphics=False)
     self.assertArrayAlmostEqual(C/units.GPa, self.C_ref, tol=0.2)