Пример #1
0
    def __init__(self, atoms, name, potential, calc_energy=True):
        """
        Initialise the writer with the templating atoms and
        potential.
        """
        self.atoms = atoms
        self.name = name
        self.potential = potential
        self.calc_energy = calc_energy
        self.counter = 0

        # TODO: check naming
        self.base_dir = os.getcwd()
        run_path = '{0}'.format(atoms.info['name'])
        info("Putting files in {0}.".format(run_path))
        os.mkdir(run_path)
        os.chdir(run_path)

        trajectory = 'traj_{0}.xyz'.format(atoms.info['name'])
        self.out = AtomsWriter(trajectory)
Пример #2
0
def relax_structure(atoms, relax_fmax=0.05, traj_interval=None):
    """
    Relax atoms object. If it contains a 'fixed_mask' array, then run constrained relaxation
    """
    arel = atoms.copy()
    try:
        fix_mask = atoms.get_array("fixed_mask")
        print("Running relaxation with %d constrained atoms" % fix_mask.sum())
        const = FixAtoms(mask=fix_mask)
        arel.set_constraint(const)
    except:
        print("No constraints specified, running relaxation")
    arel.set_calculator(calc)
    opt = FIRE(arel)  # LBFGS(arel) #
    if traj_interval is not None:
        from quippy.io import AtomsWriter

        out = AtomsWriter("traj-relax_structure.xyz")
        trajectory_write = lambda: out.write(QAtoms(arel, charge=None))
        opt.attach(trajectory_write, interval=traj_interval)
    opt.run(fmax=relax_fmax)
    return arel
Пример #3
0
def run(opts, args, verbosity):
    args = args[:]
    con = connect(args.pop(0))
    if args:
        if len(args) == 1 and args[0].isdigit():
            expressions = int(args[0])
        else:
            expressions = ','.join(args)
    else:
        expressions = []

    if opts.count or opts.uniq:
        opts.limit = 0

    rows = con.select(expressions, verbosity=verbosity, limit=opts.limit)

    if opts.count:
        n = 0
        for row in rows:
            n += 1
        print('%s' % plural(n, 'row'))
        return

    dcts = list(rows)

    if len(dcts) > 0:
        if opts.include_all or opts.list_columns:
            keys = []
            for dct in dcts:
                if hasattr(dct, 'key_value_pairs'):
                    for key in dct.key_value_pairs.keys():
                        if key not in keys:
                            keys.append(key)
            opts.columns = ','.join(['+'+key for key in keys])

        f = Formatter(opts.columns, opts.sort)
        if verbosity >= 1:
            ids, columns = f.format(dcts, opts)
        if verbosity > 1 or opts.list_columns:
            for col in columns:
                if not opts.list_columns:
                    print 'COLUMN',
                print col
            if opts.list_columns:
                return

        if opts.extract is not None:
            if '%' not in opts.extract:
                writer = AtomsWriter(opts.extract)
            for i, dct in enumerate(dcts):
                if '%' in opts.extract:
                    filename = opts.extract % i
                    writer = AtomsWriter(filename)
                at = dict2atoms(dct)
                if verbosity > 1:
                    print 'Writing config %d %r to %r' % (i, at, writer)
                writer.write(at)
Пример #4
0
def relax_gb(gb_file='file_name',
             traj_steps=120,
             total_steps=1200,
             force_tol=0.05):
    """Method to relax a grain_boundary bicrystal structure. Requires a .json
    file with at a minimum the 'param_file' variable specified.

    Args:
      gb_file(str): gbid.
      traj_steps(int): number of steps between print trajectories.
      total_steps(int): total number of force relaxation steps.
      force_tol(float): Force relaxation criterion in ev/A.

    Returns:
      :class:`ase.Atoms` Object
    """
    def converged(grain, smax, fmax):
        maxstress = max(grain.get_stress().ravel())
        rmsforces = np.sum(grain.get_forces()**2, axis=1)**0.5
        maxforce = max(rmsforces)
        if maxforce < fmax and maxstress < smax:
            return True
        return False

    with open('subgb.json', 'r') as outfile:
        j_dict = json.load(outfile)
    try:
        POT_DIR = os.path.join(app.root_path, 'potentials')
    except KeyError:
        sys.exit(
            "Please set POTDIR in os environment. `export POTDIR='path/to/potfiles/`"
        )
    try:
        param_file = j_dict['param_file']
        if param_file == 'iron_mish.xml':
            eam_pot = os.path.join(POT_DIR, 'iron_mish.xml')
            r_scale = 1.0129007626
        elif param_file == 'Fe_Mendelev.xml':
            eam_pot = os.path.join(POT_DIR, 'Fe_Mendelev.xml')
            r_scale = 1.00894848312
        elif param_file == 'PotBH.xml':
            eam_pot = os.path.join(POT_DIR, 'PotBH.xml')
            r_scale = 1.00894848312
        elif param_file == 'Fe_Ackland.xml':
            eam_pot = os.path.join(POT_DIR, 'Fe_Ackland.xml')
            r_scale = 1.00894185389
        elif param_file == 'Fe_Dudarev.xml':
            eam_pot = os.path.join(POT_DIR, 'Fe_Dudarev.xml')
            r_scale = 1.01279093417
        elif param_file == 'gp33b.xml':
            eam_pot = os.path.join(POT_DIR, 'gp33b.xml')
            sparse_file = 'gp33b.xml.sparseX.GAP_2016_10_3_60_19_29_10_8911'
            eam_pot_sparse = os.path.join(POT_DIR, sparse_file)
            shutil.copy(eam_pot, './')
            shutil.copy(eam_pot_sparse, './')
        else:
            print 'No paramfile found!'
            sys.exit()
    except KeyError:
        print 'No EAM potential file with that name. Relax failed.'
        sys.exit()

    print 'Using: ', eam_pot
    pot_file = eam_pot.split('/')[-1]
    print '{0}.xyz'.format(gb_file)
    print os.getcwd()
    grain = io.read('{0}.xyz'.format(gb_file), index='-1')
    if param_file != 'gp33b.xml':
        pot = Potential(
            'IP EAM_ErcolAd do_rescale_r=T r_scale={0}'.format(r_scale),
            param_filename=eam_pot)
    else:
        pot = Potential('IP GAP', param_filename=eam_pot)

    grain.set_calculator(pot)
    grain.info['adsorbate_info'] = None
    E_gb_init = grain.get_potential_energy()
    traj_file = gb_file
    if 'traj' in traj_file:
        out = AtomsWriter('{0}'.format('{0}.xyz'.format(traj_file)))
    else:
        out = AtomsWriter('{0}'.format('{0}_traj.xyz'.format(traj_file)))
    strain_mask = [0, 0, 1, 0, 0, 0]
    ucf = UnitCellFilter(grain, strain_mask)
    opt = FIRE(ucf)
    cell = grain.get_cell()
    A = cell[0][0] * cell[1][1]
    H = cell[2][2]
    #Calculation dumps total energyenergy and grainboundary area data to json file.
    with open('subgb.json', 'r') as f:
        gb_dict = json.load(f)

    #Write an initial dict so we know if the system has been initialized but the calculation is not finished.
    with open('subgb.json', 'w') as outfile:
        for key, value in gb_dict.items():
            j_dict[key] = value
        json.dump(j_dict, outfile, indent=2)

    CONVERGED = False
    FORCE_TOL = force_tol

    #default to 5 if traj_steps = 120, otherwise increases
    num_iters = int(float(total_steps) / float(traj_steps))
    logging.debug('num_iters: {}'.format(num_iters))
    for i in range(num_iters):
        opt.run(fmax=FORCE_TOL, steps=traj_steps)
        out.write(grain)
        force_array = grain.get_forces()
        max_force_II = max([max(f) for f in force_array])
        max_forces = [
            np.sqrt(fx**2 + fy**2 + fz**2) for fx, fy, fz in zip(
                grain.properties['force'][0], grain.properties['force'][1],
                grain.properties['force'][2])
        ]
        if max(max_forces) <= FORCE_TOL:
            CONVERGED = True
            break
    out.close()

    gb_dict['converged'] = CONVERGED
    E_gb = grain.get_potential_energy()
    gb_dict['E_gb'] = E_gb
    gb_dict['E_gb_init'] = E_gb_init
    gb_dict['area'] = A
    with open('subgb.json', 'w') as outfile:
        for key, value in gb_dict.items():
            j_dict[key] = value
        json.dump(j_dict, outfile, indent=2)

    if param_file == 'gp33b.xml':
        os.remove(param_file)
        os.remove(sparse_file)
    else:
        pass
    return grain
Пример #5
0
    defect.set_cutoff(3.0)
    defect.calc_connect()
    new_core = pp_nye_tensor(defect, dis_type=dis_type)
    defect.info['core']= new_core
    defect.write('{0}_therm.xyz'.format(input_file))
    print 'Crack Simulation Finished'

  if calc_nye or calc_virial:
#ats = AtomsReader('{0}_traj.xyz'.format(input_file))
    ats = AtomsReader('{0}.xyz'.format(input_file))
    hyb = np.zeros(ats[0].n)
#calc_nye tensor for each configuration in the trajectory:
    print len(hyb)
    print ats[0].params
    print len(ats)
    traj_burg = AtomsWriter('{0}_burg.xyz'.format(input_file))
    for i, at in enumerate(ats[::sampling]):
      try:
        del at.properties['edgex']
        del at.properties['edgey']
        del at.properties['screw']
      except KeyError:
#property doesn't exist on atoms object
        pass
      if i > 0:
        at.info['core'] = new_core
      new_core = pp_nye_tensor(at, dis_type=dis_type)
      if calc_virial:
        at.set_calculator(pot)  
        pp_virial(at) 
      print i, new_core
Пример #6
0
            dynamics.attach(pass_print_context(defect, dynamics))
        elif dyn_type == 'LOTF':
            defect.info['core'] = np.array([98.0, 98.0, 1.49])
            print 'Initializing LOTFDynamics'
            verbosity_push(PRINT_VERBOSE)
            dynamics = LOTFDynamics(defect,
                                    timestep,
                                    params.extrapolate_steps,
                                    check_force_error=False)
            dynamics.set_qm_update_func(update_qm_region)
            dynamics.attach(pass_print_context(defect, dynamics))
            dynamics.attach(traj_writer, print_interval, defect)
        else:
            print 'No dyn_type chosen', 1 / 0

        trajectory = AtomsWriter('{0}.traj.xyz'.format(input_file))
        print 'Running Crack Simulation'
        dynamics.run(nsteps)
        #Write cooked i.e. thermalized ceel to file.
        defect.set_cutoff(3.0)
        defect.calc_connect()
        new_core = pp_nye_tensor(defect, dis_type=dis_type)
        defect.info['core'] = new_core
        defect.write('{0}_therm.xyz'.format(input_file))
        print 'Crack Simulation Finished'

    if calc_nye or calc_virial:
        #ats = AtomsReader('{0}_traj.xyz'.format(input_file))
        ats = AtomsReader('{0}.xyz'.format(input_file))
        hyb = np.zeros(ats[0].n)
        #calc_nye tensor for each configuration in the trajectory:
Пример #7
0
import os
import glob
import argparse
from quippy import Atoms
from quippy.io import AtomsWriter, AtomsReader

parser = argparse.ArgumentParser()

parser.add_argument("-p", "--pattern", required=True)
parser.add_argument("-j", "--jobfile")
pattern = args.pattern

jobs = glob.glob(pattern)
out = AtomsWriter('traj.xyz')
for job in jobs:
    struct_file = os.path.join(job, 'feb{0}.xyz'.format(job[-3:]))
    ats = AtomsReader(struct_file)[-1]
    out.write(ats)
Пример #8
0
        atoms.params['core'] = crackpos
        print HYBRID_ACTIVE_MARK
        print 'Core Found. No. Quantum Atoms:', sum(atoms.hybrid[:])
      else:
        print 'No cell geometry given, specifiy either disloc or crack', 1/0 
  
  # ********* Setup and run MD ***********
  # Set the initial temperature to 2*simT: it will then equilibriate to
  # simT, by the virial theorem
  if params.test_mode:
      np.random.seed(0) # use same random seed each time to be deterministic 
  if params.rescale_velo:
      MaxwellBoltzmannDistribution(atoms, 2.0*sim_T)
  # Save frames to the trajectory every `traj_interval` time steps
  # but only when interpolating
  trajectory = AtomsWriter(os.path.join(params.rundir, params.traj_file))
  # Initialise the dynamical system
  system_timer('init_dynamics')
  if params.extrapolate_steps == 1:
      dynamics = VelocityVerlet(atoms, params.timestep)
      check_force_error = False
      if not params.classical:
          qmmm_pot.set(calc_weights=True)
      dynamics.state_label = 'D'
  else:
    print 'Initializing LOTF Dynamics'
    dynamics = LOTFDynamics(atoms, params.timestep,
                            params.extrapolate_steps,
                            check_force_error=check_force_error)
  system_timer('init_dynamics')
#Function to update the QM region at the beginning of each extrapolation cycle   
Пример #9
0
class ParamWriter(object):
    """
    Write out configurations to a trajectory and castep files to
    individual subdirectories.

    """
    def __init__(self, atoms, name, potential, calc_energy=True):
        """
        Initialise the writer with the templating atoms and
        potential.
        """
        self.atoms = atoms
        self.name = name
        self.potential = potential
        self.calc_energy = calc_energy
        self.counter = 0

        # TODO: check naming
        self.base_dir = os.getcwd()
        run_path = '{0}'.format(atoms.info['name'])
        info("Putting files in {0}.".format(run_path))
        os.mkdir(run_path)
        os.chdir(run_path)

        trajectory = 'traj_{0}.xyz'.format(atoms.info['name'])
        self.out = AtomsWriter(trajectory)

    def write_config(self, params):
        cell_params = params[:6]
        # Make a list of 3 item lists
        atom_params = [self.atoms[0].position] + zip(*[iter(params[6:])] * 3)

        new_atoms = self.atoms.copy()
        new_atoms.set_cell([[cell_params[0], 0.0, 0.0],
                            [cell_params[1], cell_params[2], 0.0],
                            [cell_params[3], cell_params[4], cell_params[5]]])

        new_atoms.set_positions(atom_params)
        info("Cell volume: {0}".format(new_atoms.get_volume()))
        if self.calc_energy:
            self.potential.calc(new_atoms,
                                energy=True,
                                forces=True,
                                virial=True)
        # Add to the xyz
        self.out.write(new_atoms)
        sp_path = '{0:03d}'.format(self.counter)
        write_filename = '{0}.{1:03d}'.format(self.atoms.info['name'],
                                              self.counter)
        os.mkdir(sp_path)
        os.chdir(sp_path)
        castep_write(new_atoms, filename=write_filename, kpoint_spacing=0.015)
        info("Wrote a configuration {0}.".format(write_filename))
        os.chdir('..')
        self.counter += 1

    def close(self):
        """
        Clean up.
        """
        self.out.close()
        os.chdir(self.base_dir)
Пример #10
0
for k in at.info.keys():
    if k not in ['energy', 'strain']:
        del at.info[k]

# ***** Setup and run MD *****

# Initialise the dynamical system
initial_momenta = at.get_momenta()
dynamics = Langevin(at,
                    params.timestep,
                    params.sim_T * units.kB,
                    8e-4,
                    logfile=log_name)

# Save frames to the trajectory every `traj_interval` time steps
out = AtomsWriter(traj_name)


def trajectory_write(at):
    atout = at.copy()
    for k in atout.arrays.keys():
        if k not in ['species', 'positions', 'momenta', 'numbers', 'force']:
            atout.set_array(k, None)
    for k in atout.info.keys():
        if k not in ['energy', 'time', 'temperature', 'pbc', 'Lattice']:
            del atout.info[k]
    at.info['energy'] = at.get_potential_energy()
    out.write(atout)


dynamics.attach(trajectory_write, params.traj_interval, at)  # Save trajectory
Пример #11
0
    np.random.seed(42) # use same random seed each time to be deterministic 
    if 'thermalized' not in crack_dict.keys():
      MaxwellBoltzmannDistribution(atoms, 2.0*sim_T)
      crack_dict['thermalized'] = True
    elif crack_dict['thermalized'] == False:
      MaxwellBoltzmannDistribution(atoms, 2.0*sim_T)
      crack_dict['thermalized'] = True
    else:
      pass

# Now keep a record if this crack cell has been thermalized:
    with open("crack_info.pckl", "w") as f:
      pickle.dump(crack_dict,f)

# Save frames to the trajectory every `traj_interval` time steps.
  trajectory = AtomsWriter(os.path.join(rundir, traj_file))
# Initialise the dynamical system
  system_timer('init_dynamics')
  if extrapolate_steps == 1:
      dynamics = VelocityVerlet(atoms, timestep)
      check_force_error = False
      if not classical:
          qmmm_pot.set(calc_weights=True)
      dynamics.state_label = 'D'
  else:
    print 'Initializing LOTF Dynamics'
    dynamics = LOTFDynamics(atoms, timestep,
                            extrapolate_steps,
                            check_force_error=check_force_error)
  system_timer('init_dynamics')
# Function to update the QM region at the beginning of each extrapolation cycle   
Пример #12
0
  surf_cell = gb_frac.build_surface(bp = sym_tilt_110[0][1])
  pot     = Potential('IP EAM_ErcolAd', param_filename=eam_pot)
  bulk.set_calculator(pot)
  ener_per_atom = bulk.get_potential_energy()/len(bulk)
  surf_cell.set_calculator(pot)
  surf_ener = surf_cell.get_potential_energy()
  cell  = surf_cell.get_cell()
  A     = cell[0][0]*cell[1][1]
  gamma = (surf_ener- len(surf_cell)*ener_per_atom)/A

  print '2*gamma ev/A2', gamma
  print '2*gamma J/m2',  gamma/(units.J/units.m**2)
  j_dict = {'or_axis':or_axis, 'bp':bp, 'gamma':gamma}
  with open('gbfrac.json','w') as f:
    json.dump(j_dict, f)
  out = AtomsWriter('{0}'.format('{0}_surf.xyz'.format(gbid)))
  out.write(Atoms(surf_cell))
  out.close()
  frac_cell = gb_frac.build_tilt_sym_frac()

#Unit cell for grain boundary fracture cell:
  print frac_cell.get_cell().round(2)

  frac_cell = Atoms(frac_cell)
  frac_cell = del_atoms(frac_cell)

#Relax grainboundary crack cell unit cell:
  pot      = Potential('IP EAM_ErcolAd', param_filename='Fe_Mendelev.xml')
  frac_cell.set_calculator(pot)
  slab_opt          = FIRE(frac_cell)
  slab_opt.run(fmax = (0.02*units.eV/units.Ang))
Пример #13
0
def molecular_dynamics(system,
                       potential,
                       potential_filename=None,
                       temperature=300,
                       total_steps=1100000,
                       timestep=1.0,
                       connect_interval=200,
                       write_interval=20000,
                       equilibration_steps=100000,
                       out_of_plane=None,
                       random_seed=None):
    """
    Run very simple molecular dynamics to generate some configurations. Writes
    configurations out as xyz and CASTEP files.
    """

    info("Inside MD.")
    if random_seed is None:
        random_seed = random.SystemRandom().randint(0, 2**63)
    quippy.system.system_set_random_seeds(random_seed)
    info("Quippy Random Seed {0}.".format(random_seed))
    system = Atoms(system)

    # Can take Potential objects, or just use a string
    if not isinstance(potential, Potential):
        if potential_filename:
            potential = Potential(potential, param_filename=potential_filename)
        else:
            potential = Potential(potential)
    system.set_calculator(potential)

    dynamical_system = DynamicalSystem(system)
    with Capturing(debug_on_exit=True):
        dynamical_system.rescale_velo(temperature)

    if out_of_plane is not None:
        # Stop things moving vertically in the cell
        dynamical_system.atoms.velo[3, :] = 0

    base_dir = os.getcwd()
    run_path = '{0}_{1:g}/'.format(system.info['name'], temperature)
    info("Putting files in {0}.".format(run_path))
    os.mkdir(run_path)
    os.chdir(run_path)

    trajectory = 'traj_{0}_{1:g}.xyz'.format(system.info['name'], temperature)
    out = AtomsWriter(trajectory)

    dynamical_system.atoms.set_cutoff(potential.cutoff() + 2.0)
    dynamical_system.atoms.calc_connect()
    potential.calc(dynamical_system.atoms,
                   force=True,
                   energy=True,
                   virial=True)

    structure_count = 0

    # Basic NVE molecular dynamics
    for step_number in range(1, total_steps + 1):
        dynamical_system.advance_verlet1(timestep,
                                         virial=dynamical_system.atoms.virial)
        potential.calc(dynamical_system.atoms,
                       force=True,
                       energy=True,
                       virial=True)
        dynamical_system.advance_verlet2(timestep,
                                         f=dynamical_system.atoms.force,
                                         virial=dynamical_system.atoms.virial)

        # Maintenance of the system
        if not step_number % connect_interval:
            debug("Connect at step {0}".format(step_number))
            dynamical_system.atoms.calc_connect()
            if step_number < equilibration_steps:
                with Capturing(debug_on_exit=True):
                    dynamical_system.rescale_velo(temperature)

        if not step_number % write_interval:
            debug("Status at step {0}".format(step_number))
            # Print goes to captured stdout
            with Capturing(debug_on_exit=True):
                dynamical_system.print_status(
                    epot=dynamical_system.atoms.energy)
                dynamical_system.rescale_velo(temperature)

            if step_number > equilibration_steps:
                debug("Write at step {0}".format(step_number))
                out.write(dynamical_system.atoms)
                sp_path = '{0:03d}'.format(structure_count)
                write_filename = '{0}_{1:g}.{2:03d}'.format(
                    system.info['name'], temperature, structure_count)
                os.mkdir(sp_path)
                os.chdir(sp_path)
                castep_write(dynamical_system.atoms, filename=write_filename)
                espresso_write(dynamical_system.atoms, prefix=write_filename)
                write_extxyz("{0}.xyz".format(write_filename),
                             dynamical_system.atoms)
                info("Wrote a configuration {0}.".format(write_filename))
                os.chdir('..')
                structure_count += 1

    out.close()
    os.chdir(base_dir)

    info("MD Done.")
Пример #14
0
                                 (1.5*units.kB*len(atoms)))
    atoms.info['strain'] = get_strain(atoms)
    atoms.info['G'] = get_energy_release_rate(atoms)/(units.J/units.m**2)
    
    crack_pos = find_crack_tip_stress_field(atoms, calc=mm_pot)
    atoms.info['crack_pos_x'] = crack_pos[0]
    atoms.info['d_crack_pos_x'] = crack_pos[0] - orig_crack_pos[0]

    print log_format % atoms.info


dynamics.attach(printstatus)

# Check if the crack has advanced, and stop incrementing the strain if it has
def check_if_cracked(atoms):
    crack_pos = find_crack_tip_stress_field(atoms, calc=mm_pot)

    # stop straining if crack has advanced more than tip_move_tol
    if not atoms.info['is_cracked'] and (crack_pos[0] - orig_crack_pos[0]) > tip_move_tol:
        atoms.info['is_cracked'] = True
        del atoms.constraints[atoms.constraints.index(strain_atoms)]

dynamics.attach(check_if_cracked, 1, atoms)

# Save frames to the trajectory every `traj_interval` time steps
trajectory = AtomsWriter(traj_file)
dynamics.attach(trajectory, traj_interval, atoms)

# Start running!
dynamics.run(nsteps)
Пример #15
0
def constrained_minim(atoms,
                      method='LBFGS',
                      vacuum=20.0,
                      k_spring=0.6,
                      clamp_mask=None,
                      initial_positions=None,
                      fmax=0.05,
                      spring='point'):
    c = np.ptp(atoms.positions, axis=0)
    c += vacuum
    atoms.set_cell(np.diag(c))

    if clamp_mask is None:
        at_help = Atoms('crack.xyz')
        clamp_mask = at_help.get_array('clamp_mask')
    if initial_positions is None:
        at_help = Atoms('crack.xyz')
        at_help.get_array('pos_orig')

    if spring == 'plane':
        springs = [
            Hookean(a1=i,
                    a2=[0, -1, 0, initial_positions[i, 1]],
                    k=k_spring,
                    rt=0) for i in np.where(clamp_mask)[0]
        ]
    else:
        springs = [
            Hookean(a1=i, a2=initial_positions[i], k=k_spring, rt=0)
            for i in np.where(clamp_mask)[0]
        ]

    from quippy.io import AtomsWriter
    out = AtomsWriter("traj-relax_structure.xyz")
    trajectory_write = lambda: out.write(atoms)

    if method == "LBFGS":
        pot = atoms.calc
        cc = ConstraintCalculator(springs)
        sc = SumCalculator(pot, cc)

        left, bottom, _ = initial_positions.min(axis=0)
        fix_line_mask = (initial_positions[:, 0] < left + 6.5)
        fix_line = FixAtoms(mask=fix_line_mask)
        atoms.set_array('fix_line_mask', fix_line_mask)
        atoms.set_constraint(fix_line)
        atoms.set_calculator(sc)
        opt = LBFGS(atoms, use_armijo=False)

    elif method == "FIRE":
        right, top, _ = initial_positions.max(axis=0)
        left, bottom, _ = initial_positions.min(axis=0)
        fix_line_mask = np.logical_or(initial_positions[:, 0] > right - 6.5,
                                      initial_positions[:, 0] < left + 6.5)
        fix_line_idx = np.where(fix_line_mask)[0]
        fix_line = [FixedLine(i, np.array([0, 1, 0])) for i in fix_line_idx]
        atoms.set_array('fix_line_mask', fix_line_mask)

        atoms.set_constraint(fix_line + springs)

        opt = FIRE(atoms, dtmax=2.5, maxmove=0.5)

    elif method == "mix":
        # do a first opt by keeping vertical edges fixed, then make them move along y
        right, top, _ = initial_positions.max(axis=0)
        left, bottom, _ = initial_positions.min(axis=0)
        fix_line_mask = np.logical_or(initial_positions[:, 0] > right - 6.5,
                                      initial_positions[:, 0] < left + 6.5)
        fix_line_idx = np.where(fix_line_mask)[0]

        pot = atoms.calc
        cc = ConstraintCalculator(springs)
        sc = SumCalculator(pot, cc)

        atoms.set_constraint(FixAtoms(mask=fix_line_mask))
        atoms.set_calculator(sc)
        LBFGS(atoms, use_armijo=False).run(fmax=0.2)

        fix_line = [FixedLine(i, np.array([0, 1, 0])) for i in fix_line_idx]
        atoms.set_array('fix_line_mask', fix_line_mask)

        atoms.set_constraint(fix_line + springs)
        atoms.set_calculator(pot)
        opt = vanillaLBFGS(atoms)

    else:
        print("Method not understood")
        return

    opt.attach(trajectory_write, interval=5)
    opt.run(fmax=fmax)
    return
Пример #16
0
    def __init__(self,
                 atoms,
                 timestep,
                 trajectory,
                 trajectoryinterval=10,
                 initialtemperature=None,
                 logfile='-',
                 loginterval=1,
                 loglabel='D'):

        # we will do the calculation in place, to minimise number of copies,
        # unless atoms is not a quippy Atoms
        if not isinstance(atoms, Atoms):
            warnings.warn(
                'Dynamics atoms is not quippy.Atoms instance, copy forced!')
            atoms = Atoms(atoms)
        self.atoms = atoms

        fortran_indexing = False
        if hasattr(atoms, 'fortran_indexing'):
            fortran_indexing = atoms.fortran_indexing

        if self.atoms.has('masses'):
            if self.atoms.has_property('mass'):
                if abs(self.atoms.mass / MASSCONVERT -
                       self.atoms.get_masses()) > 1e-3:
                    raise RuntimeError(
                        'Dynamics confused as atoms has inconsistent "mass" and "masses" arrays'
                    )
            else:
                self.atoms.add_property('mass',
                                        self.atoms.get_masses() * MASSCONVERT)
        else:
            if self.atoms.has_property('mass'):
                self.atoms.set_masses(self.atoms.mass / MASSCONVERT)
            else:
                self.atoms.set_masses('defaults')

        if self.atoms.has('momenta'):
            if self.atoms.has_property('velo'):
                if abs(self.atoms.velo * sqrt(MASSCONVERT) -
                       self.atoms.get_velocities().T).max() > 1e-3:
                    raise RuntimeError(
                        'Dynamics confused as atoms has inconsistent "velo" and "momenta" arrays'
                    )
            else:
                self.atoms.add_property('velo', (self.atoms.get_velocities() /
                                                 sqrt(MASSCONVERT)).T)
        else:
            if self.atoms.has_property('velo'):
                self.atoms.set_velocities(self.atoms.velo.T *
                                          sqrt(MASSCONVERT))
            else:
                # start with zero momenta
                self.atoms.set_momenta(np.zeros_like(self.atoms.positions))
                self.atoms.add_property('velo', 0., n_cols=3)

        self._ds = DynamicalSystem(self.atoms,
                                   fortran_indexing=fortran_indexing)

        if initialtemperature is not None:
            if not all(abs(self._ds.atoms.velo) < 1e-3):
                msg = ('initialtemperature given but Atoms already ' +
                       'have non-zero velocities!')
                raise RuntimeError(msg)
            self._ds.rescale_velo(initialtemperature)

        # now self._ds.atoms is either a Fortran shallowcopy of atoms,
        # or a copy if input atoms was not an instance of quippy.Atoms

        if 'time' in atoms.info:
            self.set_time(atoms.info['time'])  # from ASE units to fs

        self.observers = []
        self.set_timestep(timestep)

        if trajectory is not None:
            if isinstance(trajectory, basestring):
                trajectory = AtomsWriter(trajectory)
            self.attach(trajectory, trajectoryinterval, self._ds.atoms)

        self.loglabel = loglabel
        if logfile is not None:
            if isinstance(logfile, basestring):
                logfile = InOutput(logfile, OUTPUT)
            self.attach(self.print_status, loginterval, logfile)
Пример #17
0
dynamical_system.set_barostat(type=BAROSTAT_HOOVER_LANGEVIN, p_ext=0.0,
                              hydrostatic_strain=True, diagonal_strain=True,
                              finite_strain_formulation=False, tau_epsilon=10.0,
                              w_epsilon=10000.0, w_epsilon_factor=10000.0,
                              t=TEMPERATURE)
dynamical_system.add_thermostat(type=THERMOSTAT_ALL_PURPOSE, t=TEMPERATURE, tau=100.0)
dynamical_system.rescale_velo(TEMPERATURE)

total_steps = 1100000
timestep = 0.1  # fs
connect_interval = 200
write_interval = 20000
equilibration_steps = 100000

trajectory = 'traj_{}_{}.xyz'.format(lattice.func_name, TEMPERATURE)
out = AtomsWriter(trajectory)

dynamical_system.atoms.calc_connect()
fs_potential.calc(dynamical_system.atoms, force=True, energy=True, virial=True)

# Basic NVE molecular dynamics
for step_number in range(1, total_steps+1):
    dynamical_system.advance_verlet1(timestep,
                                     virial=dynamical_system.atoms.virial)
    fs_potential.calc(dynamical_system.atoms, force=True,
                      energy=True, virial=True)
    dynamical_system.advance_verlet2(timestep, f=dynamical_system.atoms.force,
                                     virial=dynamical_system.atoms.virial)

    # Maintenance of the system
    if not step_number % connect_interval: