Exemple #1
0
 def __init__(self, atoms, 
              timestep, temperature, externalstress, ttime, pfactor,
              mask=None, trajectory=None, logfile=None, loginterval=1):
     ParallelMolDynMixin.__init__(self, 'NPT', atoms)
     aseNPT.__init__(self, atoms, 
              timestep, temperature, externalstress, ttime, pfactor,
              mask=mask, trajectory=trajectory, logfile=logfile,
              loginterval=loginterval)
Exemple #2
0
    def __init__(self, atoms, timestep, temperature, externalstress, 
            ttime, pfactor, mask=None, trajectory=None, **kwargs):

        NPT.__init__(self, atoms, timestep, temperature,
                     externalstress, ttime, pfactor, mask,
                     trajectory)

        OTF.__init__(self, **kwargs)

        self.md_engine = 'NPT'
 def _molecular_dynamics(self, resume=None):
     """Performs a molecular dynamics simulation, until mdmin is
     exceeded. If resuming, the file number (md%05i) is expected."""
     self._log('msg', 'Molecular dynamics: md%05i' % self._counter)
     mincount = 0
     energies, oldpositions = [], []
     thermalized = False
     if resume:
         self._log('msg', 'Resuming MD from md%05i.traj' % resume)
         if os.path.getsize('md%05i.traj' % resume) == 0:
             self._log(
                 'msg', 'md%05i.traj is empty. Resuming from '
                 'qn%05i.traj.' % (resume, resume - 1))
             atoms = io.read('qn%05i.traj' % (resume - 1), index=-1)
         else:
             images = io.Trajectory('md%05i.traj' % resume, 'r')
             for atoms in images:
                 energies.append(atoms.get_potential_energy())
                 oldpositions.append(atoms.positions.copy())
                 passedmin = self._passedminimum(energies)
                 if passedmin:
                     mincount += 1
             self._atoms.set_momenta(atoms.get_momenta())
             thermalized = True
         self._atoms.positions = atoms.get_positions()
         self._log('msg',
                   'Starting MD with %i existing energies.' % len(energies))
     if not thermalized:
         MaxwellBoltzmannDistribution(self._atoms,
                                      temp=self._temperature * units.kB,
                                      force_temp=True)
     traj = io.Trajectory('md%05i.traj' % self._counter, 'a', self._atoms)
     self._constrain()
     dyn = NPT(self._atoms,
               timestep=self._timestep * units.fs,
               temperature=self._temperature * units.kB,
               externalstress=self._externalstress,
               ttime=self._ttime * units.fs,
               pfactor=self._pfactor * units.fs**2)
     #        dyn = NPTber(self._atoms, timestep=self._timestep * units.fs, temperature=self._temperature, fixcm=True, pressure=self._pressure, taut=self._taut * units.fs, taup=self._taup * units.fs, compressibility=self._compressibility)
     log = MDLogger(dyn,
                    self._atoms,
                    'md%05i.log' % self._counter,
                    header=True,
                    stress=False,
                    peratom=False)
     dyn.attach(log, interval=1)
     dyn.attach(traj, interval=1)
     while mincount < self._mdmin:
         #            self._constrain()
         dyn.run(1)
         #            del self._atoms.constraints
         energies.append(self._atoms.get_potential_energy())
         passedmin = self._passedminimum(energies)
         if passedmin:
             mincount += 1
         oldpositions.append(self._atoms.positions.copy())
     # Reset atoms to minimum point.
     self._atoms.positions = oldpositions[passedmin[0]]
Exemple #4
0
def fly(temperature, updates, atoms=None, cutoff=None, au=None, calc=None, kern=None, dt=2., tsteps=10,
        ext_stress=0, pfactor=None, mask=None, ediff=0.1, fdiff=0.1, group=None, lf_kwargs={}):
    atoms, model, new_model, traj, log = strategy(atoms, temperature)
    if model is None:
        if not kern:
            kern = default_kernel(np.unique(atoms.numbers), cutoff, au=au)
    else:
        model = PosteriorPotentialFromFolder(model, group=group)
        kern = model.gp
    atoms.set_calculator(calc if calc else my_vasp())
    if hasattr(pfactor, '__iter__'):
        psteps, bulk_modulus = pfactor
        ptime = psteps*dt
        pfactor = (ptime**2)*bulk_modulus
    ase_dyn = NPT(atoms, dt*units.fs, temperature*units.kB, ext_stress,
                  tsteps*dt*units.fs, pfactor, mask=mask, trajectory=traj)
    dyn = Leapfrog(ase_dyn, kern, model=model,
                   algorithm='ultrafast',
                   ediff=ediff, fdiff=fdiff,
                   correct_verlet=False,
                   logfile=log,
                   group=group,
                   **lf_kwargs)
    dyn.run_updates(updates)
    dyn.model.to_folder(new_model)
    if calc is None:
        clean_vasp()
    if group is not None:
        torch.distributed.barrier()
    return dyn.model
Exemple #5
0
def npt_dynamics(atoms, dt, tem, bulk_modulus, stress, mask, iso, trajectory,
                 loginterval, append, tdamp, pdamp):
    ttime = tdamp * units.fs
    ptime = pdamp * units.fs
    if bulk_modulus:
        pfactor = (ptime**2) * bulk_modulus * units.GPa
    else:
        pfactor = None
    configure_cell(atoms)
    dyn = NPT(atoms,
              dt * units.fs,
              temperature_K=tem,
              externalstress=stress * units.GPa,
              ttime=ttime,
              pfactor=pfactor,
              mask=mask,
              trajectory=trajectory,
              append_trajectory=append,
              loginterval=loginterval)
    if iso:
        dyn.set_fraction_traceless(0.)
    return dyn
Exemple #6
0
 def __init__(self,
              atoms,
              timestep,
              temperature,
              externalstress,
              ttime,
              pfactor,
              mask=None,
              trajectory=None,
              logfile=None,
              loginterval=1):
     ParallelMolDynMixin.__init__(self, 'NPT', atoms)
     aseNPT.__init__(self,
                     atoms,
                     timestep,
                     temperature,
                     externalstress,
                     ttime,
                     pfactor,
                     mask=mask,
                     trajectory=trajectory,
                     logfile=logfile,
                     loginterval=loginterval)
Exemple #7
0
def mlmd(atoms,
         covariance=None,
         calc_script=None,
         dt=None,
         tem=300.,
         picos=100,
         bulk_modulus=None,
         stress=0.,
         mask=None,
         group=None,
         tape='model.sgpr',
         trajectory='md.traj',
         loginterval=1,
         append=False,
         rattle=0.0,
         ediff=0.041,
         fdiff=0.082,
         coveps=1e-4,
         random_seed=None):
    """
    atoms:        ASE atoms
    covariance:   kernel or model
    calc_script:  path to a python script where the DFT calculator is defined
    dt:           time-step in fs
    tem:          temperature in Kelvin
    picos:        pico-seconds for md
    bulk_modulus: bulk_modulus for NPT simulations. if None, NVT is performed
    stress:       external stress (GPa) for NPT
    mask:         see ase.npt.NPT
    group:        process-group for MPI. if None, it is initiated
    tape:         checkpoint for the ML potential
    trajectory:   traj file name
    loginterval:  for traj file
    append:       append to traj file
    rattle:       rattle atoms at initial step (recommended ~0.05)
    ediff:        energy sensitivity
    fdiff:        force sensitivity
    coveps:       skips ML update if covloss < coveps
    """
    # set calculator
    if calc_script is not None:
        calc_script = SocketCalculator(script=calc_script)
    calc = ActiveCalculator(covariance=covariance,
                            calculator=calc_script,
                            process_group=group or mpi_init(),
                            tape=tape,
                            fdiff=fdiff,
                            ediff=ediff,
                            coveps=coveps)

    if random_seed:
        np.random.seed(random_seed)

    # process atoms
    if type(atoms) == str:
        if atoms.startswith('export'):
            folder = atoms.split('-')[1] if '-' in atoms else 'model'
            calc.model.to_folder(folder)
            return
        else:
            atoms = read(atoms)
    atoms.rattle(rattle, rng=np.random)  # rattle after mpi_init
    atoms.set_calculator(calc)

    # define and run Nose-Hoover dynamics
    if dt is None:
        if (atoms.numbers == 1).any():
            dt = 0.25
        else:
            dt = 1.
    ttime = 25 * units.fs
    ptime = 100 * units.fs
    if bulk_modulus:
        pfactor = (ptime**2) * bulk_modulus * units.GPa
    else:
        pfactor = None
    init_velocities(atoms, tem)
    make_cell_upper_triangular(atoms)
    filtered = FilterDeltas(atoms)
    steps_for_1ps = int(1000 / dt)
    dyn = NPT(filtered,
              dt * units.fs,
              tem * units.kB,
              stress * units.GPa,
              ttime,
              pfactor,
              mask=mask,
              trajectory=trajectory,
              append_trajectory=append,
              loginterval=loginterval)
    dyn.run(picos * steps_for_1ps)
Exemple #8
0
from ase.io.trajectory import Trajectory
from ase.io import read
from ase.md.npt import NPT
from ase.units import fs, kB


atoms = read('Na_in_water.xyz')

calc = GPAW(mode='lcao',
            xc='PBE',
            basis='dzp',
            symmetry={'point_group': False},
            charge=1,
            txt='gpawOutput.gpaw-out')

atoms.set_calculator(calc)

dyn = NPT(atoms,
	  pfactor=None,
          externalstress=0,
          temperature=350*kB,
          timestep=0.5*fs,
          ttime=20*fs,
          logfile='mdOutput.log')

trajectory = Trajectory('nptDyn.traj', 'w', atoms)
dyn.attach(trajectory.write, interval=1)


dyn.run(4000)
Exemple #9
0
 def __init__(self, atoms, *args, **kwargs):
     aseNPT.__init__(self, atoms, *args, **kwargs)
     if getattr(atoms, "parallel", False):
         raise NotImplementedError("NPT dynamics does not work in parallel with this version of ASE.  Please use the developer version.")
    )
start = time.time()
calc = GPAW(mode='lcao',
            xc='PBE',
            basis='dzp',
            symmetry={'point_group': False},
            charge=1,
            h=0.2,
            txt='out_mdTask1.txt')

a.set_calculator(calc)

dyn = NPT(atoms=a,
          timestep=dt,
          temperature=350 * kB,
          externalstress=0,
          ttime=20 * fs,
          pfactor=None,
          logfile='log_mdTask1.txt')  # Using the Nosé-Hoover thermostat

trajectory = Trajectory('mdTask1.traj', 'w', a)
dyn.attach(
    trajectory.write,
    interval=1)  # Write state of the system to trajectory at every timestep
dyn.run(N_steps)
end = time.time()
if world.rank == 0:
    print('-------- MD simulation finished in: ' +
          f'{(end-start):.2f} s --------'.rjust(34))
    print(
        '----------------------------------------------------------------------'
Exemple #11
0
# atoms,
# d_t,
# trajectory = label+'.traj',
# logfile = 'log_'+label+'.txt',
# )
# from ase.md import Langevin
# dyn = Langevin(
# atoms       = atoms,
# timestep    = 10 *units.fs,
# temperature_K = temp,
# friction    = 1e-02,
# trajectory  = label+'.traj',
# logfile     = 'log_'+label+'.txt',
# )
from ase.md.npt import NPT
dyn = NPT(
    atoms=atoms,
    timestep=d_t,
    temperature_K=temp,
    externalstress=0.,
    ttime=75 * units.fs,
    pfactor=(75. * units.fs)**2 * 100. * units.GPa,
    trajectory=label + '.traj',
    logfile='log_' + label + '.txt',
)
### relax option
dyn.set_fraction_traceless(0)  # 0 --> no shape change but yes volume change
dyn.run(
    steps=t_step
)  #MD simulation of object 'dyn' is performed by 'run' method of VV class
Exemple #12
0
 def __init__(self, atoms, *args, **kwargs):
     aseNPT.__init__(self, atoms, *args, **kwargs)
     if getattr(atoms, "parallel", False):
         raise NotImplementedError(
             "NPT dynamics does not work in parallel with this version of ASE.  Please use the developer version."
         )
Exemple #13
0
    os.remove(ase_db)
kspacing = 0.2
steps = 10

struc = bulk("Si", 'diamond', a=5.468728, cubic=True)
mliap = "potentials/Si-20-20.pth"
ff = PyXtal_FF(model={'system': ["Si"]}, logo=False)
ff.run(mode='predict', mliap=mliap)
calc = PyXtalFFCalculator(ff=ff)
struc.set_calculator(calc)

#struc.set_calculator(set_vasp('single', kspacing))
#energy, forces = dft_run(struc, path=dumpfolder, ncpu=16, max_time=10) # total energy

# MD
traj = Trajectory("Si.traj", 'w', struc)
MaxwellBoltzmannDistribution(struc, temperature_K=300)
dyn = NPT(struc,
          0.1 * units.fs,
          externalstress=0.,
          ttime=1000 * units.fs,
          pfactor=1000 * units.fs,
          temperature_K=300)
dyn.attach(traj.write, interval=steps)

for i in range(1000):
    dyn.run(steps=steps)
    PrintEnergy(struc)
    save_to_ASE_db(struc, path=ase_db)
traj.close()
    def init_md(
        self,
        name,
        time_step=0.5,
        temp_init=300,
        temp_bath=None,
        external_stress=None,
        ttime=None,
        pfactor=None,
        reset=False,
        interval=1,
    ):
        """
        Initialize an ase molecular dynamics trajectory. The logfile needs to
        be specifies, so that old trajectories are not overwritten. This
        functionality can be used to subsequently carry out equilibration and
        production.

        Args:
            name (str): Basic name of logfile and trajectory
            time_step (float): Time step in fs (default=0.5)
            temp_init (float): Initial temperature of the system in K
                (default is 300)
            temp_bath (float): Carry out Langevin NVT dynamics at the specified
                temperature. If set to None, NVE dynamics are performed
                instead (default=None)
            reset (bool): Whether dynamics should be restarted with new initial
                conditions (default=False)
            interval (int): Data is stored every interval steps (default=1)
        """

        # If a previous dynamics run has been performed, don't reinitialize
        # velocities unless explicitly requested via restart=True
        if not self.dynamics or reset:
            self._init_velocities(temp_init=temp_init)

        # Set up dynamics
        if temp_bath is None and external_stress is None:
            self.dynamics = VelocityVerlet(self.molecule, time_step * units.fs)
        elif external_stress is None:
            self.dynamics = Langevin(
                self.molecule,
                time_step * units.fs,
                temp_bath * units.kB,
                1.0 / (100.0 * units.fs),
            )
        else:
            self.dynamics = NPT(
                self.molecule,
                time_step * units.fs,
                temp_bath * units.kB,
                external_stress * units.GPa,
                ttime * units.fs,
                pfactor * units.fs**2 * units.GPa,
            )

        # Create monitors for logfile and a trajectory file
        logfile = os.path.join(self.working_dir, "%s.log" % name)
        trajfile = os.path.join(self.working_dir, "%s.traj" % name)
        logger = MDLogger(
            self.dynamics,
            self.molecule,
            logfile,
            stress=False,
            peratom=False,
            header=True,
            mode="a",
        )
        trajectory = Trajectory(trajfile, "w", self.molecule)

        # Attach monitors to trajectory
        self.dynamics.attach(logger, interval=interval)
        self.dynamics.attach(trajectory.write, interval=interval)
class AseInterface:
    """
    Interface for ASE calculations (optimization and molecular dynamics)

    Args:
        molecule_path (str): Path to initial geometry
        ml_model (object): Trained model
        working_dir (str): Path to directory where files should be stored
        device (str): cpu or cuda
    """
    def __init__(
            self,
            molecule_path,
            ml_model,
            working_dir,
            device="cpu",
            energy="energy",
            forces="forces",
            energy_units="eV",
            forces_units="eV/Angstrom",
            environment_provider=SimpleEnvironmentProvider(),
    ):
        # Setup directory
        self.working_dir = working_dir
        if not os.path.exists(self.working_dir):
            os.makedirs(self.working_dir)

        # Load the molecule
        self.molecule = None
        self._load_molecule(molecule_path)

        # Set up calculator
        calculator = SpkCalculator(
            ml_model,
            device=device,
            energy=energy,
            forces=forces,
            energy_units=energy_units,
            forces_units=forces_units,
            environment_provider=environment_provider,
        )
        self.molecule.set_calculator(calculator)

        # Unless initialized, set dynamics to False
        self.dynamics = False

    def _load_molecule(self, molecule_path):
        """
        Load molecule from file (can handle all ase formats).

        Args:
            molecule_path (str): Path to molecular geometry
        """
        file_format = os.path.splitext(molecule_path)[-1]
        if file_format == "xyz":
            self.molecule = read_xyz(molecule_path)
        else:
            self.molecule = read(molecule_path)

    def save_molecule(self, name, file_format="xyz", append=False):
        """
        Save the current molecular geometry.

        Args:
            name (str): Name of save-file.
            file_format (str): Format to store geometry (default xyz).
            append (bool): If set to true, geometry is added to end of file
                (default False).
        """
        molecule_path = os.path.join(self.working_dir,
                                     "%s.%s" % (name, file_format))
        if file_format == "xyz":
            # For extended xyz format, plain is needed since ase can not parse
            # the extxyz it writes
            write_xyz(molecule_path, self.molecule, plain=True)
        else:
            write(molecule_path,
                  self.molecule,
                  format=file_format,
                  append=append)

    def calculate_single_point(self):
        """
        Perform a single point computation of the energies and forces and
        store them to the working directory. The format used is the extended
        xyz format. This functionality is mainly intended to be used for
        interfaces.
        """
        energy = self.molecule.get_potential_energy()
        forces = self.molecule.get_forces()
        self.molecule.energy = energy
        self.molecule.forces = forces

        self.save_molecule("single_point", file_format="extxyz")

    def init_md(
        self,
        name,
        time_step=0.5,
        temp_init=300,
        temp_bath=None,
        external_stress=None,
        ttime=None,
        pfactor=None,
        reset=False,
        interval=1,
    ):
        """
        Initialize an ase molecular dynamics trajectory. The logfile needs to
        be specifies, so that old trajectories are not overwritten. This
        functionality can be used to subsequently carry out equilibration and
        production.

        Args:
            name (str): Basic name of logfile and trajectory
            time_step (float): Time step in fs (default=0.5)
            temp_init (float): Initial temperature of the system in K
                (default is 300)
            temp_bath (float): Carry out Langevin NVT dynamics at the specified
                temperature. If set to None, NVE dynamics are performed
                instead (default=None)
            reset (bool): Whether dynamics should be restarted with new initial
                conditions (default=False)
            interval (int): Data is stored every interval steps (default=1)
        """

        # If a previous dynamics run has been performed, don't reinitialize
        # velocities unless explicitly requested via restart=True
        if not self.dynamics or reset:
            self._init_velocities(temp_init=temp_init)

        # Set up dynamics
        if temp_bath is None and external_stress is None:
            self.dynamics = VelocityVerlet(self.molecule, time_step * units.fs)
        elif external_stress is None:
            self.dynamics = Langevin(
                self.molecule,
                time_step * units.fs,
                temp_bath * units.kB,
                1.0 / (100.0 * units.fs),
            )
        else:
            self.dynamics = NPT(
                self.molecule,
                time_step * units.fs,
                temp_bath * units.kB,
                external_stress * units.GPa,
                ttime * units.fs,
                pfactor * units.fs**2 * units.GPa,
            )

        # Create monitors for logfile and a trajectory file
        logfile = os.path.join(self.working_dir, "%s.log" % name)
        trajfile = os.path.join(self.working_dir, "%s.traj" % name)
        logger = MDLogger(
            self.dynamics,
            self.molecule,
            logfile,
            stress=False,
            peratom=False,
            header=True,
            mode="a",
        )
        trajectory = Trajectory(trajfile, "w", self.molecule)

        # Attach monitors to trajectory
        self.dynamics.attach(logger, interval=interval)
        self.dynamics.attach(trajectory.write, interval=interval)

    def _init_velocities(self,
                         temp_init=300,
                         remove_translation=True,
                         remove_rotation=True):
        """
        Initialize velocities for molecular dynamics

        Args:
            temp_init (float): Initial temperature in Kelvin (default 300)
            remove_translation (bool): Remove translation components of
                velocity (default True)
            remove_rotation (bool): Remove rotation components of velocity
                (default True)
        """
        MaxwellBoltzmannDistribution(self.molecule, temp_init * units.kB)
        if remove_translation:
            Stationary(self.molecule)
        if remove_rotation:
            ZeroRotation(self.molecule)

    def run_md(self, steps):
        """
        Perform a molecular dynamics simulation using the settings specified
        upon initializing the class.

        Args:
            steps (int): Number of simulation steps performed
        """
        if not self.dynamics:
            raise AttributeError("Dynamics need to be initialized using the"
                                 " 'setup_md' function")

        self.dynamics.run(steps)

    def optimize(self, fmax=1.0e-2, steps=1000):
        """
        Optimize a molecular geometry using the Quasi Newton optimizer in ase
        (BFGS + line search)

        Args:
            fmax (float): Maximum residual force change (default 1.e-2)
            steps (int): Maximum number of steps (default 1000)
        """
        name = "optimization"
        optimize_file = os.path.join(self.working_dir, name)
        optimizer = QuasiNewton(
            self.molecule,
            trajectory="%s.traj" % optimize_file,
            restart="%s.pkl" % optimize_file,
        )
        optimizer.run(fmax, steps)

        # Save final geometry in xyz format
        self.save_molecule(name)

    def compute_normal_modes(self, write_jmol=True):
        """
        Use ase calculator to compute numerical frequencies for the molecule

        Args:
            write_jmol (bool): Write frequencies to input file for
                visualization in jmol (default=True)
        """
        freq_file = os.path.join(self.working_dir, "normal_modes")

        # Compute frequencies
        frequencies = Vibrations(self.molecule, name=freq_file)
        frequencies.run()

        # Print a summary
        frequencies.summary()

        # Write jmol file if requested
        if write_jmol:
            frequencies.write_jmol()
Exemple #16
0
npt = False
tem = 1000.
stress = 0.
dt = 1.
ttime = 25 * units.fs
ptime = 100 * units.fs
bulk_modulus = 137.
pfactor = (ptime**2) * bulk_modulus * units.GPa
init_velocities(atoms, tem)
# make_cell_upper_triangular(atoms)
filtered = FilterDeltas(atoms)
dyn = NPT(filtered,
          dt * units.fs,
          temperature_K=tem,
          externalstress=stress * units.GPa,
          ttime=ttime,
          pfactor=pfactor if npt else None,
          mask=None,
          trajectory='md.traj',
          append_trajectory=False,
          loginterval=1)

# F. run md
dyn.run(1000)

# G. save model manually (necessary only if pckl=None above)
# calc.model.to_folder('model.pckl')

# H. restart
#    calc = ActiveCalculator(covariance='model.pckl/', ...)

# I. using the saved tapes (.sgpr files)