Esempio n. 1
0
 def do_bendcharm(self, thresshold=2 * deg):
     '''
         No Harmonic bend can have a rest value equal to are large than
         180 deg - thresshold. If a master (or its slaves) has such a rest
         value, convert master and all slaves to BendCharm with
         cos(phis0)=-1.
     '''
     for master in self.valence.iter_masters(label='BendAHarm'):
         indices = [master.index]
         for slave in master.slaves:
             indices.append(slave)
         found = False
         for index in indices:
             rv = self.valence.get_params(index, only='rv')
             if rv >= 180.0 * deg - thresshold:
                 found = True
                 break
         if found:
             log.dump(
                 '%s has rest value > 180-%.0f deg, converted to BendCHarm with cos(phi0)=-1'
                 % (master.basename, thresshold / deg))
             for index in indices:
                 term = self.valence.terms[index]
                 self.valence.modify_term(
                     index, Harmonic, [BendCos(*term.get_atoms())],
                     term.basename.replace('BendAHarm', 'BendCHarm'),
                     ['HC_FC_DIAG'], ['kjmol', 'au'])
                 self.valence.set_params(index, fc=0.0, rv0=-1.0)
                 for traj in self.trajectories:
                     if traj.term.index == index:
                         traj.rv = None
                         traj.fc = None
                         traj.active = False
Esempio n. 2
0
    def do_squarebend(self, thresshold=20 * deg):
        '''
            Identify bend patterns in which 4 atoms of type A surround a central
            atom of type B with A-B-A angles of 90/180 degrees. A simple
            harmonic pattern will not be adequate since a rest value of 90 and
            180 degrees is possible for the same A-B-A term. Therefore, a
            cosine term with multiplicity of 4 is used (which corresponds to a
            chebychev4 potential with sign=-1):

                  V = K/2*[1-cos(4*theta)]

            To identify the patterns, it is assumed that the rest values have
            already been estimated from the perturbation trajectories. For each
            master and slave of a BENDAHARM term, its rest value is computed and
            checked if it lies either the interval [90-thresshold,90+thresshold]
            or [180-thresshold,180]. If this is the case, the new cosine term
            is used.

            **Optional arguments**

            thresshold
                the (half) the width of the interval around 180 deg (90 degrees)
                to check if a square BA4
        '''
        for master in self.valence.iter_masters(label='BendAHarm'):
            rvs = np.zeros([len(master.slaves) + 1], float)
            rvs[0] = self.valence.get_params(master.index, only='rv')
            for i, islave in enumerate(master.slaves):
                rvs[1 + i] = self.valence.get_params(islave, only='rv')
            n90 = 0
            n180 = 0
            nother = 0
            for i, rv in enumerate(rvs):
                if 90 * deg - thresshold <= rv and rv <= 90 * deg + thresshold:
                    n90 += 1
                elif 180 * deg - thresshold <= rv and rv <= 180 * deg + thresshold:
                    n180 += 1
                else:
                    nother += 1
            if n90 > 0 and n180 > 0:
                log.dump(
                    '%s has rest values around 90 deg and 180 deg, converted to BendCheby4'
                    % master.basename)
                #modify master and slaves
                indices = [master.index]
                for slave in master.slaves:
                    indices.append(slave)
                for index in indices:
                    term = self.valence.terms[index]
                    self.valence.modify_term(
                        index, Chebychev4, [BendCos(*term.get_atoms())],
                        term.basename.replace('BendAHarm', 'BendCheby4'),
                        ['HC_FC_DIAG'], ['kjmol', 'au'])
                    self.valence.set_params(index, sign=-1)
                    for traj in self.trajectories:
                        if traj.term.index == index:
                            traj.active = False
                            traj.fc = None
                            traj.rv = None