Exemple #1
0
    def __init__(self, system, alpha, scalings):
        '''
           **Arguments:**

           system
                The system to which this interaction applies.

           alpha
                The alpha parameter in the Ewald summation method.

           scalings
                A ``Scalings`` object. This object contains all the information
                about the energy scaling of pairwise contributions that are
                involved in covalent interactions. See
                :class:`yaff.pes.scalings.Scalings` for more details.
        '''
        ForcePart.__init__(self, 'ewald_cor', system)
        if not system.cell.nvec == 3:
            raise TypeError('The system must have a 3D periodic cell')
        if system.charges is None:
            raise ValueError('The system does not have charges.')
        self.system = system
        self.alpha = alpha
        self.scalings = scalings
        if log.do_medium:
            with log.section('FPINIT'):
                log('Force part: %s' % self.name)
                log.hline()
                log('  alpha:             %s' % log.invlength(self.alpha))
                log('  scalings:          %5.3f %5.3f %5.3f' % (scalings.scale1, scalings.scale2, scalings.scale3))
                log.hline()
Exemple #2
0
    def __init__(self, system, alpha, dielectric=1.0):
        '''
           **Arguments:**

           system
                The system to which this interaction applies.

           alpha
                The alpha parameter in the Ewald summation method.

           **Optional arguments:**

           dielectric
                The scalar relative permittivity of the system.
        '''
        ForcePart.__init__(self, 'ewald_neut', system)
        if not system.cell.nvec == 3:
            raise TypeError('The system must have a 3D periodic cell')
        if system.charges is None:
            raise ValueError('The system does not have charges.')
        self.system = system
        self.alpha = alpha
        self.dielectric = dielectric
        if log.do_medium:
            with log.section('FPINIT'):
                log('Force part: %s' % self.name)
                log.hline()
                log('  alpha:                   %s' % log.invlength(self.alpha))
                log('  relative permittivity:   %5.3f' % self.dielectric)
                log.hline()
Exemple #3
0
    def __init__(self, system, alpha, gcut=0.35):
        '''
           **Arguments:**

           system
                The system to which this interaction applies.

           alpha
                The alpha parameter in the Ewald summation method.

           gcut
                The cutoff in reciprocal space.
        '''
        ForcePart.__init__(self, 'ewald_reci', system)
        if not system.cell.nvec == 3:
            raise TypeError('The system must have a 3D periodic cell.')
        if system.charges is None:
            raise ValueError('The system does not have charges.')
        if system.dipoles is None:
            raise ValueError('The system does not have dipoles.')
        self.system = system
        self.alpha = alpha
        self.gcut = gcut
        self.update_gmax()
        self.work = np.empty(system.natom*2)
        if log.do_medium:
            with log.section('FPINIT'):
                log('Force part: %s' % self.name)
                log.hline()
                log('  alpha:             %s' % log.invlength(self.alpha))
                log('  gcut:              %s' % log.invlength(self.gcut))
                log.hline()
Exemple #4
0
    def __init__(self, system, grids):
        '''
           **Arguments:**

           system
                An instance of the ``System`` class.

           grids
                A dictionary with (ffatype, grid) items. Each grid must be a
                three-dimensional array with energies.

           This force part is only applicable to systems that are 3D periodic.
        '''
        if system.cell.nvec != 3:
            raise ValueError('The system must be 3d periodic for the grid term.')
        for grid in grids.itervalues():
            if grid.ndim != 3:
                raise ValueError('The energy grids must be 3D numpy arrays.')
        ForcePart.__init__(self, 'grid', system)
        self.system = system
        self.grids = grids
        if log.do_medium:
            with log.section('FPINIT'):
                log('Force part: %s' % self.name)
                log.hline()
Exemple #5
0
    def __init__(self, system, alpha, dielectric=1.0):
        '''
           **Arguments:**

           system
                The system to which this interaction applies.

           alpha
                The alpha parameter in the Ewald summation method.

           **Optional arguments:**

           dielectric
                The scalar relative permittivity of the system.
        '''
        ForcePart.__init__(self, 'ewald_neut', system)
        if not system.cell.nvec == 3:
            raise TypeError('The system must have a 3D periodic cell')
        if system.charges is None:
            raise ValueError('The system does not have charges.')
        self.system = system
        self.alpha = alpha
        self.dielectric = dielectric
        if log.do_medium:
            with log.section('FPINIT'):
                log('Force part: %s' % self.name)
                log.hline()
                log('  alpha:                   %s' %
                    log.invlength(self.alpha))
                log('  relative permittivity:   %5.3f' % self.dielectric)
                log.hline()
Exemple #6
0
    def __call__(self, iterative):
        r'''When this point is reached, a complete time integration step was
           finished and PLUMED should be notified about this.
        '''
        if not self.hooked:
            if log.do_high:
                log.hline()
                log("Reinitializing PLUMED")
                log.hline()
            if log.do_warning:
                log.warn("You are using PLUMED as a hook for your integrator. "
                         "If PLUMED adds time-dependent forces (for instance "
                         "when performing metadynamics) there is no energy "
                         "conservation. The conserved quantity reported by "
                         "YAFF is irrelevant in this case.")
            self.setup_plumed(timestep=iterative.timestep,
                              restart=iterative.counter > 0)
            self.hooked = True
        # PLUMED provides a setEnergy command, which should pass the
        # current potential energy. It seems that this is never used, so we
        # don't pass anything for the moment.
#        current_energy = sum([part.energy for part in iterative.ff.parts[:-1] if not isinstance(part, ForcePartPlumed)])
#        self.plumed.cmd("setEnergy", current_energy)
        self.plumedstep = iterative.counter
        self._internal_compute(None, None)
        self.plumed.cmd("update")
Exemple #7
0
    def make_step(self):
        # get relevant hessian information
        evals, evecs = self.hessian.get_spectrum()
        if log.do_high:
            log(" lowest eigen value: %7.1e" % evals.min())
            log("highest eigen value: %7.1e" % evals.max())
        # convert gradient to eigen basis
        grad_eigen = np.dot(evecs.T, self.g_old)

        while True:
            # Find the step with the given radius. If the hessian is positive
            # definite and the unconstrained step is smaller than the trust
            # radius, this step is returned
            delta_eigen = solve_trust_radius(grad_eigen, evals, self.trust_radius)
            radius = np.linalg.norm(delta_eigen)

            # convert the step to user basis
            delta_x = np.dot(evecs, delta_eigen)

            # compute the function and gradient at the new position
            x = self.x_old + delta_x
            f, g = self.fun(x, True)

            # compute the change in function value
            delta_f = f - self.f_old
            # compute the change in norm of the gradient
            delta_norm_g = np.linalg.norm(g) - np.linalg.norm(self.g_old)
            # must_shrink is a parameter to control the trust radius
            must_shrink = False

            if delta_f > 0:
                # The function must decrease, if not the trust radius is too big.
                if log.do_high:
                    log("Function increases.")
                must_shrink = True

            if self.trust_radius < self.small_radius and delta_norm_g > 0:
                # When the trust radius becomes small, the numerical noise on
                # the energy may be too large to detect an increase energy.
                # In that case the norm of the gradient is used instead.
                if log.do_high:
                    log("Gradient norm increases.")
                must_shrink = True

            if must_shrink:
                self.trust_radius *= 0.5
                while self.trust_radius >= radius:
                    self.trust_radius *= 0.5
                if self.trust_radius < self.too_small_radius:
                    raise RuntimeError("The trust radius becomes too small. Is the potential energy surface smooth?")
            else:
                # If we get here, we are done with the trust radius loop.
                if log.do_high:
                    log.hline()
                # It is fine to increase the trust radius a little after a
                # successful step.
                if self.trust_radius < self.initial_trust_radius:
                    self.trust_radius *= 2.0
                # Return the results of the successful step
                return x, f, g
Exemple #8
0
    def __init__(self, system, part_pair):
        '''
           **Arguments:**

           system
                An instance of the ``System`` class.

           part_pair
                An instance of the ``PairPot`` class.

           This force part is only applicable to systems that are 3D periodic.
        '''
        if system.cell.nvec != 3:
            raise ValueError(
                'Tail corrections can only be applied to 3D periodic systems')
        if part_pair.name in ['pair_ei', 'pair_eidip']:
            raise ValueError('Tail corrections are divergent for %s' %
                             part_pair.name)
        super(ForcePartTailCorrection,
              self).__init__('tailcorr_%s' % (part_pair.name), system)
        self.ecorr, self.wcorr = part_pair.pair_pot.prepare_tailcorrections(
            system.natom)
        self.system = system
        if log.do_medium:
            with log.section('FPINIT'):
                log('Force part: %s' % self.name)
                log.hline()
Exemple #9
0
    def __init__(self, system, alpha, gcut=0.35):
        '''
           **Arguments:**

           system
                The system to which this interaction applies.

           alpha
                The alpha parameter in the Ewald summation method.

           gcut
                The cutoff in reciprocal space.
        '''
        ForcePart.__init__(self, 'ewald_reci', system)
        if not system.cell.nvec == 3:
            raise TypeError('The system must have a 3D periodic cell.')
        if system.charges is None:
            raise ValueError('The system does not have charges.')
        if system.dipoles is None:
            raise ValueError('The system does not have dipoles.')
        self.system = system
        self.alpha = alpha
        self.gcut = gcut
        self.update_gmax()
        self.work = np.empty(system.natom * 2)
        if log.do_medium:
            with log.section('FPINIT'):
                log('Force part: %s' % self.name)
                log.hline()
                log('  alpha:             %s' % log.invlength(self.alpha))
                log('  gcut:              %s' % log.invlength(self.gcut))
                log.hline()
Exemple #10
0
    def __init__(self, system, grids):
        '''
           **Arguments:**

           system
                An instance of the ``System`` class.

           grids
                A dictionary with (ffatype, grid) items. Each grid must be a
                three-dimensional array with energies.

           This force part is only applicable to systems that are 3D periodic.
        '''
        if system.cell.nvec != 3:
            raise ValueError(
                'The system must be 3d periodic for the grid term.')
        for grid in grids.values():
            if grid.ndim != 3:
                raise ValueError('The energy grids must be 3D numpy arrays.')
        ForcePart.__init__(self, 'grid', system)
        self.system = system
        self.grids = grids
        if log.do_medium:
            with log.section('FPINIT'):
                log('Force part: %s' % self.name)
                log.hline()
Exemple #11
0
    def __init__(self, system, alpha, scalings):
        '''
           **Arguments:**

           system
                The system to which this interaction applies.

           alpha
                The alpha parameter in the Ewald summation method.

           scalings
                A ``Scalings`` object. This object contains all the information
                about the energy scaling of pairwise contributions that are
                involved in covalent interactions. See
                :class:`yaff.pes.scalings.Scalings` for more details.
        '''
        ForcePart.__init__(self, 'ewald_cor', system)
        if not system.cell.nvec == 3:
            raise TypeError('The system must have a 3D periodic cell')
        if system.charges is None:
            raise ValueError('The system does not have charges.')
        self.system = system
        self.alpha = alpha
        self.scalings = scalings
        if log.do_medium:
            with log.section('FPINIT'):
                log('Force part: %s' % self.name)
                log.hline()
                log('  alpha:             %s' % log.invlength(self.alpha))
                log('  scalings:          %5.3f %5.3f %5.3f' %
                    (scalings.scale1, scalings.scale2, scalings.scale3))
                log.hline()
Exemple #12
0
    def make_step(self):
        # get relevant hessian information
        evals, evecs = self.hessian.get_spectrum()
        if log.do_high:
            log(' lowest eigen value: %7.1e' % evals.min())
            log('highest eigen value: %7.1e' % evals.max())
        # convert gradient to eigen basis
        grad_eigen = np.dot(evecs.T, self.g_old)

        while True:
            # Find the step with the given radius. If the hessian is positive
            # definite and the unconstrained step is smaller than the trust
            # radius, this step is returned
            delta_eigen = solve_trust_radius(grad_eigen, evals, self.trust_radius)
            radius = np.linalg.norm(delta_eigen)

            # convert the step to user basis
            delta_x = np.dot(evecs, delta_eigen)

            # compute the function and gradient at the new position
            x = self.x_old + delta_x
            f, g = self.fun(x, True)

            # compute the change in function value
            delta_f = f - self.f_old
            # compute the change in norm of the gradient
            delta_norm_g = np.linalg.norm(g) - np.linalg.norm(self.g_old)
            # must_shrink is a parameter to control the trust radius
            must_shrink = False

            if delta_f > 0:
                # The function must decrease, if not the trust radius is too big.
                if log.do_high:
                    log('Function increases.')
                must_shrink = True

            if (self.trust_radius < self.small_radius and delta_norm_g > 0):
                # When the trust radius becomes small, the numerical noise on
                # the energy may be too large to detect an increase energy.
                # In that case the norm of the gradient is used instead.
                if log.do_high:
                    log('Gradient norm increases.')
                must_shrink = True

            if must_shrink:
                self.trust_radius *= 0.5
                while self.trust_radius >= radius:
                    self.trust_radius *= 0.5
                if self.trust_radius < self.too_small_radius:
                    raise RuntimeError('The trust radius becomes too small. Is the potential energy surface smooth?')
            else:
                # If we get here, we are done with the trust radius loop.
                if log.do_high:
                    log.hline()
                # It is fine to increase the trust radius a little after a
                # successful step.
                if self.trust_radius < self.initial_trust_radius:
                    self.trust_radius *= 2.0
                # Return the results of the successful step
                return x, f, g
Exemple #13
0
    def _init_derived_bonds(self):
        # 1-bond neighbors
        self.neighs1 = dict((i,set([])) for i in xrange(self.natom))
        for i0, i1 in self.bonds:
            self.neighs1[i0].add(i1)
            self.neighs1[i1].add(i0)
        # 2-bond neighbors
        self.neighs2 = dict((i,set([])) for i in xrange(self.natom))
        for i0, n0 in self.neighs1.iteritems():
            for i1 in n0:
                for i2 in self.neighs1[i1]:
                    # Require that there are no shorter paths than two bonds between
                    # i0 and i2. Also avoid duplicates.
                    if i2 > i0 and i2 not in self.neighs1[i0]:
                        self.neighs2[i0].add(i2)
                        self.neighs2[i2].add(i0)
        # 3-bond neighbors
        self.neighs3 = dict((i,set([])) for i in xrange(self.natom))
        for i0, n0 in self.neighs1.iteritems():
            for i1 in n0:
                for i3 in self.neighs2[i1]:
                    # Require that there are no shorter paths than three bonds
                    # between i0 and i3. Also avoid duplicates.
                    if i3 != i0 and i3 not in self.neighs1[i0] and i3 not in self.neighs2[i0]:
                        self.neighs3[i0].add(i3)
                        self.neighs3[i3].add(i0)
        # report some basic stuff on screen
        if log.do_medium:
            log('Analysis of the bonds:')
            bond_types = {}
            for i0, i1 in self.bonds:
                key = tuple(sorted([self.numbers[i0], self.numbers[i1]]))
                bond_types[key] = bond_types.get(key, 0) + 1
            log.hline()
            log(' First   Second   Count')
            for (num0, num1), count in sorted(bond_types.iteritems()):
                log('%6i   %6i   %5i' % (num0, num1, count))
            log.hline()
            log.blank()

            log('Analysis of the neighbors:')
            log.hline()
            log('Number of first neighbors:  %6i' % (sum(len(n) for n in self.neighs1.itervalues())/2))
            log('Number of second neighbors: %6i' % (sum(len(n) for n in self.neighs2.itervalues())/2))
            log('Number of third neighbors:  %6i' % (sum(len(n) for n in self.neighs3.itervalues())/2))
            # Collect all types of 'environments' for each element. This is
            # useful to double check the bonds
            envs = {}
            for i0 in xrange(self.natom):
                num0 = self.numbers[i0]
                nnums = tuple(sorted(self.numbers[i1] for i1 in self.neighs1[i0]))
                key = (num0, nnums)
                envs[key] = envs.get(key, 0)+1
            # Print the environments on screen
            log.hline()
            log('Element   Neighboring elements   Count')
            for (num0, nnums), count in sorted(envs.iteritems()):
                log('%7i   %20s   %5i' % (num0, ','.join(str(num1) for num1 in nnums), count))
            log.hline()
            log.blank()
Exemple #14
0
    def __init__(self,
                 system,
                 alpha,
                 gcut=0.35,
                 dielectric=1.0,
                 exclude_frame=False,
                 n_frame=0):
        '''
           **Arguments:**

           system
                The system to which this interaction applies.

           alpha
                The alpha parameter in the Ewald summation method.

           **Optional arguments:**

           gcut
                The cutoff in reciprocal space.

           dielectric
                The scalar relative permittivity of the system.

           exclude_frame
                A boolean to exclude framework-framework interactions
                (exclude_frame=True) for efficiency sake in MC simulations.

           n_frame
                Number of framework atoms. This parameter is used to exclude
                framework-framework neighbors when exclude_frame=True.
        '''
        ForcePart.__init__(self, 'ewald_reci', system)
        if not system.cell.nvec == 3:
            raise TypeError('The system must have a 3D periodic cell.')
        if system.charges is None:
            raise ValueError('The system does not have charges.')
        self.system = system
        self.alpha = alpha
        self.gcut = gcut
        self.dielectric = dielectric
        self.update_gmax()
        self.work = np.empty(system.natom * 2)
        if exclude_frame == True and n_frame < 0:
            raise ValueError(
                'The number of framework atoms to exclude must be positive.')
        elif exclude_frame == False:
            n_frame = 0
        self.n_frame = n_frame
        if log.do_medium:
            with log.section('FPINIT'):
                log('Force part: %s' % self.name)
                log.hline()
                log('  alpha:                 %s' % log.invlength(self.alpha))
                log('  gcut:                  %s' % log.invlength(self.gcut))
                log('  relative permittivity: %5.3f' % self.dielectric)
                log.hline()
Exemple #15
0
 def __call__(self, iterative):
     if log.do_medium:
         if self.time0 is None:
             self.time0 = time.time()
             if log.do_medium:
                 log.hline()
                 log('counter  Walltime')
                 log.hline()
         log('%7i %10.1f' % (
             iterative.counter,
             time.time() - self.time0,
         ))
Exemple #16
0
 def __call__(self, iterative):
     if log.do_medium:
         if self.time0 is None:
             self.time0 = time.time()
             if log.do_medium:
                 log.hline()
                 log('counter  Walltime')
                 log.hline()
         log('%7i %10.1f' % (
             iterative.counter,
             time.time() - self.time0,
         ))
Exemple #17
0
 def __call__(self, mc):
     if log.do_medium:
         if self.time0 is None:
             self.time0 = time.time()
             if log.do_medium:
                 log.hline()
                 log('     counter %s   Walltime' % (mc.log_header()))
                 log.hline()
         log('%12i %s %10.1f' % (
             mc.counter,
             mc.log(),
             time.time() - self.time0,
         ))
Exemple #18
0
    def __init__(self, system, alpha, gcut=0.35, dielectric=1.0, exclude_frame=False, n_frame=0):
        '''
           **Arguments:**

           system
                The system to which this interaction applies.

           alpha
                The alpha parameter in the Ewald summation method.

           **Optional arguments:**

           gcut
                The cutoff in reciprocal space.

           dielectric
                The scalar relative permittivity of the system.

           exclude_frame
                A boolean to exclude framework-framework interactions
                (exclude_frame=True) for efficiency sake in MC simulations.

           n_frame
                Number of framework atoms. This parameter is used to exclude
                framework-framework neighbors when exclude_frame=True.
        '''
        ForcePart.__init__(self, 'ewald_reci', system)
        if not system.cell.nvec == 3:
            raise TypeError('The system must have a 3D periodic cell.')
        if system.charges is None:
            raise ValueError('The system does not have charges.')
        self.system = system
        self.alpha = alpha
        self.gcut = gcut
        self.dielectric = dielectric
        self.update_gmax()
        self.work = np.empty(system.natom*2)
        if exclude_frame == True and n_frame < 0:
            raise ValueError('The number of framework atoms to exclude must be positive.')
        elif exclude_frame == False:
            n_frame = 0
        self.n_frame = n_frame
        if log.do_medium:
            with log.section('FPINIT'):
                log('Force part: %s' % self.name)
                log.hline()
                log('  alpha:                 %s' % log.invlength(self.alpha))
                log('  gcut:                  %s' % log.invlength(self.gcut))
                log('  relative permittivity: %5.3f' % self.dielectric)
                log.hline()
Exemple #19
0
 def _init_log(self):
     if log.do_medium:
         log('Unit cell')
         log.hline()
         log('Number of periodic dimensions: %i' % self.cell.nvec)
         lengths, angles = self.cell.parameters
         names = 'abc'
         for i in range(len(lengths)):
             log('Cell parameter %5s: %10s' % (names[i], log.length(lengths[i])))
         names = 'alpha', 'beta', 'gamma'
         for i in range(len(angles)):
             log('Cell parameter %5s: %10s' % (names[i], log.angle(angles[i])))
         log.hline()
         log.blank()
Exemple #20
0
 def __init__(self, comsystem, scaling=None):
     ForcePart.__init__(self, 'valence_com', comsystem)
     #ForcePartValence.__init__(self, system)
     self.comlist = comsystem.comlist
     self.gpos = np.zeros((comsystem.gpos_dim, 3), float)
     self.dlist = DeltaList(self.comlist)
     self.iclist = InternalCoordinateList(self.dlist)
     self.vlist = ValenceList(self.iclist)
     self.scaling = scaling
     if log.do_medium:
         with log.section('FPINIT'):
             log('Force part: %s' % self.name)
             log.hline()
     self.term = None  # volume term
Exemple #21
0
 def _init_log(self):
     if log.do_medium:
         log('Unit cell')
         log.hline()
         log('Number of periodic dimensions: %i' % self.cell.nvec)
         lengths, angles = self.cell.parameters
         names = 'abc'
         for i in xrange(len(lengths)):
             log('Cell parameter %5s: %10s' % (names[i], log.length(lengths[i])))
         names = 'alpha', 'beta', 'gamma'
         for i in xrange(len(angles)):
             log('Cell parameter %5s: %10s' % (names[i], log.angle(angles[i])))
         log.hline()
         log.blank()
Exemple #22
0
    def __init__(self, system):
        '''
           **Arguments:**

           system
                An instance of the ``System`` class.
        '''
        ForcePart.__init__(self, 'valence', system)
        self.dlist = DeltaList(system)
        self.iclist = InternalCoordinateList(self.dlist)
        self.vlist = ValenceList(self.iclist)
        if log.do_medium:
            with log.section('FPINIT'):
                log('Force part: %s' % self.name)
                log.hline()
Exemple #23
0
    def __init__(self, system):
        '''
           **Arguments:**

           system
                An instance of the ``System`` class.
        '''
        ForcePart.__init__(self, 'valence', system)
        self.dlist = DeltaList(system)
        self.iclist = InternalCoordinateList(self.dlist)
        self.vlist = ValenceList(self.iclist)
        if log.do_medium:
            with log.section('FPINIT'):
                log('Force part: %s' % self.name)
                log.hline()
Exemple #24
0
 def __call__(self, iterative):
     if log.do_medium:
         if self.time0 is None:
             self.time0 = time.time()
             if log.do_medium:
                 log.hline()
                 log('Conv.val. =&the highest ratio of a convergence criterion over its threshold.')
                 log('N         =&the number of convergence criteria that is not met.')
                 log('Worst     =&the name of the convergence criterion that is worst.')
                 log('counter  Conv.val.  N           Worst     Energy   Walltime')
                 log.hline()
         log('%7i % 10.3e %2i %15s %s %10.1f' % (
             iterative.counter,
             iterative.dof.conv_val,
             iterative.dof.conv_count,
             iterative.dof.conv_worst,
             log.energy(iterative.epot),
             time.time() - self.time0,
         ))
Exemple #25
0
 def __call__(self, iterative):
     if log.do_medium:
         if self.time0 is None:
             self.time0 = time.time()
             if log.do_medium:
                 log.hline()
                 log('Conv.val. =&the highest ratio of a convergence criterion over its threshold.')
                 log('N         =&the number of convergence criteria that is not met.')
                 log('Worst     =&the name of the convergence criterion that is worst.')
                 log('counter  Conv.val.  N           Worst     Energy   Walltime')
                 log.hline()
         log('%7i % 10.3e %2i %15s %s %10.1f' % (
             iterative.counter,
             iterative.dof.conv_val,
             iterative.dof.conv_count,
             iterative.dof.conv_worst,
             log.energy(iterative.epot),
             time.time() - self.time0,
         ))
Exemple #26
0
 def __call__(self, iterative):
     if log.do_medium:
         if self.time0 is None:
             self.time0 = time.time()
             if log.do_medium:
                 log.hline()
                 log('Cons.Err. =&the root of the ratio of the variance on the conserved quantity and the variance on the kinetic energy.')
                 log('d-rmsd    =&the root-mean-square displacement of the atoms.')
                 log('g-rmsd    =&the root-mean-square gradient of the energy.')
                 log('counter  Cons.Err.       Temp     d-RMSD     g-RMSD   Walltime')
                 log.hline()
         log('%7i %10.5f %s %s %s %10.1f' % (
             iterative.counter,
             iterative.cons_err,
             log.temperature(iterative.temp),
             log.length(iterative.rmsd_delta),
             log.force(iterative.rmsd_gpos),
             time.time() - self.time0,
         ))
Exemple #27
0
    def __init__(self, system, comlist=None):
        '''
           Parameters
           ----------

           system
                An instance of the ``System`` class.
           comlist
                An optional layer to derive centers of mass from the atomic positions.
                These centers of mass are used as input for the first layer, the relative
                vectors.
        '''
        ForcePart.__init__(self, 'valence', system)
        self.comlist = comlist
        self.dlist = DeltaList(system if comlist is None else comlist)
        self.iclist = InternalCoordinateList(self.dlist)
        self.vlist = ValenceList(self.iclist)
        if log.do_medium:
            with log.section('FPINIT'):
                log('Force part: %s' % self.name)
                log.hline()
Exemple #28
0
    def __init__(self, system, comlist=None):
        '''
           Parameters
           ----------

           system
                An instance of the ``System`` class.
           comlist
                An optional layer to derive centers of mass from the atomic positions.
                These centers of mass are used as input for the first layer, the relative
                vectors.
        '''
        ForcePart.__init__(self, 'valence', system)
        self.comlist = comlist
        self.dlist = DeltaList(system if comlist is None else comlist)
        self.iclist = InternalCoordinateList(self.dlist)
        self.vlist = ValenceList(self.iclist)
        if log.do_medium:
            with log.section('FPINIT'):
                log('Force part: %s' % self.name)
                log.hline()
Exemple #29
0
    def __init__(self, system):
        '''
           Parameters
           ----------

           system
                An instance of the ``System`` class.
        '''
        ForcePart.__init__(self, 'valence', system)

        # override self.gpos to the correct size!
        # natom of COMSystem object will return number of beads
        # but gpos has to have the size (n_atoms, 3), to be consisten
        # with the other parts of the force field
        self.dlist = DeltaList(system)
        self.iclist = InternalCoordinateList(self.dlist)
        self.vlist = ValenceList(self.iclist)
        if log.do_medium:
            with log.section('FPINIT'):
                log('Force part: %s' % self.name)
                log.hline()
Exemple #30
0
 def _init_derived_scopes(self):
     if self.scope_ids is None:
         if len(self.scopes) != self.natom:
             raise TypeError('When the scope_ids are derived automatically, the length of the scopes list must match the number of atoms.')
         lookup = {}
         scopes = []
         self.scope_ids = np.zeros(self.natom, int)
         for i in xrange(self.natom):
             scope = self.scopes[i]
             scope_id = lookup.get(scope)
             if scope_id is None:
                 scope_id = len(scopes)
                 scopes.append(scope)
                 lookup[scope] = scope_id
             self.scope_ids[i] = scope_id
         self.scopes = scopes
     for scope in self.scopes:
         check_name(scope)
     # check the range of the ids
     if self.scope_ids.min() != 0 or self.scope_ids.max() != len(self.scopes)-1:
         raise ValueError('The ffatype_ids have incorrect bounds.')
     if log.do_medium:
         log('The following scopes are present in the system:')
         log.hline()
         log('                 Scope   ID   Number of atoms')
         log.hline()
         for scope_id, scope in enumerate(self.scopes):
             log('%22s  %3i       %3i' % (scope, scope_id, (self.scope_ids==scope_id).sum()))
         log.hline()
         log.blank()
Exemple #31
0
    def __init__(self, system, nlist, scalings, pair_pot):
        '''
           **Arguments:**

           system
                The system to which this pairwise interaction applies.

           nlist
                A ``NeighborList`` object. This has to be the same as the one
                passed to the ForceField object that contains this part.

           scalings
                A ``Scalings`` object. This object contains all the information
                about the energy scaling of pairwise contributions that are
                involved in covalent interactions. See
                :class:`yaff.pes.scalings.Scalings` for more details.

           pair_pot
                An instance of the ``PairPot`` built-in class from
                :mod:`yaff.pes.ext`.
        '''
        ForcePart.__init__(self, 'pair_%s' % pair_pot.name, system)
        self.nlist = nlist
        self.scalings = scalings
        self.pair_pot = pair_pot
        self.nlist.request_rcut(pair_pot.rcut)
        if log.do_medium:
            with log.section('FPINIT'):
                log('Force part: %s' % self.name)
                log.hline()
                log('  scalings:          %5.3f %5.3f %5.3f' %
                    (scalings.scale1, scalings.scale2, scalings.scale3))
                log('  real space cutoff: %s' % log.length(pair_pot.rcut))
                tr = pair_pot.get_truncation()
                if tr is None:
                    log('  truncation:     none')
                else:
                    log('  truncation:     %s' % tr.get_log())
                self.pair_pot.log()
                log.hline()
Exemple #32
0
 def _init_derived_scopes(self):
     if self.scope_ids is None:
         if len(self.scopes) != self.natom:
             raise TypeError(
                 'When the scope_ids are derived automatically, the length of the scopes list must match the number of atoms.'
             )
         lookup = {}
         scopes = []
         self.scope_ids = np.zeros(self.natom, int)
         for i in range(self.natom):
             scope = self.scopes[i]
             scope_id = lookup.get(scope)
             if scope_id is None:
                 scope_id = len(scopes)
                 scopes.append(scope)
                 lookup[scope] = scope_id
             self.scope_ids[i] = scope_id
         self.scopes = scopes
     for scope in self.scopes:
         check_name(scope)
     # check the range of the ids
     if self.scope_ids.min() != 0 or self.scope_ids.max() != len(
             self.scopes) - 1:
         raise ValueError('The ffatype_ids have incorrect bounds.')
     if log.do_medium:
         log('The following scopes are present in the system:')
         log.hline()
         log('                 Scope   ID   Number of atoms')
         log.hline()
         for scope_id, scope in enumerate(self.scopes):
             log('%22s  %3i       %3i' %
                 (scope, scope_id, (self.scope_ids == scope_id).sum()))
         log.hline()
         log.blank()
Exemple #33
0
    def __init__(self, system, nlist, scalings, pair_pot):
        '''
           **Arguments:**

           system
                The system to which this pairwise interaction applies.

           nlist
                A ``NeighborList`` object. This has to be the same as the one
                passed to the ForceField object that contains this part.

           scalings
                A ``Scalings`` object. This object contains all the information
                about the energy scaling of pairwise contributions that are
                involved in covalent interactions. See
                :class:`yaff.pes.scalings.Scalings` for more details.

           pair_pot
                An instance of the ``PairPot`` built-in class from
                :mod:`yaff.pes.ext`.
        '''
        ForcePart.__init__(self, 'pair_%s' % pair_pot.name, system)
        self.nlist = nlist
        self.scalings = scalings
        self.pair_pot = pair_pot
        self.nlist.request_rcut(pair_pot.rcut)
        if log.do_medium:
            with log.section('FPINIT'):
                log('Force part: %s' % self.name)
                log.hline()
                log('  scalings:          %5.3f %5.3f %5.3f' % (scalings.scale1, scalings.scale2, scalings.scale3))
                log('  real space cutoff: %s' % log.length(pair_pot.rcut))
                tr = pair_pot.get_truncation()
                if tr is None:
                    log('  truncation:     none')
                else:
                    log('  truncation:     %s' % tr.get_log())
                self.pair_pot.log()
                log.hline()
Exemple #34
0
def estimate_hessian(dof, eps=1e-4):
    """Estimate the Hessian using the symmetric finite difference approximation.

       **Arguments:**

       dof
            A DOF object

       **Optional arguments:**

       eps
            The magnitude of the displacements
    """
    with log.section('HESS'), timer.section('Hessian'):
        # Loop over all displacements
        if log.do_medium:
            log('The following displacements are computed:')
            log('DOF     Dir Energy')
            log.hline()
        x1 = dof.x0.copy()
        rows = np.zeros((len(x1), len(x1)), float)
        for i in xrange(len(x1)):
            x1[i] = dof.x0[i] + eps
            epot, gradient_p = dof.fun(x1, do_gradient=True)
            if log.do_medium:
                log('% 7i pos %s' % (i, log.energy(epot)))
            x1[i] = dof.x0[i] - eps
            epot, gradient_m = dof.fun(x1, do_gradient=True)
            if log.do_medium:
                log('% 7i neg %s' % (i, log.energy(epot)))
            rows[i] = (gradient_p-gradient_m)/(2*eps)
            x1[i] = dof.x0[i]
        dof.reset()
        if log.do_medium:
            log.hline()

        # Enforce symmetry and return
        return 0.5*(rows + rows.T)
Exemple #35
0
def estimate_hessian(dof, eps=1e-4):
    """Estimate the Hessian using the symmetric finite difference approximation.

       **Arguments:**

       dof
            A DOF object

       **Optional arguments:**

       eps
            The magnitude of the displacements
    """
    with log.section('HESS'), timer.section('Hessian'):
        # Loop over all displacements
        if log.do_medium:
            log('The following displacements are computed:')
            log('DOF     Dir Energy')
            log.hline()
        x1 = dof.x0.copy()
        rows = np.zeros((len(x1), len(x1)), float)
        for i in xrange(len(x1)):
            x1[i] = dof.x0[i] + eps
            epot, gradient_p = dof.fun(x1, do_gradient=True)
            if log.do_medium:
                log('% 7i pos %s' % (i, log.energy(epot)))
            x1[i] = dof.x0[i] - eps
            epot, gradient_m = dof.fun(x1, do_gradient=True)
            if log.do_medium:
                log('% 7i neg %s' % (i, log.energy(epot)))
            rows[i] = (gradient_p - gradient_m) / (2 * eps)
            x1[i] = dof.x0[i]
        dof.reset()
        if log.do_medium:
            log.hline()

        # Enforce symmetry and return
        return 0.5 * (rows + rows.T)
Exemple #36
0
    def __init__(self, system, pext):
        '''
           **Arguments:**

           system
                An instance of the ``System`` class.

           pext
                The external pressure. (Positive will shrink the system.) In
                case of 2D-PBC, this is the surface tension. In case of 1D, this
                is the linear strain.

           This force part is only applicable to systems that are periodic.
        '''
        if system.cell.nvec == 0:
            raise ValueError('The system must be periodic in order to apply a pressure')
        ForcePart.__init__(self, 'press', system)
        self.system = system
        self.pext = pext
        if log.do_medium:
            with log.section('FPINIT'):
                log('Force part: %s' % self.name)
                log.hline()
Exemple #37
0
 def __call__(self, iterative):
     if log.do_medium:
         if self.time0 is None:
             self.time0 = time.time()
             if log.do_medium:
                 log.hline()
                 log('Cons.Err. =&the root of the ratio of the variance on the conserved quantity and the variance on the kinetic energy.'
                     )
                 log('d-rmsd    =&the root-mean-square displacement of the atoms.'
                     )
                 log('g-rmsd    =&the root-mean-square gradient of the energy.'
                     )
                 log('counter  Cons.Err.       Temp     d-RMSD     g-RMSD   Walltime'
                     )
                 log.hline()
         log('%7i %10.5f %s %s %s %10.1f' % (
             iterative.counter,
             iterative.cons_err,
             log.temperature(iterative.temp),
             log.length(iterative.rmsd_delta),
             log.force(iterative.rmsd_gpos),
             time.time() - self.time0,
         ))
Exemple #38
0
    def __init__(self, system, part_pair):
        '''
           **Arguments:**

           system
                An instance of the ``System`` class.

           part_pair
                An instance of the ``PairPot`` class.

           This force part is only applicable to systems that are 3D periodic.
        '''
        if system.cell.nvec != 3:
            raise ValueError('Tail corrections can only be applied to 3D periodic systems')
        if part_pair.name in ['pair_ei','pair_eidip']:
            raise ValueError('Tail corrections are divergent for %s'%part_pair.name)
        super(ForcePartTailCorrection, self).__init__('tailcorr_%s'%(part_pair.name), system)
        self.ecorr, self.wcorr = part_pair.pair_pot.prepare_tailcorrections(system.natom)
        self.system = system
        if log.do_medium:
            with log.section('FPINIT'):
                log('Force part: %s' % self.name)
                log.hline()
Exemple #39
0
    def __init__(self, system, comlist=None):
        '''
           **Arguments:**

           system
                An instance of the ``System`` class.

           **Optional arguments:**

           comlist
                An optional layer to derive centers of mass from the atomic positions.
                These centers of mass are used as input for the first layer, the relative
                vectors.
        '''
        ForcePart.__init__(self, 'bias', system)
        self.system = system
        self.valence = ForcePartValence(system)
        if comlist is not None:
            raise NotImplementedError
        if comlist is not None:
            self.valence_com = ForcePartValence(system, comlist=comlist)
        else:
            self.valence_com = None
        self.terms = []
        # The terms contributing to the bias potential are divided into three
        # categories:
        #   0) instances of BiasPotential
        #   1) instances of ValenceTerm with a regular DeltaList
        #   2) instances of ValenceTerm with a COMList
        # The following list facilitates looking up the terms after they have
        # been added
        self.term_lookup = []
        if log.do_medium:
            with log.section('FPINIT'):
                log('Force part: %s' % self.name)
                log.hline()
Exemple #40
0
    def __init__(self, system, pext):
        '''
           **Arguments:**

           system
                An instance of the ``System`` class.

           pext
                The external pressure. (Positive will shrink the system.) In
                case of 2D-PBC, this is the surface tension. In case of 1D, this
                is the linear strain.

           This force part is only applicable to systems that are periodic.
        '''
        if system.cell.nvec == 0:
            raise ValueError(
                'The system must be periodic in order to apply a pressure')
        ForcePart.__init__(self, 'press', system)
        self.system = system
        self.pext = pext
        if log.do_medium:
            with log.section('FPINIT'):
                log('Force part: %s' % self.name)
                log.hline()
Exemple #41
0
 def finalize(self):
     if log.do_medium:
         self.dof.log()
         log.hline()
Exemple #42
0
    def _init_derived_bonds(self):
        # 1-bond neighbors
        self.neighs1 = dict((i, set([])) for i in range(self.natom))
        for i0, i1 in self.bonds:
            self.neighs1[i0].add(i1)
            self.neighs1[i1].add(i0)
        # 2-bond neighbors
        self.neighs2 = dict((i, set([])) for i in range(self.natom))
        for i0, n0 in self.neighs1.items():
            for i1 in n0:
                for i2 in self.neighs1[i1]:
                    # Require that there are no shorter paths than two bonds between
                    # i0 and i2. Also avoid duplicates.
                    if i2 > i0 and i2 not in self.neighs1[i0]:
                        self.neighs2[i0].add(i2)
                        self.neighs2[i2].add(i0)
        # 3-bond neighbors
        self.neighs3 = dict((i, set([])) for i in range(self.natom))
        for i0, n0 in self.neighs1.items():
            for i1 in n0:
                for i3 in self.neighs2[i1]:
                    # Require that there are no shorter paths than three bonds
                    # between i0 and i3. Also avoid duplicates.
                    if i3 != i0 and i3 not in self.neighs1[
                            i0] and i3 not in self.neighs2[i0]:
                        self.neighs3[i0].add(i3)
                        self.neighs3[i3].add(i0)
        # 4-bond neighbors
        self.neighs4 = dict((i, set([])) for i in range(self.natom))
        for i0, n0 in self.neighs1.items():
            for i1 in n0:
                for i4 in self.neighs3[i1]:
                    # Require that there are no shorter paths than three bonds
                    # between i0 and i4. Also avoid duplicates.
                    if i4 != i0 and i4 not in self.neighs1[
                            i0] and i4 not in self.neighs2[
                                i0] and i4 not in self.neighs3[i0]:
                        self.neighs4[i0].add(i4)
                        self.neighs4[i4].add(i0)
        # report some basic stuff on screen
        if log.do_medium:
            log('Analysis of the bonds:')
            bond_types = {}
            for i0, i1 in self.bonds:
                key = tuple(sorted([self.numbers[i0], self.numbers[i1]]))
                bond_types[key] = bond_types.get(key, 0) + 1
            log.hline()
            log(' First   Second   Count')
            for (num0, num1), count in sorted(bond_types.items()):
                log('%6i   %6i   %5i' % (num0, num1, count))
            log.hline()
            log.blank()

            log('Analysis of the neighbors:')
            log.hline()
            log('Number of first neighbors:  %6i' %
                (sum(len(n) for n in self.neighs1.values()) // 2))
            log('Number of second neighbors: %6i' %
                (sum(len(n) for n in self.neighs2.values()) // 2))
            log('Number of third neighbors:  %6i' %
                (sum(len(n) for n in self.neighs3.values()) // 2))
            # Collect all types of 'environments' for each element. This is
            # useful to double check the bonds
            envs = {}
            for i0 in range(self.natom):
                num0 = self.numbers[i0]
                nnums = tuple(
                    sorted(self.numbers[i1] for i1 in self.neighs1[i0]))
                key = (num0, nnums)
                envs[key] = envs.get(key, 0) + 1
            # Print the environments on screen
            log.hline()
            log('Element   Neighboring elements   Count')
            for (num0, nnums), count in sorted(envs.items()):
                log('%7i   %20s   %5i' %
                    (num0, ','.join(str(num1) for num1 in nnums), count))
            log.hline()
            log.blank()
Exemple #43
0
 def finalize(self):
     if log.do_medium:
         self.dof.log()
         log.hline()
Exemple #44
0
 def finalize(self):
     if log.do_medium:
         log.hline()
Exemple #45
0
def write_lammps_table(ff,
                       fn='lammps.table',
                       rmin=0.50 * angstrom,
                       nrows=2500,
                       unit_style='electron'):
    '''
       Write tables containing noncovalent interactions for LAMMPS.
       For every pair of ffatypes, a separate table is generated.
       Because electrostatic interactions require a specific treatment, point-
       charge electrostatics are NOT included in the tables.

       When distributed charge distributions (e.g. Gaussian) are used, this
       complicates matters. LAMMPS will still only treat point-charge
       electrostatics using a dedicated method (e.g. Ewald or PPPM), so the
       table has to contain the difference between the distributed charges and
       the point charge electrostatic interactions. This also means that every
       ffatype need a unique charge distribution, i.e. all atoms of the same
       atom type need to have the same charge and Gaussian radius.

       All pair potentials contributing to the table need to have the same
       scalings for near-neighbor interactions; this is however independent
       of the generation of the table and is dealt with elsewhere

       **Arguments:**

       ff
            Yaff ForceField instance

       **Optional arguments:**

       fn
            Filename where tables will be stored

    '''
    # Find out if we are dealing with electrostatics from distributed charges
    corrections = []
    for part in ff.parts:
        if part.name == 'pair_ei':
            if np.any(part.pair_pot.radii != 0.0):
                # Create a ForcePart with electrostatics from distributed
                # charges, completely in real space.
                pair_pot_dist = PairPotEI(part.pair_pot.charges,
                                          0.0,
                                          part.pair_pot.rcut,
                                          tr=part.pair_pot.get_truncation(),
                                          dielectric=part.pair_pot.dielectric,
                                          radii=part.pair_pot.radii)
                fp_dist = ForcePartPair(ff.system, ff.nlist, part.scalings,
                                        pair_pot_dist)
                corrections.append((fp_dist, 1.0))
                # Create a ForcePart with electrostatics from point
                # charges, completely in real space.
                pair_pot_point = PairPotEI(part.pair_pot.charges,
                                           0.0,
                                           part.pair_pot.rcut,
                                           tr=part.pair_pot.get_truncation(),
                                           dielectric=part.pair_pot.dielectric)
                fp_point = ForcePartPair(ff.system, ff.nlist, part.scalings,
                                         pair_pot_point)
                corrections.append((fp_point, -1.0))
    # Find the largest cut-off
    rmax = 0.0
    for part in ff.parts:
        if part.name.startswith('pair_'):
            if part.name == 'pair_ei' and len(corrections) == 0: continue
            rmax = np.amax([rmax, part.pair_pot.rcut])
    # Get LAMMPS ffatypes
    ffatypes, ffatype_ids = get_lammps_ffatypes(ff)
    # Select atom pairs for each pair of atom types
    ffa_pairs = []
    for i in range(len(ffatypes)):
        index0 = np.where(ffatype_ids == i)[0][0]
        for j in range(i, len(ffatypes)):
            index1 = -1
            candidates = np.where(ffatype_ids == j)[0]
            for cand in candidates:
                if cand==index0 or cand in ff.system.neighs1[index0] or\
                    cand in ff.system.neighs2[index0] or cand in ff.system.neighs3[index0] or\
                    cand in ff.system.neighs4[index0]:
                    continue
                else:
                    index1 = cand
                    break
            if index1 == -1:
                log("ERROR constructing LAMMPS tables: there is no pair of atom types %s-%s which are not near neighbors"
                    % (ffatypes[i], ffatypes[j]))
                log("Consider using a supercell to fix this problem")
                raise ValueError
            ffa_pairs.append([index0, index1])
    if log.do_medium:
        with log.section('LAMMPS'):
            log("Generating LAMMPS table with covalent interactions")
            log.hline()
            log("rmin = %s | rmax = %s" % (log.length(rmin), log.length(rmax)))
    # We only consider one neighbor interaction
    ff.compute()
    ff.nlist.nneigh = 1
    # Construct array of evenly spaced values
    distances = np.linspace(rmin, rmax, nrows)
    ftab = open(fn, 'w')
    ftab.write("# LAMMPS tabulated potential generated by Yaff\n")
    ftab.write("# All quantities in atomic units\n")
    ftab.write(
        "# The names of the tables refer to the ffatype_ids that have to be used in the Yaff system\n"
    )
    ftab.write("#%4s %13s %21s %21s\n" % ("i", "d", "V", "F"))
    # Loop over all atom pairs
    for index0, index1 in ffa_pairs:
        energies = []
        for d in distances:
            gposnn = np.zeros(ff.system.pos.shape, float)
            ff.nlist.neighs[0] = (index0, index1, d, 0.0, 0.0, d, 0, 0, 0)
            energy = 0.0
            for part in ff.parts:
                if not part.name.startswith('pair'): continue
                if part.name == 'pair_ei': continue
                energy += part.compute(gpos=gposnn)
            for part, sign in corrections:
                gposcorr = np.zeros(ff.system.pos.shape, float)
                energy += sign * part.compute(gpos=gposcorr)
                gposnn[:] += sign * gposcorr
            row = [d, energy, gposnn[index0, 2]]
            energies.append(row)
        energies = np.asarray(energies)
        ffai = ffatypes[ffatype_ids[index0]]
        ffaj = ffatypes[ffatype_ids[index1]]
        if np.all(energies[:, 1] == 0.0):
            log.warn("Noncovalent energies between atoms %d (%s) and %d (%s) are zero"\
                    % (index0,ffai,index1,ffaj))
        if np.all(energies[:, 2] == 0.0):
            log.warn("Noncovalent forces between atoms %d (%s) and %d (%s) are zero"\
                    % (index0,ffai,index1,ffaj))
        if ffai > ffaj:
            name = '%s---%s' % (str(ffai), str(ffaj))
        else:
            name = '%s---%s' % (str(ffaj), str(ffai))
        ftab.write("%s\nN %d R %13.8f %13.8f\n\n" %
                   (name, nrows, rmin / lammps_units[unit_style]['distance'],
                    rmax / lammps_units[unit_style]['distance']))
        for irow, row in enumerate(energies):
            ftab.write(
                "%05d %+13.8f %+21.12f %+21.12f\n" %
                (irow + 1, row[0] / lammps_units[unit_style]['distance'],
                 row[1] / lammps_units[unit_style]['energy'],
                 row[2] / lammps_units[unit_style]['energy'] *
                 lammps_units[unit_style]['distance']))
        if log.do_medium:
            log("%s done" % name)
Exemple #46
0
 def finalize(self):
     if log.do_medium:
         log.hline()
Exemple #47
0
 def _init_derived_ffatypes(self):
     if self.ffatype_ids is None:
         if len(self.ffatypes) != self.natom:
             raise TypeError(
                 'When the ffatype_ids are derived automatically, the length of the ffatypes list must match the number of atoms.'
             )
         lookup = {}
         ffatypes = []
         self.ffatype_ids = np.zeros(self.natom, int)
         for i in range(self.natom):
             if self.scope_ids is None:
                 ffatype = self.ffatypes[i]
                 key = ffatype, None
             else:
                 scope_id = self.scope_ids[i]
                 ffatype = self.ffatypes[i]
                 key = ffatype, scope_id
             ffatype_id = lookup.get(key)
             if ffatype_id is None:
                 ffatype_id = len(ffatypes)
                 ffatypes.append(ffatype)
                 lookup[key] = ffatype_id
             self.ffatype_ids[i] = ffatype_id
         self.ffatypes = ffatypes
     for ffatype in self.ffatypes:
         check_name(ffatype)
     # check the range of the ids
     if self.ffatype_ids.min() != 0 or self.ffatype_ids.max() != len(
             self.ffatypes) - 1:
         raise ValueError('The ffatype_ids have incorrect bounds.')
     # differentiate ffatype_ids if the same ffatype_id is used in different
     # scopes
     if self.scopes is not None:
         self.ffatype_id_to_scope_id = {}
         fixed_fids = {}
         for i in range(self.natom):
             fid = self.ffatype_ids[i]
             sid = self.ffatype_id_to_scope_id.get(fid)
             if sid is None:
                 self.ffatype_id_to_scope_id[fid] = self.scope_ids[i]
             elif sid != self.scope_ids[i]:
                 # We found the same ffatype_id in a different scope_id. This
                 # must be fixed. First check if we have already a new
                 # scope_id ready
                 sid = self.scope_ids[i]
                 new_fid = fixed_fids.get((sid, fid))
                 if new_fid is None:
                     # No previous new fid create, do it now.
                     new_fid = len(self.ffatypes)
                     # Copy the ffatype label
                     self.ffatypes.append(self.ffatypes[fid])
                     # Keep track of the new fid
                     fixed_fids[(sid, fid)] = new_fid
                     if log.do_warning:
                         log.warn(
                             'Atoms with type ID %i in scope %s were changed to type ID %i.'
                             % (fid, self.scopes[sid], new_fid))
                 # Apply the new fid
                 self.ffatype_ids[i] = new_fid
                 self.ffatype_id_to_scope_id[new_fid] = sid
     # Turn the ffatypes in the scopes into array
     if self.ffatypes is not None:
         self.ffatypes = np.array(self.ffatypes, copy=False)
     if self.scopes is not None:
         self.scopes = np.array(self.scopes, copy=False)
     # check the range of the ids
     if self.ffatype_ids.min() != 0 or self.ffatype_ids.max() != len(
             self.ffatypes) - 1:
         raise ValueError('The ffatype_ids have incorrect bounds.')
     if log.do_medium:
         log('The following atom types are present in the system:')
         log.hline()
         if self.scopes is None:
             log('             Atom type   ID   Number of atoms')
             log.hline()
             for ffatype_id, ffatype in enumerate(self.ffatypes):
                 log('%22s  %3i       %3i' %
                     (ffatype, ffatype_id,
                      (self.ffatype_ids == ffatype_id).sum()))
         else:
             log('                 Scope              Atom type   ID   Number of atoms'
                 )
             log.hline()
             for ffatype_id, ffatype in enumerate(self.ffatypes):
                 scope = self.scopes[
                     self.ffatype_id_to_scope_id[ffatype_id]]
                 log('%22s %22s  %3i       %3i' %
                     (scope, ffatype, ffatype_id,
                      (self.ffatype_ids == ffatype_id).sum()))
         log.hline()
         log.blank()
Exemple #48
0
 def finalize(self):
     self.traj.close()
     if log.do_medium:
         log.hline()
Exemple #49
0
 def finalize(self):
     self.traj.close()
     if log.do_medium:
         log.hline()
Exemple #50
0
 def _init_derived_ffatypes(self):
     if self.ffatype_ids is None:
         if len(self.ffatypes) != self.natom:
             raise TypeError('When the ffatype_ids are derived automatically, the length of the ffatypes list must match the number of atoms.')
         lookup = {}
         ffatypes = []
         self.ffatype_ids = np.zeros(self.natom, int)
         for i in xrange(self.natom):
             if self.scope_ids is None:
                 ffatype = self.ffatypes[i]
                 key = ffatype, None
             else:
                 scope_id = self.scope_ids[i]
                 ffatype = self.ffatypes[i]
                 key = ffatype, scope_id
             ffatype_id = lookup.get(key)
             if ffatype_id is None:
                 ffatype_id = len(ffatypes)
                 ffatypes.append(ffatype)
                 lookup[key] = ffatype_id
             self.ffatype_ids[i] = ffatype_id
         self.ffatypes = ffatypes
     for ffatype in self.ffatypes:
         check_name(ffatype)
     # check the range of the ids
     if self.ffatype_ids.min() != 0 or self.ffatype_ids.max() != len(self.ffatypes)-1:
         raise ValueError('The ffatype_ids have incorrect bounds.')
     # differentiate ffatype_ids if the same ffatype_id is used in different
     # scopes
     if self.scopes is not None:
         self.ffatype_id_to_scope_id = {}
         fixed_fids = {}
         for i in xrange(self.natom):
             fid = self.ffatype_ids[i]
             sid = self.ffatype_id_to_scope_id.get(fid)
             if sid is None:
                 self.ffatype_id_to_scope_id[fid] = self.scope_ids[i]
             elif sid != self.scope_ids[i]:
                 # We found the same ffatype_id in a different scope_id. This
                 # must be fixed. First check if we have already a new
                 # scope_id ready
                 sid = self.scope_ids[i]
                 new_fid = fixed_fids.get((sid, fid))
                 if new_fid is None:
                     # No previous new fid create, do it now.
                     new_fid = len(self.ffatypes)
                     # Copy the ffatype label
                     self.ffatypes.append(self.ffatypes[fid])
                     # Keep track of the new fid
                     fixed_fids[(sid, fid)] = new_fid
                     if log.do_warning:
                         log.warn('Atoms with type ID %i in scope %s were changed to type ID %i.' % (fid, self.scopes[sid], new_fid))
                 # Apply the new fid
                 self.ffatype_ids[i] = new_fid
                 self.ffatype_id_to_scope_id[new_fid] = sid
     # Turn the ffatypes in the scopes into array
     if self.ffatypes is not None:
         self.ffatypes = np.array(self.ffatypes, copy=False)
     if self.scopes is not None:
         self.scopes = np.array(self.scopes, copy=False)
     # check the range of the ids
     if self.ffatype_ids.min() != 0 or self.ffatype_ids.max() != len(self.ffatypes)-1:
         raise ValueError('The ffatype_ids have incorrect bounds.')
     if log.do_medium:
         log('The following atom types are present in the system:')
         log.hline()
         if self.scopes is None:
             log('             Atom type   ID   Number of atoms')
             log.hline()
             for ffatype_id, ffatype in enumerate(self.ffatypes):
                 log('%22s  %3i       %3i' % (ffatype, ffatype_id, (self.ffatype_ids==ffatype_id).sum()))
         else:
             log('                 Scope              Atom type   ID   Number of atoms')
             log.hline()
             for ffatype_id, ffatype in enumerate(self.ffatypes):
                 scope = self.scopes[self.ffatype_id_to_scope_id[ffatype_id]]
                 log('%22s %22s  %3i       %3i' % (scope, ffatype, ffatype_id, (self.ffatype_ids==ffatype_id).sum()))
         log.hline()
         log.blank()