Esempio n. 1
0
 def _interpolation_grid_force(self):
     self._widths = []
     self._bounds = []
     self._extra_points = []
     for v in self.bias_variables:
         extra_points = min(self.grid_expansion, v.grid_size) if v.periodic else 0
         extra_range = extra_points*v._range/(v.grid_size - 1)
         self._widths.append(v.grid_size + 2*extra_points)
         self._bounds += [v.min_value - extra_range, v.max_value + extra_range]
         self._extra_points.append(extra_points)
     self._bias = np.zeros(np.prod(self._widths))
     num_bias_variables = len(self.bias_variables)
     if num_bias_variables == 1:
         self._table = openmm.Continuous1DFunction(self._bias, *self._bounds)
     elif num_bias_variables == 2:
         self._table = openmm.Continuous2DFunction(*self._widths, self._bias, *self._bounds)
     else:
         self._table = openmm.Continuous3DFunction(*self._widths, self._bias, *self._bounds)
     expression = f'bias({",".join(v.id for v in self.bias_variables)})'
     for i, v in enumerate(self.bias_variables):
         expression += f';{v.id}={v._get_energy_function(i+1)}'
     force = openmm.CustomCVForce(expression)
     for i in range(num_bias_variables):
         x = openmm.CustomExternalForce('x')
         x.addParticle(0, [])
         force.addCollectiveVariable(f'x{i+1}', x)
     force.addTabulatedFunction('bias', self._table)
     force.addGlobalParameter('Lx', 0)
     return force
Esempio n. 2
0
def get_Upair_force(Ucg, coeff, r_vals):
    """Create pairwise potentials as tabulated functions"""

    N = Ucg.n_atoms
    bcut = Ucg.bond_cutoff
    Up_vals = Ucg.Upair_values(coeff, r_vals)
    if len(Up_vals) > 1:
        table_vals = np.zeros((len(Up_vals), len(r_vals)))
        for i in range(len(Up_vals)):
            table_vals[i,:] = Up_vals[i]

        xvals = np.arange(len(Up_vals)).astype(float)
        yvals = r_vals

        Table_func = omm.Continuous2DFunction(len(xvals), len(yvals),
                table_vals.flatten(), xvals[0], xvals[-1], yvals[0], yvals[-1])

        Up_force = omm.CustomCompoundBondForce(2, "Table(p_idx, distance(p1, p2))")
        Up_force.addPerBondParameter("p_idx")
        Up_force.addTabulatedFunction("Table", Table_func)
    else:
        Table_func = omm.Continuous1DFunction(Up_vals[0], r_vals[0], r_vals[-1])

        Up_force = omm.CustomCompoundBondForce(2, "Table(distance(p1, p2))")
        Up_force.addTabulatedFunction("Table", Table_func)


    if Ucg.pair_symmetry == "shared":
        # all pairs share same interaction
        for i in range(N - bcut):
            for j in range(i + bcut, N):
                Up_force.addBond((i, j))

    elif Ucg.pair_symmetry == "seq_sep":
        # pairs with same sequence sep share same interaction
        for i in range(N - bcut):
            for j in range(i + bcut, N):
                p_idx = np.abs(j - i) - bcut
                Up_force.addBond([i, j], p_idx)

    elif Ucg.pair_symmetry == "unique":
        # all pair have different interactions
        p_idx = 0
        for i in range(N - bcut):
            for j in range(i + bcut, N):
                Up_force.addBond((i, j), (p_idx))
                p_idx += 1
    else:
        raise ValueError("pair_symmetry must be: shared, seq_sep, unique. Gave:" + str(Ucg.pair_symmetry))

    return Up_force
Esempio n. 3
0
 def __init__(self, variables, height, frequency, grid_expansion):
     self.bias_variables = [cv for cv in variables if cv.sigma is not None]
     self.height = height
     self.frequency = frequency
     self.grid_expansion = grid_expansion
     self._widths = []
     self._bounds = []
     self._expanded = []
     self._extra_points = []
     for cv in self.bias_variables:
         expanded = cv.periodic  # and len(self.bias_variables) > 1
         extra_points = min(grid_expansion, cv.grid_size) if expanded else 0
         extra_range = extra_points * cv._range / (cv.grid_size - 1)
         self._widths += [cv.grid_size + 2 * extra_points]
         self._bounds += [
             cv.min_value - extra_range, cv.max_value + extra_range
         ]
         self._expanded += [expanded]
         self._extra_points += [extra_points]
     self._bias = np.zeros(tuple(reversed(self._widths)))
     if len(variables) == 1:
         self._table = openmm.Continuous1DFunction(
             self._bias.flatten(),
             *self._bounds,
             # self.bias_variables[0].periodic,
         )
     elif len(variables) == 2:
         self._table = openmm.Continuous2DFunction(
             *self._widths,
             self._bias.flatten(),
             *self._bounds,
         )
     elif len(variables) == 3:
         self._table = openmm.Continuous3DFunction(
             *self._widths,
             self._bias.flatten(),
             *self._bounds,
         )
     else:
         raise ValueError(
             'UFED requires 1, 2, or 3 biased collective variables')
     parameter_list = ', '.join(f's_{cv.id}' for cv in self.bias_variables)
     self.force = openmm.CustomCVForce(f'bias({parameter_list})')
     for cv in self.bias_variables:
         expression = f'{cv.min_value}+{cv._range}*(x/Lx-floor(x/Lx))'
         parameter = openmm.CustomExternalForce(expression)
         parameter.addGlobalParameter('Lx', 0.0)
         parameter.addParticle(0, [])
         self.force.addCollectiveVariable(f's_{cv.id}', parameter)
     self.force.addTabulatedFunction('bias', self._table)
Esempio n. 4
0
    def __init__(self,
                 system,
                 variables,
                 temperature,
                 biasFactor,
                 height,
                 frequency,
                 saveFrequency=None,
                 biasDir=None):
        """Create a Metadynamics object.

        Parameters
        ----------
        system: System
            the System to simulate.  A CustomCVForce implementing the bias is created and
            added to the System.
        variables: list of BiasVariables
            the collective variables to sample
        temperature: temperature
            the temperature at which the simulation is being run.  This is used in computing
            the free energy.
        biasFactor: float
            used in scaling the height of the Gaussians added to the bias.  The collective
            variables are sampled as if the effective temperature of the simulation were
            temperature*biasFactor.
        height: energy
            the initial height of the Gaussians to add
        frequency: int
            the interval in time steps at which Gaussians should be added to the bias potential
        saveFrequency: int (optional)
            the interval in time steps at which to write out the current biases to disk.  At
            the same time it writes biases, it also checks for updated biases written by other
            processes and loads them in.  This must be a multiple of frequency.
        biasDir: str (optional)
            the directory to which biases should be written, and from which biases written by
            other processes should be loaded
        """
        if not unit.is_quantity(temperature):
            temperature = temperature * unit.kelvin
        if not unit.is_quantity(height):
            height = height * unit.kilojoules_per_mole
        if biasFactor < 1.0:
            raise ValueError('biasFactor must be >= 1')
        if (saveFrequency is None
                and biasDir is not None) or (saveFrequency is not None
                                             and biasDir is None):
            raise ValueError('Must specify both saveFrequency and biasDir')
        if saveFrequency is not None and (saveFrequency < frequency
                                          or saveFrequency % frequency != 0):
            raise ValueError('saveFrequency must be a multiple of frequency')
        self.variables = variables
        self.temperature = temperature
        self.biasFactor = biasFactor
        self.height = height
        self.frequency = frequency
        self.biasDir = biasDir
        self.saveFrequency = saveFrequency
        self._id = np.random.randint(0x7FFFFFFF)
        self._saveIndex = 0
        self._selfBias = np.zeros(tuple(v.gridWidth for v in variables))
        self._totalBias = np.zeros(tuple(v.gridWidth for v in variables))
        self._loadedBiases = {}
        self._deltaT = temperature * (biasFactor - 1)
        varNames = ['cv%d' % i for i in range(len(variables))]
        self._force = mm.CustomCVForce('table(%s)' % ', '.join(varNames))
        for name, var in zip(varNames, variables):
            self._force.addCollectiveVariable(name, var.force)
        widths = [v.gridWidth for v in variables]
        mins = [v.minValue for v in variables]
        maxs = [v.maxValue for v in variables]
        if len(variables) == 1:
            self._table = mm.Continuous1DFunction(self._totalBias.flatten(),
                                                  mins[0], maxs[0])
        elif len(variables) == 2:
            self._table = mm.Continuous2DFunction(widths[0], widths[1],
                                                  self._totalBias.flatten(),
                                                  mins[0], maxs[0], mins[1],
                                                  maxs[1])
        elif len(variables) == 3:
            self._table = mm.Continuous3DFunction(widths[0], widths[1],
                                                  widths[2],
                                                  self._totalBias.flatten(),
                                                  mins[0], maxs[0], mins[1],
                                                  maxs[1], mins[2], maxs[2])
        else:
            raise ValueError(
                'Metadynamics requires 1, 2, or 3 collective variables')
        self._force.addTabulatedFunction('table', self._table)
        self._force.setForceGroup(31)
        system.addForce(self._force)
        self._syncWithDisk()
Esempio n. 5
0
def get_Ucv_force(n_beads, Ucv_ext, cv_grid_ext, cv_coeff, cv_mean, feat_types, feat_idxs):
    feature_funcs = {"dist":"distance(p{}, p{})", "invdist":"(1/distance(p{}, p{}))", 
            "angle":"angle(p{}, p{}, p{})", "dih":"dihedral(p{}, p{}, p{}, p{})"}


    cv_expr = "Table("
    pr_cv_expr = "Table("
    #cv_expr = ""
    #pr_cv_expr = ""
    feat_idx = 0
    atm_to_p_idx = []
    p_idx = -np.ones(n_beads, int)
    curr_p_idx = 1
    for i in range(len(feat_types)):
        feat_fun = feature_funcs[feat_types[i]]
        for j in range(cv_coeff.shape[0]):
            idxs = feat_idxs[i][j]

            expr_idxs = []
            for n in range(len(idxs)): 
                if p_idx[idxs[n]] == -1:
                    p_idx[idxs[n]] = curr_p_idx
                    atm_to_p_idx.append(int(idxs[n]))
                    curr_p_idx += 1
                expr_idxs.append(p_idx[idxs[n]])
            #print("{} -> {}      {} -> {}".format(idxs[0], expr_idxs[0], idxs[1], expr_idxs[1]))   # DEBUGGING

            feat_explicit = feat_fun.format(*expr_idxs)

            feat_coeff = cv_coeff[feat_idx,0]
            feat_mean = cv_mean[feat_idx]

            if feat_idx > 0:
                if feat_coeff < 0:
                    cv_expr += " - {:.5f}*(".format(abs(feat_coeff))
                    pr_cv_expr += "\n - {:.5f}*(".format(abs(feat_coeff))
                else:
                    cv_expr += " + {:.5f}*(".format(abs(feat_coeff))
                    pr_cv_expr += "\n + {:.5f}*(".format(abs(feat_coeff))
            else:
                if feat_coeff < 0:
                    cv_expr += "-{:.5f}*(".format(abs(feat_coeff))
                    pr_cv_expr += "-{:.5f}*(".format(abs(feat_coeff))
                else:
                    cv_expr += "{:.5f}*(".format(abs(feat_coeff))
                    pr_cv_expr += "{:.5f}*(".format(abs(feat_coeff))

            cv_expr += feat_explicit
            pr_cv_expr += feat_explicit

            if feat_mean < 0:
                cv_expr += " + {:.5f})".format(abs(feat_mean))
                pr_cv_expr += " + {:.5f})".format(abs(feat_mean))
            else:
                cv_expr += " - {:.5f})".format(abs(feat_mean))
                pr_cv_expr += " - {:.5f})".format(abs(feat_mean))

            feat_idx += 1 

    cv_expr += ");"
    pr_cv_expr += ");"
    #cv_expr += ";"
    #pr_cv_expr += ";"

    Ucv_force = omm.CustomCompoundBondForce(n_beads, cv_expr)
    Ucv_force.addBond(atm_to_p_idx)
    #Ucv_force.addFunction("Table", Ucv_ext, cv_grid_ext[0], cv_grid_ext[-1])
    Table_func = omm.Continuous1DFunction(Ucv_ext, cv_grid_ext[0], cv_grid_ext[-1])
    Ucv_force.addTabulatedFunction("Table", Table_func)

    return Ucv_force, pr_cv_expr