Example #1
0
 def satisfy(self, vterm, pars, part, system):
     if self.pars == pars:
         part_valence = ForcePartValence(system)
         part_valence.add_term(vterm)
         energy = part_valence.compute()
         ic_index = part_valence.vlist.vtab[0]['ic0']
         ic = part_valence.vlist.iclist.ictab[ic_index]['value']
         return np.abs(ic - self.rv) < self.eps
     else:
         return True
Example #2
0
    def __init__(self,
                 system,
                 term,
                 other_terms,
                 cart_penalty=1e-3 * angstrom):
        '''
            A class deriving from the Yaff ForceField class to implement the
            strain of a molecular geometry associated with the term defined by
            term_index.

            **Arguments**

            system
                A Yaff System instance containing all system information.

            term
                a Term instance representing the term of the perturbation
                trajectory of the current strain

            other_terms
                a list of Term instances representing all other terms for ICs
                for which a strain contribution should be added

            **Keyword Arguments**

            cart_penalty
                Magnitude of an extra term added to the strain that penalises
                a deviation of the cartesian coordinates of each atom with
                respect to the equilibrium coordinates. This penalty is equal
                to norm(R-R_eq)**2/(2.0*3*Natoms*cart_penalty**2) and prevents
                global translations, global rotations as well as rotations of
                molecular fragments far from the IC under consideration.
        '''
        self.coords0 = system.pos.copy()
        self.ndof = np.prod(self.coords0.shape)
        self.cart_penalty = cart_penalty
        self.cons_ic_atindexes = term.get_atoms()
        #construct main strain
        strain = ForcePartValence(system)
        for other in other_terms:
            if other.kind == 3: continue  #no cross terms
            strain.add_term(Harmonic(1.0, None, other.ics[0]))
        #set the rest values to the equilibrium values
        strain.dlist.forward()
        strain.iclist.forward()
        for iterm in range(strain.vlist.nv):
            vterm = strain.vlist.vtab[iterm]
            ic = strain.iclist.ictab[vterm['ic0']]
            vterm['par1'] = ic['value']
        ForceField.__init__(self, system, [strain])
        #Abuse the Chebychev1 polynomial to simply get the value of q-1 and
        #implement the contraint
        constraint = ForcePartValence(system)
        constraint.add_term(Chebychev1(-2.0, term.ics[0]))
        self.constraint = ForceField(system, [constraint])
        self.constrain_target = None
        self.constrain_value = None
        self.value = None
Example #3
0
 def get_hessian_contrib(self, index, fc=None):
     '''
         Get the contribution to the covalent hessian of term with given
         index (and its slaves). If fc is given, set the fc of the master
         and its slave to the given fc.
     '''
     val = ForcePartValence(self.system)
     kind = self.vlist.vtab[index]['kind']
     masterslaves = [index] + self.terms[index].slaves
     if kind == 4:  #Cosine
         m, k, rv = self.get_params(index)
         if fc is not None: k = fc
         for jterm in masterslaves:
             ics = self.terms[jterm].ics
             args = (m, k, rv) + tuple(ics)
             val.add_term(Cosine(*args))
     elif kind == 3:  #cross
         k, rv0, rv1 = self.get_params(index)
         if fc is not None: k = fc
         for jterm in masterslaves:
             ics = self.terms[jterm].ics
             args = (k, rv0, rv1) + tuple(ics)
             val.add_term(Cross(*args))
     elif kind == 1:  #Polyfour
         a0, a1, a2, a3 = list(self.get_params(index))
         if fc is not None:
             a3 = 2.0 * fc
             a1 = -4.0 * fc * np.cos(a0)**2
         for jterm in masterslaves:
             ics = self.terms[jterm].ics
             args = ([0.0, a1, 0.0, a3], ) + tuple(ics)
             val.add_term(PolyFour(*args))
     elif kind == 0:  #Harmonic:
         k, rv = self.get_params(index)
         if fc is not None: k = fc
         for jterm in masterslaves:
             ics = self.terms[jterm].ics
             args = (k, rv) + tuple(ics)
             val.add_term(Harmonic(*args))
     else:
         raise ValueError('Term kind %i not supported' % kind)
     ff = ForceField(self.system, [val])
     hcov = estimate_cart_hessian(ff)
     return hcov
Example #4
0
    def __init__(self, system, specs=None):
        '''
            **Arguments**

            system
                an instance of the Yaff System class containing all system
                properties

            **Keyword Arguments**

            specs
                Not yet implemented
        '''
        with log.section('VAL', 2, timer='Initializing'):
            log.dump('Initializing valence force field')
            self.system = system
            self.terms = []
            ForcePartValence.__init__(self, system)
            self.init_bond_terms()
            self.init_bend_terms()
            self.init_dihedral_terms()
            self.init_oop_terms()
Example #5
0
    def __init__(self, system, term, other_terms, cart_penalty=1e-3*angstrom):
        '''
            A class deriving from the Yaff ForceField class to implement the
            strain of a molecular geometry associated with the term defined by
            term_index.

            **Arguments**

            system
                A Yaff System instance containing all system information.

            term
                a Term instance representing the term of the perturbation
                trajectory of the current strain

            other_terms
                a list of Term instances representing all other terms for ICs
                for which a strain contribution should be added

            **Keyword Arguments**

            cart_penalty
                Magnitude of an extra term added to the strain that penalises
                a deviation of the cartesian coordinates of each atom with
                respect to the equilibrium coordinates. This penalty is equal
                to norm(R-R_eq)**2/(2.0*3*Natoms*cart_penalty**2) and prevents
                global translations, global rotations as well as rotations of
                molecular fragments far from the IC under consideration.
        '''
        self.coords0 = system.pos.copy()
        self.ndof = np.prod(self.coords0.shape)
        self.cart_penalty = cart_penalty
        self.cons_ic_atindexes = term.get_atoms()
        #construct main strain
        strain = ForcePartValence(system)
        for other in other_terms:
            if other.kind == 3: continue #no cross terms
            strain.add_term(Harmonic(1.0, None, other.ics[0]))
        #set the rest values to the equilibrium values
        strain.dlist.forward()
        strain.iclist.forward()
        for iterm in range(strain.vlist.nv):
            vterm = strain.vlist.vtab[iterm]
            ic = strain.iclist.ictab[vterm['ic0']]
            vterm['par1'] = ic['value']
        ForceField.__init__(self, system, [strain])
        #Abuse the Chebychev1 polynomial to simply get the value of q-1 and
        #implement the contraint
        constraint = ForcePartValence(system)
        constraint.add_term(Chebychev1(-2.0,term.ics[0]))
        self.constraint = ForceField(system, [constraint])
        self.constrain_target = None
        self.constrain_value = None
        self.value = None
Example #6
0
    def __init__(self,
                 system,
                 cons_ic,
                 cons_ic_atindexes,
                 ics,
                 cart_penalty=1e-3 * angstrom):
        '''
            A class deriving from the Yaff ForceField class to implement the
            strain of a molecular geometry associated with the term defined by
            term_index.

            **Arguments**

            system
                A Yaff System instance containing all system information.

            cons_ic
                An instance of Yaff Internal Coordinate representing the
                constrained term in the strain.

            cons_ic_atindexes
                A list of the atoms involved in the constrained IC. This is
                required for the implementation of the cartesian penalty. In
                principle this could be extracted from the information stored
                in cons_ic, but this is the lazy solution.

            ics
                A list of Yaff Internal Coordinate instances for which the
                strain needs to be minimized.

            cart_penalty
                Magnitude of an extra term added to the strain that penalises
                a deviation of the cartesian coordinates of each atom with
                respect to the equilibrium coordinates. This penalty is equal
                to norm(R-R_eq)**2/(2.0*3*Natoms*cart_penalty**2) and prevents
                global translations, global rotations as well as rotations of
                molecular fragments far from the IC under consideration.
        '''
        self.coords0 = system.pos.copy()
        self.ndof = np.prod(self.coords0.shape)
        self.cart_penalty = cart_penalty
        self.cons_ic_atindexes = cons_ic_atindexes
        part = ForcePartValence(system)
        for ic in ics:
            part.add_term(Harmonic(1.0, None, ic))
        #set the rest values to the equilibrium values
        part.dlist.forward()
        part.iclist.forward()
        for iterm in xrange(part.vlist.nv):
            term = part.vlist.vtab[iterm]
            ic = part.iclist.ictab[term['ic0']]
            term['par1'] = ic['value']
        ForceField.__init__(self, system, [part])
        #Abuse the Chebychev1 polynomial to simply get the value of q-1 and
        #implement the contraint
        part = ForcePartValence(system)
        part.add_term(Chebychev1(-2.0, cons_ic))
        self.constraint = ForceField(system, [part])
        self.constrain_target = None
        self.constrain_value = None
        self.value = None
Example #7
0
    def add_term(self, pot, ics, atypes, tasks, units):
        '''
            Adds new term both to the Yaff vlist object and a new QuickFF
            list (self.terms) which holds all information about the term
            for easy access later in QuickFF.

            **Arguments**

            pot
                an instance of ValenceTerm from `yaff.pes.vlist.py` representing
                the potential chosen for the term

            ics
                list of InternalCoordinate instances from `yaff.pes.iclist.py`

            atypes
                ordered string of atom types (required to assign name to the
                term)

            tasks
                List of strings defining all tasks that have to be performed for
                this term. Possible tasks are: PT_ALL, HC_FC_DIAG, HC_FC_CROSS,
                EQ_RV.

            units
                Units for all parameters in this term (ordered in the same
                way as parameters are stored in `yaff.vlist.vtab`)
        '''
        index = len(self.terms)
        #define the name
        if len(ics) == 1:
            tmp = {
                (0, 0): 'BondHarm/',
                (2, 0): 'BendAHarm/',
                (4, 4): 'Torsion/',
                (3, 1): 'TorsC2Harm/',
                (10, 0): 'Oopdist/',
                (11, 0): 'SqOopdist/',
            }
            prefix = tmp[(ics[0].kind, pot.kind)]
            suffix = ''
        else:
            assert len(ics) == 2 and pot.kind == 3
            prefix = 'Cross/'
            if ics[0].kind == 0 and ics[1].kind == 0:
                suffix = '/bb'  #first bond and second bond
            elif ics[0].kind == 0 and ics[1].kind == 2:
                if set(ics[0].index_pairs[0]) == set(ics[1].index_pairs[0]):
                    suffix = '/b0a'  #first bond and angle
                elif set(ics[0].index_pairs[0]) == set(ics[1].index_pairs[1]):
                    suffix = '/b1a'  #second bond and angle
                else:
                    raise ValueError(
                        'Incompatible bond/angle given in cross term')
            else:
                raise ValueError('Incompatible ICs given in cross term')
        basename = prefix + '.'.join(atypes) + suffix
        #search for possible master and update slaves
        master = None
        slaves = None
        for i, term in enumerate(self.terms):
            if term.basename == basename:
                if term.is_master():
                    master = term.index
                    term.slaves.append(index)
                else:
                    assert master == term.master
        if master is None:
            master = index
            slaves = []
        #add term to self.terms and self.vlist.vtab
        term = Term(index,
                    basename,
                    pot.kind,
                    ics,
                    tasks,
                    units,
                    master=master,
                    slaves=slaves)
        self.terms.append(term)
        if pot.kind == 1:  #all 4 parameters of PolyFour are given as 1 tuple
            args = [(None, ) * len(units)] + ics
        else:
            args = [
                None,
            ] * len(units) + ics
        ForcePartValence.add_term(self, pot(*args))
        return term