コード例 #1
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
コード例 #2
0
ファイル: ff.py プロジェクト: boegel/yaff
    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()
コード例 #3
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()
コード例 #4
0
ファイル: ff.py プロジェクト: MichaelSluydts/yaff
    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()
コード例 #5
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()
コード例 #6
0
ファイル: ff.py プロジェクト: molmod/yaff
    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()
コード例 #7
0
class ForcePartValence(ForcePart):
    '''The covalent part of a force-field model.

       The covalent force field is implemented in a three-layer approach,
       similar to the implementation of a neural network:

       1. The first layer consists of a :class:`yaff.pes.dlist.DeltaList` object
          that computes all the relative vectors needed for the internal
          coordinates in the covalent energy terms. This list is automatically
          built up as energy terms are added with the ``add_term`` method. This
          list also takes care of transforming `derivatives of the energy
          towards relative vectors` into `derivatives of the energy towards
          Cartesian coordinates and the virial tensor`.

       2. The second layer consist of a
          :class:`yaff.pes.iclist.InternalCoordinateList` object that computes
          the internal coordinates, based on the ``DeltaList``. This list is
          also automatically built up as energy terms are added. The same list
          is also responsible for transforming `derivatives of the energy
          towards internal coordinates` into `derivatives of the energy towards
          relative vectors`.

       3. The third layers consists of a :class:`yaff.pes.vlist.ValenceList`
          object. This list computes the covalent energy terms, based on the
          result in the ``InternalCoordinateList``. This list also computes the
          derivatives of the energy terms towards the internal coordinates.

       The computation of the covalent energy is the so-called `forward code
       path`, which consists of running through steps 1, 2 and 3, in that order.
       The derivatives of the energy are computed in the so-called `backward
       code path`, which consists of taking steps 1, 2 and 3 in reverse order.
       This basic idea of back-propagation for the computation of derivatives
       comes from the field of neural networks. More details can be found in the
       chapter, :ref:`dg_sec_backprop`.
    '''
    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()

    def add_term(self, term):
        '''Add a new term to the covalent force field.

           **Arguments:**

           term
                An instance of the class :class:`yaff.pes.ff.vlist.ValenceTerm`.

           In principle, one should add all energy terms before calling the
           ``compute`` method, but with the current implementation of Yaff,
           energy terms can be added at any time. (This may change in future.)
        '''
        if log.do_high:
            with log.section('VTERM'):
                log('%7i&%s %s' % (self.vlist.nv, term.get_log(), ' '.join(ic.get_log() for ic in term.ics)))
        self.vlist.add_term(term)

    def _internal_compute(self, gpos, vtens):
        with timer.section('Valence'):
            self.dlist.forward()
            self.iclist.forward()
            energy = self.vlist.forward()
            if not ((gpos is None) and (vtens is None)):
                self.vlist.back()
                self.iclist.back()
                self.dlist.back(gpos, vtens)
            return energy
コード例 #8
0
class ForcePartValenceCOM(ForcePartValence):
    '''
    Part of a force-field model with interactions that act on centers of mass
    At this moment, only covalent interactions are supported.
    '''
    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

    def _internal_compute(self, gpos, vtens):
        with timer.section('Valence'):
            self.comlist.forward()
            self.dlist.forward()
            self.iclist.forward()
            energy = 0
            energy += self.vlist.forward()
            if self.term is not None:
                energy += self.term.compute()
            if not ((gpos is None) and (vtens is None)):
                #print('AA gpos before bias: ', gpos[:3])
                self.vlist.back()
                self.iclist.back()
                self.comlist.gpos[:] = 0.0
                self.dlist.back(self.comlist.gpos, vtens)
                if self.term is not None and vtens is not None:
                    my_vtens = np.zeros((3, 3))
                    self.term.compute(np.zeros((3, 3)), my_vtens)
                    vtens += my_vtens
                energy = self._scale(self.comlist.gpos, vtens, energy)
                #print('COM bias energy: ', energy / molmod.units.kjmol)
                self.comlist.back(gpos)
                #print('ValenceCOM gpos after bias: ', gpos[:3])
            else:
                energy = self._scale(None, None, energy)
            #print('compos 0: ', self.comlist.pos[0, :])
            #print('vtab: ', self.vlist.vtab)
            #print('ValenceCOM energy: ', energy)
            return energy

    def _scale(self, gpos, vtens, energy):
        '''
        Scales the gpos and energy
        '''
        #print('energy before: ', energy / molmod.units.kjmol)
        if self.scaling is not None:
            thres = self.scaling[0]
            curve = self.scaling[1]
            #print('threshold: ', thres / molmod.units.kjmol)
            delta = energy - thres
            #print('delta: ', delta / molmod.units.kjmol)
            #print('energy: ', energy, '  thres: ', thres)
            if curve * delta < 40:
                #print(curve * delta)
                a = np.exp(curve * delta)
                b = 1
                N = (a + b)
                energy = np.log(N) / curve + thres
                #print('scaled  energy: ', energy)
                if gpos is not None:
                    scale = a / (N)
                    #print('scale: ', scale)
                    gpos *= scale
                if vtens is not None:
                    scale = a / (N)
                    vtens *= scale
            else:
                scale = 1
        #print('energy after: ', energy / molmod.units.kjmol)
        return energy
コード例 #9
0
class ForcePartValence(ForcePart):
    '''The covalent part of a force-field model.

       The covalent force field is implemented in a three-layer approach,
       similar to the implementation of a neural network:

       (0. Optional, not used by default. A layer that computes centers of mass for groups
           of atoms.)

       1. The first layer consists of a :class:`yaff.pes.dlist.DeltaList` object
          that computes all the relative vectors needed for the internal
          coordinates in the covalent energy terms. This list is automatically
          built up as energy terms are added with the ``add_term`` method. This
          list also takes care of transforming `derivatives of the energy
          towards relative vectors` into `derivatives of the energy towards
          Cartesian coordinates and the virial tensor`.

       2. The second layer consist of a
          :class:`yaff.pes.iclist.InternalCoordinateList` object that computes
          the internal coordinates, based on the ``DeltaList``. This list is
          also automatically built up as energy terms are added. The same list
          is also responsible for transforming `derivatives of the energy
          towards internal coordinates` into `derivatives of the energy towards
          relative vectors`.

       3. The third layers consists of a :class:`yaff.pes.vlist.ValenceList`
          object. This list computes the covalent energy terms, based on the
          result in the ``InternalCoordinateList``. This list also computes the
          derivatives of the energy terms towards the internal coordinates.

       The computation of the covalent energy is the so-called `forward code
       path`, which consists of running through steps 1, 2 and 3, in that order.
       The derivatives of the energy are computed in the so-called `backward
       code path`, which consists of taking steps 1, 2 and 3 in reverse order.
       This basic idea of back-propagation for the computation of derivatives
       comes from the field of neural networks. More details can be found in the
       chapter, :ref:`dg_sec_backprop`.
    '''
    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()

    def add_term(self, term):
        '''Add a new term to the covalent force field.

           **Arguments:**

           term
                An instance of the class :class:`yaff.pes.ff.vlist.ValenceTerm`.

           In principle, one should add all energy terms before calling the
           ``compute`` method, but with the current implementation of Yaff,
           energy terms can be added at any time. (This may change in future.)
        '''
        if log.do_high:
            with log.section('VTERM'):
                log('%7i&%s %s' % (self.vlist.nv, term.get_log(), ' '.join(
                    ic.get_log() for ic in term.ics)))
        self.vlist.add_term(term)

    def _internal_compute(self, gpos, vtens):
        with timer.section('Valence'):
            self.dlist.forward()
            self.iclist.forward()
            energy = self.vlist.forward()
            if not ((gpos is None) and (vtens is None)):
                self.vlist.back()
                self.iclist.back()
                self.dlist.back(gpos, vtens)
            return energy