예제 #1
0
def do_RSS(initial_configs_file, index=':', tol=0.01):
    import model

    ats = ase.io.read(initial_configs_file, index)
    range_slice_args = [None if i == '' else int(i) for i in index.split(':')]

    print("got index ", index, "range_slice_args", range_slice_args)
    print("using i_config", range(len(ats))[slice(*range_slice_args)])

    energies = []
    volumes = []
    for (i_config, at) in zip(range(len(ats))[slice(*range_slice_args)], ats):
        robust_minim_cell_pos(at, tol, "RSS_%04d" % i_config)
        print("RSS completed minimization")
        if hasattr(model, "fix_cell_dependence"):
            model.fix_cell_dependence()
        energies.append(at.get_potential_energy() / len(at))
        volumes.append(at.get_volume() / len(at))
        ase.io.write("RSS_relaxed_%04d.extxyz" % i_config, at)

    return {'energies': energies, 'volumes': volumes}
예제 #2
0
def robust_minim_cell_pos(atoms,
                          final_tol,
                          label="robust_minim",
                          max_sd2_iter=50,
                          sd2_tol=1.0,
                          max_lbfgs_iter=20,
                          max_n_lbfgs=50,
                          keep_symmetry=True):
    import model

    # do each minim at fixed cell-dependent model params (e.g. k-point mesh)
    if hasattr(model, "fix_cell_dependence"):
        model.fix_cell_dependence(atoms)
    relax_config(atoms,
                 relax_pos=True,
                 relax_cell=True,
                 tol=sd2_tol,
                 max_steps=max_sd2_iter,
                 traj_file="%s_sd2_traj.extxyz" % label,
                 method='sd2',
                 keep_symmetry=keep_symmetry,
                 config_label=label)

    done = False
    i_iter = 0
    while not done and i_iter < max_n_lbfgs:
        try:
            if hasattr(model, "fix_cell_dependence"):
                model.fix_cell_dependence(atoms)
            relax_config(atoms,
                         relax_pos=True,
                         relax_cell=True,
                         tol=final_tol,
                         max_steps=max_lbfgs_iter,
                         traj_file="%s_lbfgs_traj.%02d.extxyz" %
                         (label, i_iter),
                         method='lbfgs',
                         keep_symmetry=keep_symmetry,
                         config_label=label)
            done = (atoms.info["n_minim_iter"] < max_lbfgs_iter)
            print("robust_minim relax_configs LBFGS finished in ",
                  atoms.info["n_minim_iter"], "iters, max", max_lbfgs_iter)
        except:
            print("robust_minim relax_configs LBFGS failed, trying again")
        i_iter += 1

    # Undo fixed cell dependence. Hopefully no one is using robust_minim as part of a
    # more complex process that is doing its own fix_cell_depdence()
    if hasattr(model, "fix_cell_dependence"):
        model.fix_cell_dependence()
예제 #3
0
def calc_E_vs_V(bulk, dV=0.025, n_steps=(-10,10), tol=1e-2, method='lbfgs'): # hack tol to deal with Te C2/m
   import model

   V0 = bulk.get_volume()
   dV *= V0
   E_vs_V=[]

   scaled_bulk = bulk.copy()
   for i in range(0, n_steps[0]-1, -1):
      V_cur = scaled_bulk.get_volume()
      scaled_bulk.set_cell(scaled_bulk.get_cell()*((V0+i*dV)/V_cur)**(1.0/3.0), scale_atoms=True)
      ase.io.write(sys.stdout, scaled_bulk, format='extxyz')
      print("trying to relax i",i)
      try:
          if hasattr(model, "fix_cell_dependence"):
               model.fix_cell_dependence(scaled_bulk)
          ase.io.write(run_root+"-E_vs_V_%03d-unrelaxed.xyz" % i,  scaled_bulk, format='extxyz')
          scaled_bulk = relax_config(scaled_bulk, relax_pos=True, relax_cell=True, tol=tol, max_steps=200, save_traj=True, constant_volume=True, method=method,
              refine_symmetry_tol=1.0e-1, keep_symmetry=True, config_label="E_vs_V_%03d" % i, from_base_model=True, save_config=True)
      except Exception as e:
          print("WARNING: failed config in calc_E_vs_V", str(e))
          sys.exit(1) #### NB
          break
      ase.io.write(sys.stdout, scaled_bulk, format='extxyz')
      E_vs_V.insert(0, (scaled_bulk.get_volume()/len(scaled_bulk), scaled_bulk.get_potential_energy()/len(bulk), list(scaled_bulk.get_stress())) )

   scaled_bulk = bulk.copy()
   for i in range(1,n_steps[1]+1):
      V_cur = scaled_bulk.get_volume()
      scaled_bulk.set_cell(scaled_bulk.get_cell()*((V0+i*dV)/V_cur)**(1.0/3.0), scale_atoms=True)
      ase.io.write(sys.stdout, scaled_bulk, format='extxyz')
      print("trying to relax i",i)
      try:
          if hasattr(model, "fix_cell_dependence"):
               model.fix_cell_dependence(scaled_bulk)
          ase.io.write(run_root+"-E_vs_V_%02d-unrelaxed.xyz" % i,  scaled_bulk, format='extxyz')
          scaled_bulk = relax_config(scaled_bulk, relax_pos=True, relax_cell=True, tol=tol, max_steps=200, save_traj=True, constant_volume=True, method=method,
              refine_symmetry_tol=1.0e-1, keep_symmetry=True, config_label="E_vs_V_%02d" % i, from_base_model=True, save_config=True)
      except Exception as e:
          print("failed", str(e))
          break
      ase.io.write(sys.stdout, scaled_bulk, format='extxyz')
      E_vs_V.append( (scaled_bulk.get_volume()/len(scaled_bulk), scaled_bulk.get_potential_energy()/len(bulk), list(scaled_bulk.get_stress())) )

   if hasattr(model, "fix_cell_dependence"):
       model.fix_cell_dependence()
       scaled_bulk.calc = model.calculator

   return E_vs_V
예제 #4
0
def do_lattice(test_dir, lattice_type, dV=0.025, n_steps=(-10,10), tol=1.0e-2, method='lbfgs', applied_P=0.0):

   import model
   bulk = ase.io.read(test_dir+"/bulk.xyz", format="extxyz")

   results_dict = {}

   print("relax bulk")
   # relax the initial unit cell and atomic positions
   (orig_cell, new_cell) = (None, None)
   while new_cell is None or np.max(np.abs(np.dot(np.linalg.inv(new_cell),orig_cell) - np.eye(3))) > 0.05:
       if hasattr(model, "fix_cell_dependence"):
           model.fix_cell_dependence(bulk)
       orig_cell = bulk.get_cell()
       bulk = relax_config(bulk, relax_pos=True, relax_cell=True, tol=tol, save_traj=True, method=method,
                           refine_symmetry_tol=1.0e-2, keep_symmetry=True, config_label="bulk", from_base_model=True, save_config=True, applied_P=applied_P)
       new_cell = bulk.get_cell()
       if hasattr(model, "fix_cell_dependence"):
           model.fix_cell_dependence()
           bulk.calc = model.calculator
       else:
           break

   print("final relaxed bulk")
   ase.io.write(sys.stdout, bulk, format='extxyz')
   ase.io.write(os.path.join("..",run_root+"-relaxed.xyz"),  bulk, format='extxyz')

   print("calculating E vs. V")
   E_vs_V = calc_E_vs_V(bulk, dV=dV, n_steps=n_steps, tol=tol)
   results_dict.update({ 'E_vs_V' : E_vs_V })

   print("calculating elastic constants")

   if hasattr(model, "fix_cell_dependence"):
       model.fix_cell_dependence(bulk)

   bulk.calc = model.calculator

   opt = lambda atoms, **kwargs: PreconLBFGS(atoms, **kwargs)
   if lattice_type == 'cubic':
       elastic_consts = elasticity.fit_elastic_constants(bulk, symmetry='cubic', optimizer=opt, logfile=sys.stdout)
       c11 = elastic_consts[0][0,0]/GPa
       c12 = elastic_consts[0][0,1]/GPa
       c44 = elastic_consts[0][3,3]/GPa
       results_dict.update({'c11' : c11, 'c12': c12, 'c44' : c44, 'B' : (c11+2.0*c12)/3.0})
   elif lattice_type == 'orthorhombic':
       elastic_consts = elasticity.fit_elastic_constants(bulk, optimizer=opt, logfile=sys.stdout)
       c11 = elastic_consts[0][0,0]/GPa
       c22 = elastic_consts[0][1,1]/GPa
       c33 = elastic_consts[0][2,2]/GPa
       c12 = elastic_consts[0][0,1]/GPa
       c13 = elastic_consts[0][0,2]/GPa
       c23 = elastic_consts[0][1,2]/GPa
       c44 = elastic_consts[0][3,3]/GPa
       c55 = elastic_consts[0][4,4]/GPa
       c66 = elastic_consts[0][5,5]/GPa
       results_dict.update({'c11' : c11, 'c22' : c22, 'c33' : c33, 'c12': c12, 'c13' : c13, 'c23' : c23,
                            'c44' : c44, 'c55' : c55, 'c66' : c66})
   elif lattice_type == 'tetragonal':
       elastic_consts = elasticity.fit_elastic_constants(bulk, symmetry='tetragonal_high', optimizer=opt, logfile=sys.stdout)
       c11 = elastic_consts[0][0,0]/GPa
       c33 = elastic_consts[0][2,2]/GPa
       c12 = elastic_consts[0][0,1]/GPa
       c13 = elastic_consts[0][0,2]/GPa
       c44 = elastic_consts[0][3,3]/GPa
       c66 = elastic_consts[0][5,5]/GPa
       results_dict.update({'c11' : c11, 'c33' : c33, 'c12': c12, 'c13' : c13, 'c44' : c44, 'c66' : c66,
                            'B' : VRH_B(c11, c33, c12, c13, c44, c66)})
   elif lattice_type == 'hexagonal':
       # Need to check if hexagonal structures are truly trigonal_high
       # symmetry=triginal_high not hexagonal until matscipy is debugged
       elastic_consts = elasticity.fit_elastic_constants(bulk, symmetry='trigonal_high', optimizer=opt, logfile=sys.stdout)
       c11 = elastic_consts[0][0,0]/GPa
       c33 = elastic_consts[0][2,2]/GPa
       c12 = elastic_consts[0][0,1]/GPa
       c13 = elastic_consts[0][0,2]/GPa
       c44 = elastic_consts[0][3,3]/GPa
       c14 = elastic_consts[0][0,3]/GPa
       c15 = elastic_consts[0][0,4]/GPa
       c25 = elastic_consts[0][1,4]/GPa
       c66 = elastic_consts[0][5,5]/GPa
       results_dict.update({'c11' : c11, 'c33' : c33, 'c12': c12, 'c13' : c13, 'c44' : c44, 'c14' : c14,
                            'c15' : c15, 'c25' : c25, 'c66' : c66, 'B' : HTT_B(c11, c33, c12, c13)})
   elif lattice_type == 'trigonal':
       elastic_consts = elasticity.fit_elastic_constants(bulk, symmetry='trigonal_high', optimizer=opt, logfile=sys.stdout)
       c11 = elastic_consts[0][0,0]/GPa
       c33 = elastic_consts[0][2,2]/GPa
       c12 = elastic_consts[0][0,1]/GPa
       c13 = elastic_consts[0][0,2]/GPa
       c44 = elastic_consts[0][3,3]/GPa
       c14 = elastic_consts[0][0,3]/GPa
       c15 = elastic_consts[0][0,4]/GPa
       c25 = elastic_consts[0][1,4]/GPa
       c66 = elastic_consts[0][5,5]/GPa
       results_dict.update({'c11' : c11, 'c33' : c33, 'c12': c12, 'c13' : c13, 'c44' : c44, 'c14' : c14,
                            'c15' : c15, 'c25' : c25, 'c66' : c66, 'B' : HTT_B(c11, c33, c12, c13)})

   if hasattr(model, "fix_cell_dependence"):
       model.fix_cell_dependence()
       bulk.calc = model.calculator

   return results_dict
예제 #5
0
def relax_config(atoms,
                 relax_pos,
                 relax_cell,
                 tol=1e-3,
                 method='lbfgs',
                 max_steps=200,
                 save_traj=False,
                 constant_volume=False,
                 refine_symmetry_tol=None,
                 keep_symmetry=False,
                 strain_mask=None,
                 config_label=None,
                 from_base_model=False,
                 save_config=False,
                 try_restart=False,
                 fix_cell_dependence=False,
                 applied_P=0.0,
                 hydrostatic_strain=False,
                 **kwargs):

    # get from base model if requested
    import model

    if config_label is not None:
        save_file = run_root + '-' + config_label + '-relaxed.xyz'
        traj_file = run_root + '-' + config_label + '-traj.xyz'
    else:
        save_file = None
        traj_file = None

    if try_restart:
        # try from saved final config
        try:
            atoms = read(save_file, format='extxyz')
            print("relax_config read config from final file", save_file)
            return atoms
        except:
            pass
        # try from last config in traj file
        try:
            atoms_in = read(traj_file, -1, format='extxyz')
            # set positions from atoms_in rescaling to match current cell
            saved_cell = atoms.get_cell().copy()
            atoms.set_cell(atoms_in.get_cell())
            atoms.set_positions(atoms_in.get_positions())
            atoms.set_cell(saved_cell, scale_atoms=True)
            print("relax_config read config from traj", traj_file)
        except:
            pass
    else:
        if from_base_model:
            if config_label is None:
                raise ValueError(
                    'from_base_model is set but no config_label provided')
            try:
                base_run_file = os.path.join(
                    '..', base_run_root,
                    base_run_root + '-' + config_label + '-relaxed.xyz')
                atoms_in = read(base_run_file, format='extxyz')
                # set positions from atoms_in rescaling to match current cell
                saved_cell = atoms.get_cell().copy()
                atoms.set_cell(atoms_in.get_cell())
                atoms.set_positions(atoms_in.get_positions())
                atoms.set_cell(saved_cell, scale_atoms=True)
                print("relax_config read config from base model ",
                      base_run_file)
            except:
                try:
                    print("relax_config failed to read base run config from ",
                          base_run_root + '-' + config_label + '-relaxed.xyz')
                except:
                    print("relax_config failed to determined base_run_root")

    print("relax_config symmetry before refinement at default tol 1.0e-6")
    check_symmetry(atoms, 1.0e-6, verbose=True)
    if refine_symmetry_tol is not None:
        refine_symmetry(atoms, refine_symmetry_tol)
        print("relax_config symmetry after refinement")
        check_symmetry(atoms, refine_symmetry_tol, verbose=True)
    if keep_symmetry:
        print("relax_config trying to maintain symmetry")
        atoms.set_constraint(FixSymmetry(atoms))

    # if needed, fix cell dependence before running
    if fix_cell_dependence and hasattr(model, "fix_cell_dependence"):
        model.fix_cell_dependence(atoms)

    atoms.set_calculator(model.calculator)

    if method == 'lbfgs' or method == 'sd2':
        if 'move_mask' in atoms.arrays:
            atoms.set_constraint(
                FixAtoms(np.where(atoms.arrays['move_mask'] == 0)[0]))
        if relax_cell:
            atoms_cell = ExpCellFilter(atoms,
                                       mask=strain_mask,
                                       constant_volume=constant_volume,
                                       scalar_pressure=applied_P * GPa,
                                       hydrostatic_strain=hydrostatic_strain)
        else:
            atoms_cell = atoms
        atoms.info["n_minim_iter"] = 0
        if method == 'sd2':
            (traj,
             run_stat) = sd2_run("", atoms_cell, tol,
                                 lambda i: sd2_converged(i, atoms_cell, tol),
                                 max_steps)
            if save_traj is not None:
                write(traj_file, traj)
        else:
            # precon="Exp" specified to resolve an error with the lbfgs not optimising
            opt = PreconLBFGS(atoms_cell, use_armijo=False, **kwargs)
            if save_traj:
                traj = open(traj_file, "w")

                def write_trajectory():
                    if "n_minim_iter" in atoms.info:
                        atoms.info["n_minim_iter"] += 1
                    write(traj, atoms, format='extxyz')
                    traj.flush()

                opt.attach(write_trajectory)
    elif method == 'cg_n':
        raise ValueError(
            'minim method cg_n not supported in new python3 quippy')
        # if strain_mask is not None:
        # raise(Exception("strain_mask not supported with method='cg_n'"))
        # atoms.info['Minim_Constant_Volume'] = constant_volume
        # opt = Minim(atoms, relax_positions=relax_pos, relax_cell=relax_cell, method='cg_n')
    else:
        raise ValueError('unknown method %s!' % method)

    if method != 'sd2':
        opt.run(tol, max_steps)

    if refine_symmetry_tol is not None:
        print("symmetry at end of relaxation at desired tol")
        check_symmetry(atoms, refine_symmetry_tol, verbose=True)
    print("symmetry at end of relaxation at default tol 1e-6")
    check_symmetry(atoms, 1.0e-6, verbose=True)

    # in case we had a trajectory saved
    try:
        traj.close()
    except:
        pass

    if save_config:
        if config_label is None:
            raise ValueError('save_config is set but no config_label provided')
        write(save_file, atoms, format='extxyz')

    if keep_symmetry:
        for (i_c, c) in enumerate(atoms.constraints):
            if isinstance(c, FixSymmetry):
                del atoms.constraints[i_c]
                break

    # undo fix cell dependence
    if fix_cell_dependence and hasattr(model, "fix_cell_dependence"):
        sys.stderr.write(
            "WARNING: relax_config undoing fix_cell_dependence, whether or not it was set before it started\n"
        )
        model.fix_cell_dependence()
        atoms.calc = model.calculator

    return atoms