Exemple #1
0
    def __init__(self,
                 atoms,
                 timestep,
                 integrator='verlet',
                 trajectory=None,
                 traj_interval=1000,
                 logfile=None,
                 loginterval=100):
        Dynamics.__init__(self, atoms, None, None)

        self.dt = timestep

        if integrator == 'verlet':
            self.run_style = 'verlet'
        else:
            raise RuntimeError('Unknown integrator: %s' % thermostat)

        if trajectory:
            if isinstance(trajectory, str):
                trajectory = PickleTrajectory(trajectory, 'w', atoms)
            self.attach(trajectory, interval=traj_interval)

        if logfile:
            self.attach(MDLogger(dyn=self, atoms=atoms, logfile=logfile),
                        interval=loginterval)

        self.fix = None
        self.cell_relaxed = False
Exemple #2
0
    def __init__(self, atoms,
                 temperature=100 * kB,
                 optimizer=FIRE,
                 fmax=0.1,
                 dr=0.1,
                 logfile='-', 
                 trajectory='lowest.traj',
                 optimizer_logfile='-',
                 local_minima_trajectory='local_minima.traj',
                 adjust_cm=True):
        Dynamics.__init__(self, atoms, logfile, trajectory)
        self.kT = temperature
        self.optimizer = optimizer
        self.fmax = fmax
        self.dr = dr
        if adjust_cm:
            self.cm = atoms.get_center_of_mass()
        else:
            self.cm = None

        self.optimizer_logfile = optimizer_logfile
        self.lm_trajectory = local_minima_trajectory
        if isinstance(local_minima_trajectory, str):
            self.lm_trajectory = PickleTrajectory(local_minima_trajectory,
                                                  'w', atoms)

        self.initialize()
Exemple #3
0
 def __init__(self, atoms, max_step = 0.5, T= 298.0, accept_ratio=None, one_d_coord =None):
     self.max_step = max_step
     self.beta = 1.0 / (T * units.kB)
     self.accept_ratio = accept_ratio
     self.one_d_coord = one_d_coord 
     
     Dynamics.__init__(self, atoms,logfile=None, trajectory=None)
Exemple #4
0
    def __init__(self, atoms, timestep, trajectory, logfile=None,
                 loginterval=1, append_trajectory=False):

        # dt as to be attached _before_ parent class is initialized
        self.dt = timestep

        Dynamics.__init__(self, atoms, logfile=None, trajectory=trajectory,
                          append_trajectory=append_trajectory)

        self.masses = self.atoms.get_masses()
        self.max_steps = None

        if 0 in self.masses:
            warnings.warn('Zero mass encountered in atoms; this will '
                          'likely lead to errors if the massless atoms '
                          'are unconstrained.')

        self.masses.shape = (-1, 1)

        if not self.atoms.has('momenta'):
            self.atoms.set_momenta(np.zeros([len(self.atoms), 3]))

        if logfile:
            self.attach(MDLogger(dyn=self, atoms=atoms, logfile=logfile),
                        interval=loginterval)
Exemple #5
0
 def __init__(self, atoms, timestep, trajectory, logfile=None,
              loginterval=1):
     Dynamics.__init__(self, atoms, logfile=None, trajectory=trajectory)
     self.dt = timestep
     # Store data locally except on parallel simulations
     self._localdata = not getattr(atoms, "parallel", False)
     if logfile:
         self.attach(MDLogger(dyn=self, atoms=atoms, logfile=logfile),
                     interval=loginterval)
Exemple #6
0
 def __init__(self,
              atoms,
              restart=None,
              logfile=None,
              trajectory=None,
              algorithm='cg',
              relax_cell=False):
     Dynamics.__init__(self, atoms, logfile, trajectory)
     self.algorithm = algorithm
     self.relax_cell = relax_cell
Exemple #7
0
 def __init__(self,
              atoms,
              timestep,
              trajectory,
              logfile=None,
              loginterval=1):
     Dynamics.__init__(self, atoms, logfile=None, trajectory=trajectory)
     self.dt = timestep
     self.masses = self.atoms.get_masses()
     self.masses.shape = (-1, 1)
     if logfile:
         self.attach(MDLogger(dyn=self, atoms=atoms, logfile=logfile),
                     interval=loginterval)
Exemple #8
0
 def __init__(self, atoms, timestep, trajectory, logfile=None,
              loginterval=1):
     Dynamics.__init__(self, atoms, logfile=None, trajectory=trajectory)
     self.dt = timestep
     self.masses = self.atoms.get_masses()
     if 0 in self.masses:
         warnings.warn('Zero mass encountered in atoms; this will '
                       'likely lead to errors if the massless atoms '
                       'are unconstrained.')
     self.masses.shape = (-1, 1)
     if logfile:
         self.attach(MDLogger(dyn=self, atoms=atoms, logfile=logfile),
                     interval=loginterval)
Exemple #9
0
 def __init__(self, atoms, timestep, trajectory, logfile=None,
              loginterval=1):
     Dynamics.__init__(self, atoms, logfile=None, trajectory=trajectory)
     self.dt = timestep
     self.masses = self.atoms.get_masses()
     if 0 in self.masses:
         warnings.warn('Zero mass encountered in atoms; this will '
                       'likely lead to errors if the massless atoms '
                       'are unconstrained.')
     self.masses.shape = (-1, 1)
     if logfile:
         self.attach(MDLogger(dyn=self, atoms=atoms, logfile=logfile),
                     interval=loginterval)
Exemple #10
0
    def __init__(self, atoms,
                 temperature=100 * kB,
                 optimizer=SDLBFGS,
                 fmax=0.1,
                 dr=0.1,
                 logfile='-', 
                 trajectory=None,
                 optimizer_logfile='-',
                 local_minima_trajectory='local_minima.con',
                 adjust_cm=True,
                 mss=0.2,
                 minenergy=None,
                 distribution='uniform',
                 adjust_step_size=None,
                 adjust_every = None,
                 target_ratio = 0.5,
                 adjust_fraction = 0.05,
                 significant_structure = False,
                 pushapart = 0.4,
                 jumpmax=None
                 ):
        Dynamics.__init__(self, atoms, logfile, trajectory)
        self.kT = temperature
        self.optimizer = optimizer
        self.fmax = fmax
        self.dr = dr
        if adjust_cm:
            self.cm = atoms.get_center_of_mass()
        else:
            self.cm = None

        self.optimizer_logfile = optimizer_logfile
        self.lm_trajectory = local_minima_trajectory
        if isinstance(local_minima_trajectory, str):
            tsase.io.write_con(self.lm_trajectory,atoms,w='w')
        tsase.io.write_con('best_energies.con',atoms,w='w')
        self.minenergy = minenergy
        self.distribution = distribution
        self.adjust_step = adjust_step_size
        self.adjust_every = adjust_every
        self.target_ratio = target_ratio
        self.adjust_fraction = adjust_fraction
        self.significant_structure = True
        self.pushapart = pushapart
        self.jumpmax = jumpmax
        self.mss = mss
        self.initialize()
        self.norm_dists = [None] * len(self.positions)
        for i in range(len(self.norm_dists)):
            self.norm_dists[i] = []
Exemple #11
0
    def __init__(self, atoms,
                 temperature=100 * kB,
                 optimizer=SDLBFGS,
                 fmax=0.1,
                 dr=0.1,
                 logfile='-', 
                 trajectory=None,
                 optimizer_logfile='-',
                 local_minima_trajectory='local_minima.con',
                 mss=0.2,
                 minenergy=None,
                 adjust_step_size=None,
                 adjust_every = None,
                 target_ratio = 0.5,
                 adjust_fraction = 0.05,
                 pushapart = 0.4,
                 jumpmax=2,
                 inertia_weight=.4,
                 method='PSO'
                 ):
        Dynamics.__init__(self, atoms, logfile, trajectory)
        self.local_optimizations = 0
        self.bcms = 0
        self.kT = temperature
        self.optimizer = optimizer
        self.fmax = fmax
        self.dr = dr
        self.method = method

        self.cm = atoms.get_center_of_mass()

        self.optimizer_logfile = optimizer_logfile
        self.lm_trajectory = local_minima_trajectory
        self.minenergy = minenergy
        self.energy = 0
        self.adjust_step = adjust_step_size
        self.adjust_every = adjust_every
        self.target_ratio = target_ratio
        self.adjust_fraction = adjust_fraction 
        self.pushapart = pushapart
        self.jumpmax = jumpmax
        self.mss = mss
        self.inertia_weight = inertia_weight
        self.velocity = 0.0 * self.atoms.get_positions()
        self.initialize()
Exemple #12
0
    def __init__(self,
                 atoms,
                 temperature=100 * kB,
                 optimizer=FIRE,
                 fmax=0.1,
                 dr=0.1,
                 logfile='-',
                 trajectory='lowest.traj',
                 optimizer_logfile='-',
                 local_minima_trajectory='local_minima.traj',
                 adjust_cm=True):
        """Parameters:

        atoms: Atoms object
            The Atoms object to operate on.

        trajectory: string
            Pickle file used to store trajectory of atomic movement.

        logfile: file object or str
            If *logfile* is a string, a file with that name will be opened.
            Use '-' for stdout.
        """
        self.kT = temperature
        self.optimizer = optimizer
        self.fmax = fmax
        self.dr = dr
        if adjust_cm:
            self.cm = atoms.get_center_of_mass()
        else:
            self.cm = None

        self.optimizer_logfile = optimizer_logfile
        self.lm_trajectory = local_minima_trajectory
        if isinstance(local_minima_trajectory, str):
            self.db = connect(local_minima_trajectory[:-4] + 'db')
            self.lm_trajectory = Trajectory(local_minima_trajectory, 'a',
                                            atoms)

        Dynamics.__init__(self, atoms, logfile, trajectory)
        self.initialize()
Exemple #13
0
 def run(self, fmax=0.05, steps=None):
     self.fmax = fmax
     if steps:
         self.max_steps = steps
     old_positions = self.atoms.get_positions()
     for converged in Dynamics.irun(self):
         if (np.linalg.norm(self.atoms.get_positions() - self.start_geo) >
                 self.trustradius):
             print('Trust radius exceeded. Resetting to last position')
             self.atoms.set_positions(old_positions)
             break
         old_positions = self.atoms.get_positions()
     return converged
Exemple #14
0
    def __init__(self, atoms,
                 temperature=100 * kB,
                 optimizer=FIRE,
                 fmax=0.1,
                 dr=0.1,
                 logfile='-',
                 trajectory='lowest.traj',
                 optimizer_logfile='-',
                 local_minima_trajectory='local_minima.traj',
                 adjust_cm=True):
        """Parameters:

        atoms: Atoms object
            The Atoms object to operate on.

        trajectory: string
            Pickle file used to store trajectory of atomic movement.

        logfile: file object or str
            If *logfile* is a string, a file with that name will be opened.
            Use '-' for stdout.
        """
        self.kT = temperature
        self.optimizer = optimizer
        self.fmax = fmax
        self.dr = dr
        if adjust_cm:
            self.cm = atoms.get_center_of_mass()
        else:
            self.cm = None

        self.optimizer_logfile = optimizer_logfile
        self.lm_trajectory = local_minima_trajectory
        if isinstance(local_minima_trajectory, str):
            self.lm_trajectory = Trajectory(local_minima_trajectory,
                                            'w', atoms)

        Dynamics.__init__(self, atoms, logfile, trajectory)
        self.initialize()
Exemple #15
0
	def __init__(self, atoms, timestep, integrator='verlet', trajectory=None,
			traj_interval=1000, logfile=None, loginterval=100):
		Dynamics.__init__(self, atoms, None, None)

		self.dt = timestep
		
		if integrator == 'verlet':
			self.run_style = 'verlet'
		else:
			raise RuntimeError('Unknown integrator: %s' % thermostat)
		
		if trajectory:
			if isinstance(trajectory, str):
				trajectory = PickleTrajectory(trajectory, 'w', atoms)
			self.attach(trajectory, interval=traj_interval)
		
		if logfile:
			self.attach(MDLogger(dyn=self, atoms=atoms, logfile=logfile),
						interval=loginterval)
		
		self.fix = None
		self.cell_relaxed = False
Exemple #16
0
    def __init__(self,
                 atoms,
                 timestep,
                 trajectory,
                 logfile=None,
                 loginterval=1,
                 append_trajectory=False):

        # dt as to be attached _before_ parent class is initialized
        self.dt = timestep

        Dynamics.__init__(self, atoms, logfile=None, trajectory=None)

        self.masses = self.atoms.get_masses()
        self.max_steps = None

        if 0 in self.masses:
            warnings.warn('Zero mass encountered in atoms; this will '
                          'likely lead to errors if the massless atoms '
                          'are unconstrained.')

        self.masses.shape = (-1, 1)

        if not self.atoms.has('momenta'):
            self.atoms.set_momenta(np.zeros([len(self.atoms), 3]))

        # Trajectory is attached here instead of in Dynamics.__init__
        # to respect the loginterval argument.
        if trajectory is not None:
            if isinstance(trajectory, str):
                mode = "a" if append_trajectory else "w"
                trajectory = Trajectory(trajectory, mode=mode, atoms=atoms)
            self.attach(trajectory, interval=loginterval)

        if logfile:
            self.attach(MDLogger(dyn=self, atoms=atoms, logfile=logfile),
                        interval=loginterval)
Exemple #17
0
    def __init__(self,

                 # General GO parameters
                 atoms, # ASE atoms object defining the PES
                 temperature = 500, # K, initial temperature
                 optimizer = SDLBFGS, # local optimizer
                 fmax = 0.01, # magnitude of the L2 norm used as the convergence criteria for local optimization
                 adjust_cm = True, # fix the center of mass (True or False)
                 mss = 0.1, # maximum step size for the local optimizer
                 minenergy = None, # the GO algorithm stops when a configuration is found with a lower potential energy than this value
                 pushapart = 0.1, # push atoms apart until all atoms are no closer than this distance
                 keep_minima_arrays = True, # create global_minima and local_minima arrays of length maximum number of Monte Carlo steps (True or False)
                 minima_threshold = 2,  # round potential energies to how many decimal places

                 # Logging parameters
                 logfile = '-',
                 trajectory = None,
                 optimizer_logfile = None,
                 #local_minima_trajectory = 'local_minima.con',
                 local_minima_trajectory = None,

                 # Selecting move type
                 move_type = True, # True = basin hopping trial move; False = minima hopping
                 distribution = 'uniform', # The distribution to use in trial move. Make "molecular_dynamics" the distribution for MH trial move

                 # Random move parameters
                 dr = 0.45, # maximum displacement in each degree of freedom for Monte Carlo trial moves
                 adjust_step_size = None, # adjust dr after this many Monte Carlo steps (Default: None; does not adjust dr)
                 target_ratio = 0.5, # specified ratio of Monte Carlo steps
                 adjust_fraction = 0.05, # fraction by which to adjust dr by in order to meet target_ratio
                 significant_structure = True,  # displace from minimum at each move (True or False)

                 # Dynamic move parameters (Molecular Dynamics)
                 timestep = 0.1, # fs, molecular dynamics time step
                 mdmin = 2, # number of minima to pass in MD before stopping
                 dimer_method = True, # uses an iterative dimer method before molecular dynamics (True or False)
                 dimer_a = 0.001, # scalar for forces in optimization
                 dimer_d = 0.01, # distance between two images in the dimer
                 dimer_steps = 14, # number of dimer iterations

                 # Occasional jumping parameters
                 jump_distribution = 'uniform', # The distribution to use in OJ move. Same options as distribution flag
                 jumpmax = None, # number of previously rejected MC steps before taking an OJ move; None = no OJ move
                 jmp = 7, # number of consecutive accepted moves taken in OJ
                 global_jump = None, # number of times to visit the same PE before we take an OJ; None = no global jump
                 global_reset = False, # True = reset all of the history counts after a jump (basically delete the history and start fresh)

                 # Select acceptance criteria
                 acceptance_criteria = True, # BH = Tue; MH = False

                 # BH acceptance parameters
                 accept_temp = 8000, # K; separate temperature to use for BH acceptance (None: use temperature parameter instead)
                 adjust_temp = False, # dynamically adjust the temperature in BH acceptance (True or False)
                 history_weight = 0.0, # the weight factor of BH history >= 0 (0.0: no history comparison in BH acceptance)
                 history_num = 0, # limit of previously accepted minima to keep track of for BH history (set to 0 to keep track of all minima)

                 # MH acceptance criteria
                 beta1 = 1.04, # temperature adjustment parameter
                 beta2 = 1.04, # temperature adjustment parameter
                 beta3 = 1.0/1.04, # temperature adjustment parameter
                 Ediff0 = 0.5,  # eV, initial energy acceptance threshold
                 alpha1 = 0.98,  # energy threshold adjustment parameter
                 alpha2 = 1./0.98,  # energy threshold adjustment parameter
                 minimaHopping_history = False, # use history in MH trial move (True or False)

                 # Geometry comparison parameters
                 use_geometry = True, # True = compare geometry of systems when they have the same PE when determining if they are the same atoms configuration
                 eps_r = 0.1, # positional difference to consider atoms in the same location
                 use_get_mapping = True, # from atoms_operator.py use get_mapping if true or rot_match if false to compare geometry
                 neighbor_cutoff = 1.2, # parameter for get_mapping only
                 ):
        
        Dynamics.__init__(self, atoms, logfile, trajectory)
        self.temperature = temperature
        self.optimizer = optimizer
        self.fmax = fmax
        self.dr = dr
        if adjust_cm:
            self.cm = atoms.get_center_of_mass()
        else:
            self.cm = None

        self.optimizer_logfile = optimizer_logfile
        self.lm_trajectory = local_minima_trajectory
        if isinstance(local_minima_trajectory, str):
            tsase.io.write_con(self.lm_trajectory,atoms,w='w')
        self.minenergy = minenergy
        self.move_type = move_type
        self.distribution = distribution
        self.adjust_step = adjust_step_size
        self.target_ratio = target_ratio
        self.adjust_fraction = adjust_fraction
        self.significant_structure = significant_structure
        self.pushapart = pushapart
        self.jumpmax = jumpmax
        self.jmp = jmp
        self.jump_distribution = jump_distribution
        self.global_jump = global_jump
        self.global_reset = global_reset
        self.dimer_method = dimer_method
        self.dimer_a = dimer_a
        self.dimer_d = dimer_d
        self.dimer_steps = dimer_steps
        self.timestep = timestep
        self.mdmin = mdmin
        self.w = history_weight
        self.history_num = history_num
        self.adjust_temp = adjust_temp
        self.accept_temp = accept_temp
        self.accept_criteria = acceptance_criteria
        self.mh_history = minimaHopping_history
        self.beta1 = beta1
        self.beta2 = beta2
        self.beta3 = beta3
        self.Ediff = Ediff0
        self.alpha1 = alpha1
        self.alpha2 = alpha2
        self.minima_threshold = minima_threshold
        self.use_geo = use_geometry
        self.eps_r = eps_r
        self.use_get_mapping = use_get_mapping
        self.neighbor_cutoff = neighbor_cutoff
        self.keep_minima_arrays = keep_minima_arrays
        self.global_minima = [] # an array of the current global minimum for every MC step
        self.local_minima = [] # an array of the current local minimum for every MC step
        self.allTemps = []
        self.saveEdiff = []
        self.trial_loop = []
        self.num_localops = 0
        self.num_geo_compare = []

        # when a MD sim. has passed a local minimum:
        self.passedminimum = PassedMinimum()

        self.mss = mss
        # for PE comparision
        # dictionary for found local minima
        # keys will be the potential energy rounded to self.minima_threshold digits left of the decimal
        # values will be number of times the potential energy has been visited 
        self.minima = {}

        # list with fixed size that will store history_num previous minima
        self.temp_minima = [0] * self.history_num
        self.temp_positions = [0] * self.history_num

     	# for geometry comparison
        self.positionsMatrix = []
        # count of unique geometries we have accepted so far
        self.numPositions = 0
        # dictionary for geometry comparison
        # keys = approximate potential energy
        # values = list of indexes in positionsMatrix with the same PE
        self.geometries = {}
        # dictionary with keys = index in positionsMatrix
        # values = # accepted visits
        self.geo_history = {}
        self.current_index = None
        self.last_index = None
        # number of Monte Carlo moves that have been accepted in the run
        self.num_accepted_moves = 0.0
        self.initialize()
Exemple #18
0
    def __init__(self,
                 atoms,
                 maxstep=0.5,
                 parallel_drift=0.2,
                 energy_target=None,
                 angle_limit=None,
                 force_parallel_step_scale=None,
                 remove_translation=False,
                 use_FS=True,
                 initialize_old=True,
                 initialization_step_scale=1e-2,
                 use_target_shift=True,
                 target_shift_previous_steps=10,
                 seed=19460926,
                 verbose=False,
                 trajectory=None,
                 logfile=None,
                 use_tangent_curvature=False,
                 force_consistent=None,
                 append_trajectory=False,
                 loginterval=1):
        '''Perpendicular drift breaks orbits like dimer form, so they spin on new axes'''

        if force_parallel_step_scale is None:
            # a hureistic guess since most systems will overshoot when there is drift
            FPSS = 0.9 + 0.5 * parallel_drift
        else:
            FPSS = force_parallel_step_scale

        self.verbose = verbose
        self.seed = seed
        self.remove_translation = remove_translation
        self.use_FS = use_FS
        self.force_consistent = force_consistent
        self.kappa = 0.0  # initializing so logging can work
        self.use_tangent_curvature = use_tangent_curvature
        #### for FS taylor expansion
        self.T = None
        self.Told = None

        self.N = None
        self.Nold = None

        self.r_old = None
        self.r = None
        ###### initialize rng
        self.rng = default_rng(seed)

        #######
        if energy_target is None:
            self.energy_target = atoms.get_potential_energy(
                force_consistent=self.force_consistent)
        else:
            self.energy_target = energy_target

        # these need to be initialized before the initialize_old step so it doesn't crash
        self.previous_energies = np.zeros(target_shift_previous_steps)
        ## initizing the previous steps at the target energy slows
        ## target shifting untill the system has had
        ## 'target_shift_previous_steps' steps to equilibrate
        ## this should prevent occilations
        self.previous_energies.fill(self.energy_target)

        # we need velocities or this won't run and will produce NaNs,
        # if none are provided we make random ones
        p = atoms.get_momenta()
        masses = atoms.get_masses()[:, np.newaxis]
        v = p / masses
        from ase import units
        if np.linalg.norm(v) < 1e-6:
            # we have to pass dimension since atoms are not yet stored
            v = self.rand_vect((len(atoms), 3))
            atoms.set_momenta(v / masses)
            print("No Velocities found, random velocities applied")

        if initialize_old:
            #self.step_size  = maxstep*initialization_step_scale
            self.maxstep = maxstep * initialization_step_scale
            self.parallel_drift = 0.0
            ## should force_parallel_step_scale be 0.0 for a better initial curvature?
            ## Or at least smaller than 1.0? doesn't seem to matter much
            self.force_parallel_step_scale = 1.0
            self.use_target_shift = False
            self.atoms = atoms
            self.step()

        #self.step_size = maxstep # this interfers with logging
        self.maxstep = maxstep
        self.angle_limit = angle_limit
        self.parallel_drift = parallel_drift
        self.force_parallel_step_scale = FPSS
        self.use_target_shift = use_target_shift

        ## loginterval exists for the MolecularDynamics class but not the more
        ## general Dynamics class
        Dynamics.__init__(
            self,
            atoms,
            logfile,
            trajectory,  #loginterval,
            append_trajectory=append_trajectory,
        )
Exemple #19
0
    def __init__(self, atoms, timestep, trajectory, logfile=None,
                 loginterval=1, append_trajectory=False):
        """Molecular Dynamics object.

        Parameters:

        atoms: Atoms object
            The Atoms object to operate on.

        timestep: float
            The time step in ASE time units.

        trajectory: Trajectory object or str
            Attach trajectory object.  If *trajectory* is a string a
            Trajectory will be constructed.  Use *None* for no
            trajectory.

        logfile: file object or str (optional)
            If *logfile* is a string, a file with that name will be opened.
            Use '-' for stdout.

        loginterval: int (optional)
            Only write a log line for every *loginterval* time steps.  
            Default: 1

        append_trajectory: boolean (optional)
            Defaults to False, which causes the trajectory file to be
            overwriten each time the dynamics is restarted from scratch.
            If True, the new structures are appended to the trajectory
            file instead.
        """
        # dt as to be attached _before_ parent class is initialized
        self.dt = timestep

        Dynamics.__init__(self, atoms, logfile=None, trajectory=None)

        self.masses = self.atoms.get_masses()
        self.max_steps = None

        if 0 in self.masses:
            warnings.warn('Zero mass encountered in atoms; this will '
                          'likely lead to errors if the massless atoms '
                          'are unconstrained.')

        self.masses.shape = (-1, 1)

        if not self.atoms.has('momenta'):
            self.atoms.set_momenta(np.zeros([len(self.atoms), 3]))

        # Trajectory is attached here instead of in Dynamics.__init__
        # to respect the loginterval argument.
        try:
            if trajectory is not None:
                if isinstance(trajectory, str):
                    mode = "a" if append_trajectory else "w"
                    trajectory = self.ensureclose(
                        Trajectory(trajectory, mode=mode, atoms=atoms)
                    )
                self.attach(trajectory, interval=loginterval)

            if logfile:
                logger = self.ensureclose(
                    MDLogger(dyn=self, atoms=atoms, logfile=logfile))
                self.attach(logger, loginterval)

        except BaseException:
            self._closefiles()
            raise
Exemple #20
0
 def run(self, steps=50):
     """ Call Dynamics.run and adjust max_steps """
     self.max_steps = steps + self.nsteps
     return Dynamics.run(self)
Exemple #21
0
    def __init__(self,
                 atoms,
                 maxstep=0.5,
                 parallel_drift=0.1,
                 energy_target=None,
                 angle_limit=20,
                 potentiostat_step_scale=None,
                 remove_translation=False,
                 use_frenet_serret=True,
                 initialization_step_scale=1e-2,
                 use_target_shift=True,
                 target_shift_previous_steps=10,
                 use_tangent_curvature=False,
                 rng=np.random,
                 force_consistent=None,
                 trajectory=None,
                 logfile=None,
                 append_trajectory=False,
                 loginterval=1):
        """Contour Exploration object.

        Parameters:

        atoms: Atoms object
            The Atoms object to operate on. Atomic velocities are required for
            the method. If the atoms object does not contain velocities,
            random ones will be applied.

        maxstep: float
            Used to set the maximum distance an atom can move per
            iteration (default value is 0.5 Å).

        parallel_drift: float
            The fraction of the update step that is parallel to the contour but
            in a random direction. Used to break symmetries.

        energy_target: float
            The total system potential energy for that the potentiostat attepts
            to maintain. (defaults the initial potential energy)

        angle_limit: float or None
            Limits the stepsize to a maximum change of direction angle using the
            curvature. Gives a scale-free means of tuning the stepsize on the
            fly. Typically less than 30 degrees gives reasonable results but
            lower angle limits result in higher potentiostatic accuracy. Units
            of degrees. (default 20°)

        potentiostat_step_scale: float or None
            Scales the size of the potentiostat step. The potentiostat step is
            determined by linear extrapolation from the current potential energy
            to the target_energy with the current forces. A
            potentiostat_step_scale > 1.0 overcorrects and < 1.0
            undercorrects. By default, a simple heuristic is used to selected
            the valued based on the parallel_drift. (default None)

        remove_translation: boolean
            When True, the net momentum is removed at each step. Improves
            potentiostatic accuracy slightly for bulk systems but should not be
            used with constraints. (default False)

        use_frenet_serret: Bool
            Controls whether or not the Taylor expansion of the Frenet-Serret
            formulas for curved path extrapolation are used. Required for using
            angle_limit based step scalling. (default True)

        initialization_step_scale: float
            Controls the scale of the initial step as a multiple of maxstep.
            (default 1e-2)

        use_target_shift: boolean
            Enables shifting of the potentiostat target to compensate for
            systematic undercorrection or overcorrection by the potentiostat.
            Uses the average of the *target_shift_previous_steps* to prevent
            coupled occilations. (default True)

        target_shift_previous_steps: int
            The number of pevious steps to average when using use_target_shift.
            (default 10)

        use_tangent_curvature: boolean
            Use the velocity unit tangent rather than the contour normals from
            forces to compute the curvature. Usually not as accurate.
            (default False)

        rng: a random number generator
            Lets users control the random number generator for the
            parallel_drift vector. (default numpy.random)

         force_consistent: boolean
             (default None)

        trajectory: Trajectory object or str  (optional)
            Attach trajectory object.  If *trajectory* is a string a
            Trajectory will be constructed.  Default: None.

        logfile: file object or str (optional)
            If *logfile* is a string, a file with that name will be opened.
            Use '-' for stdout.  Default: None.

        loginterval: int (optional)
            Only write a log line for every *loginterval* time steps.
            Default: 1

        append_trajectory: boolean
            Defaults to False, which causes the trajectory file to be
            overwriten each time the dynamics is restarted from scratch.
            If True, the new structures are appended to the trajectory
            file instead.
        """

        if potentiostat_step_scale is None:
            # a heuristic guess since most systems will overshoot when there is
            # drift
            self.potentiostat_step_scale = 1.1 + 0.6 * parallel_drift
        else:
            self.potentiostat_step_scale = potentiostat_step_scale

        self.rng = rng
        self.remove_translation = remove_translation
        self.use_frenet_serret = use_frenet_serret
        self.force_consistent = force_consistent
        self.use_tangent_curvature = use_tangent_curvature
        self.initialization_step_scale = initialization_step_scale
        self.maxstep = maxstep
        self.angle_limit = angle_limit
        self.parallel_drift = parallel_drift
        self.use_target_shift = use_target_shift

        # These will be populated once self.step() is called, but could be set
        # after instantiating with ce = ContourExploration(...) like so:
        # ce.Nold = Nold
        # ce.r_old = atoms_old.get_positions()
        # ce.Told  = Told
        # to resume a previous contour trajectory.

        self.T = None
        self.Told = None
        self.N = None
        self.Nold = None
        self.r_old = None
        self.r = None

        if energy_target is None:
            self.energy_target = atoms.get_potential_energy(
                force_consistent=self.force_consistent)
        else:
            self.energy_target = energy_target

        # Initizing the previous steps at the target energy slows
        # target_shifting untill the system has had
        # 'target_shift_previous_steps' steps to equilibrate and should prevent
        # occilations. These need to be initialized before the initialize_old
        # step to prevent a crash
        self.previous_energies = np.full(target_shift_previous_steps,
                                         self.energy_target)

        # these first two are purely for logging,
        # auto scaling will still occur
        # and curvature will still be found if use_frenet_serret == True
        self.step_size = 0.0
        self.curvature = 0

        # loginterval exists for the MolecularDynamics class but not for
        # the more general Dynamics class
        Dynamics.__init__(
            self,
            atoms,
            logfile,
            trajectory,  # loginterval,
            append_trajectory=append_trajectory,
        )

        # we need velocities or NaNs will be produced,
        # if none are provided we make random ones
        velocities = self.atoms.get_velocities()
        if np.linalg.norm(velocities) < 1e-6:
            # we have to pass dimension since atoms are not yet stored
            atoms.set_velocities(self.rand_vect())
Exemple #22
0
    def __init__(
        self,
        atoms,
        temperature=1500.0,
        maximum_temp=None,
        minimum_temp=None,
        stop_steps=400,
        logfile='grandcanonical.log',
        trajectory='grandcanonical.traj',
        local_minima_trajectory='local_minima.traj',
        local_minima_trajecotry_db="local_minima.db",
        adjust_cm=False,
        restart=False,
        chemical_potential=None,
        bash_script="optimize.sh",
        files_to_copied=None,
    ):
        """Parameters:

        atoms: Atoms object
            The Atoms object to operate on.

        trajectory: string
            Pickle file used to store trajectory of atomic movement.

        logfile: file object or str
            If *logfile* is a string, a file with that name will be opened.
            Use '-' for stdout.
        """
        self.T = temperature
        if maximum_temp is None:
            self.max_T = 1.0 / ((1.0 / self.T) / 1.5)
        else:
            self.max_T = max([maximum_temp, self.T])
        if minimum_temp is None:
            self.min_T = 1.0 / ((1.0 / self.T) * 1.5)
        else:
            self.min_T = min([minimum_temp, self.T])
        self.stop_steps = stop_steps
        self.restart = restart
        self.bash_script = bash_script
        self.copied_files = files_to_copied

        # some file names and folders are hardcoded
        self.fn_current_atoms = "Current_atoms.traj"
        self.fn_status_file = "Current_Status.json"
        self.opt_folder = "opt_folder"

        self.structure_modifiers = {}

        self.adjust_cm = adjust_cm

        if 0:
            self.lm_trajectory = local_minima_trajectory
            if isinstance(local_minima_trajectory, str):
                self.lm_trajectory = Trajectory(local_minima_trajectory, 'a',
                                                atoms)
        self.lm_trajectory = connect(local_minima_trajecotry_db)

        # Dynamics.__init__ simply set
        # self.atoms and
        # self.logfile and
        # self.trajectory and
        # self.nsteps
        Dynamics.__init__(self, atoms, logfile, trajectory)

        # print the program logo at the beginning of the output file
        self.logfile.write("%s\n" % programlogo)
        self.logfile.flush()

        # setup the chemical potential for different elements
        self.mu = {}
        if chemical_potential is not None and os.path.isfile(
                chemical_potential):
            with open(chemical_potential, "r") as fp:
                for i, istr in enumerate(fp):
                    if istr.strip() == "":
                        continue
                    k, v = istr.split()
                    self.mu[k] = float(v)
        else:
            raise RuntimeError("chemical potential file %s is not found" %
                               chemical_potential)
        for k, v in self.mu.items():
            self.dumplog("Chemical potential of %s is %.3f" % (k, v))

        # try to read previous result
        if self.restart:
            if (not os.path.isfile(self.fn_status_file)) or (
                    not os.path.isfile(self.fn_current_atoms)):
                self.dumplog("%s or %s no found, start from scratch\n" %
                             (self.fn_current_atoms, self.fn_status_file))
                self.restart = False
            elif os.path.getsize(self.fn_current_atoms) == 0:
                self.dumplog("{} is empty, set self.restart=False".format(
                    self.fn_current_atoms))
                self.restart = False
            else:
                try:
                    atoms = read(self.fn_current_atoms)
                    atoms.get_potential_energy()
                except PropertyNotImplementedError:
                    self.dumplog(
                        "No energy found in {}, set self.restart=False".format(
                            self.fn_current_atoms))
                    self.restart = False
                except RuntimeError as e:
                    self.dumplog(
                        "Error when read {}, set self.restart=False".format(e))
                    self.restart = False

        self.energy = None
        self.free_energy = None
        self.energy_min = None
        self.free_energy_min = None
        self.no_improvement_step = 0
        # negative value indicates no on-going structure optimization, otherwise it will be the  on-going optimization
        self.on_optimization = -1

        # this is used for adjusting the temperature of Metropolis algorithm
        self.accept_history = [
        ]  # a series of 0 and 1, 0 stands for not accpeted, 1 stands for accepted
        self.max_history = 25  # max length of self.accept_history is 25

        if not self.restart:
            self.initialize()
        else:
            self.reload_previous_results()
Exemple #23
0
	def __init__(self, atoms, restart=None, logfile=None, trajectory=None, algorithm='cg', relax_cell=False):
		Dynamics.__init__(self, atoms, logfile, trajectory)
		self.algorithm = algorithm
		self.relax_cell = relax_cell
Exemple #24
0
 def __init__(
     self,
     atoms,
     temperature=100 * kB,
     optimizer=FIRE,
     optimizer2=FIRE,  #which optimizer to use to fmax_mult*fmax
     fmax_mult=15,  #at what multiple of fmax do you want to use second optimizer
     fmax=0.1,
     dr=0.1,
     logfile='-',
     trajectory='lowest.traj',
     optimizer_logfile='stdout.log',
     local_minima_trajectory='temp_local_minima.traj',  #local minima found
     adjust_cm=True,
     movemode=0,  #Pick a way for displacement. 0->random cartesian, 1->delocalized internals, 2->Periodic
     maxmoves=1000,  #Should prevent an issue, where you get stuck in a structure, for which get_energy() fails
     numdelocmodes=1,  #should a LC of modes be applied for the displacement? How many should be combined?
     adsorbmask=None,  #mask that specifies where the adsorbate is located in the atoms object (list of lowest and highest pos)
     cell_scale=[1.0, 1.0, 1.0],  #used for translation in adsorbates
     constrain=False):  #constrain stretches?
     Dynamics.__init__(self, atoms, logfile, trajectory)
     if adsorbmask is None:
         self.adsorbate = (0, len(atoms))
         self.ads = False
     else:
         self.adsorbate = adsorbmask
         self.ads = True
     self.fmax_mult = fmax_mult
     self.cell_scale = cell_scale
     self.kT = temperature
     if numdelocmodes < 1:
         if self.ads:
             self.numdelmodes = int(
                 np.round(numdelocmodes *
                          len(atoms[self.adsorbate[0]:self.adsorbate[1]]) *
                          3))  #3N dis in adsorbates
         else:
             self.numdelmodes = int(
                 np.round(numdelocmodes *
                          (len(atoms) * 3 - 6)))  #3N-6 dis in gas phase
     else:
         self.numdelmodes = int(np.round(
             numdelocmodes))  #round and int just for you trolls out there
     self.optimizer = optimizer
     self.optimizer2 = optimizer2
     self.fmax = fmax
     self.mm = maxmoves
     self.dr = dr
     self.lowstep = 0
     self.movemode = movemode
     self.movename = 'Random Cartesian'
     self.minima = []
     self.constr = constrain
     if movemode == 1:
         self.movename = 'Delocalized Internals, using %i modes' % self.numdelmodes
     elif movemode == 2:
         self.movename = 'Periodic DI'
     if adjust_cm:
         self.cm = atoms.get_center_of_mass()
     else:
         self.cm = None
     self.lmfile = local_minima_trajectory
     self.optimizer_logfile = optimizer_logfile
     self.lm_trajectory = local_minima_trajectory
     if isinstance(local_minima_trajectory, str):
         self.lm_trajectory = Trajectory(local_minima_trajectory, 'a',
                                         atoms)
     self.startT = datetime.now()
     self.log(msg='STARTING BASINHOPPING at ' +
              self.startT.strftime('%Y-%m-%d %H:%M:%S') +
              ':\n Displacements: ' + self.movename +
              ' Stepsize: %.3f fmax: %.3f T: %4.2f\n' %
              (self.dr, self.fmax, self.kT / kB))
     self.positions = 0.0 * self.atoms.get_positions()
     self.Emin = self.get_energy(self.atoms.get_positions()) or 1.e15
     self.rmin = self.atoms.get_positions()
     self.call_observers()
     self.log(-1, self.Emin, self.Emin)
Exemple #25
0
    def __init__(
            self,
            atoms,
            temperature=100 * kB,
            optimizer=SDLBFGS,
            fmax=0.1,
            move_atoms=True,
            dr=0.1,
            swap_atoms=False,
            elements_lib=None,  #elements which will be swapped, i.e., elements_lib = ['Au', 'Rh']
            active_ratio=1.0,  #define the number of atoms moved or swapped each time
            visited_configs={},  # {'state_number': [energy, atoms, repeats], ...},
            comp_eps_e=1.e-4,  #criterion to determine if two configurations are identtical in energy 
            comp_eps_r=0.02,  #criterion to determine if two configurations are identical in geometry
            logfile='-',
            trajectory=None,
            optimizer_logfile='-',
            local_minima_trajectory='local_minima.con',
            adjust_cm=True,
            mss=0.05,
            minenergy=None,
            distribution='uniform',
            adjust_step_size=None,
            target_ratio=0.5,
            adjust_fraction=0.05,
            significant_structure=False,  # displace from minimum if accept
            #   significant_structure2 = False, # displace from global minimum found so far at each move
        pushapart=0.4,
            jumpmax=5000):
        Dynamics.__init__(self, atoms, logfile, trajectory)
        self.kT = temperature
        self.optimizer = optimizer
        self.fmax = fmax
        self.move_atoms = move_atoms
        self.dr = dr
        self.swap_atoms = swap_atoms
        self.elements_lib = elements_lib
        self.active_ratio = active_ratio
        self.visited_configs = visited_configs
        self.comp_eps_e = comp_eps_e
        self.comp_eps_r = comp_eps_r

        if adjust_cm:
            self.cm = atoms.get_center_of_mass()
        else:
            self.cm = None

        self.optimizer_logfile = optimizer_logfile
        self.lm_trajectory = local_minima_trajectory
        if isinstance(local_minima_trajectory, str):
            tsase.io.write_con(self.lm_trajectory, atoms, w='w')
        self.minenergy = minenergy
        self.distribution = distribution
        self.adjust_step_size = adjust_step_size
        self.target_ratio = target_ratio
        self.adjust_fraction = adjust_fraction
        self.significant_structure = significant_structure
        #     self.significant_structure2 = significant_structure2
        self.pushapart = pushapart
        self.jumpmax = jumpmax
        self.mss = mss
        self.initialize()