static PyObject * PoseDihedralTerm(PyObject *dummy, PyObject *args) { PyFFEnergyTermObject *self; char *name = "pose dihedral angle"; self = PyFFEnergyTerm_New(); if (self == NULL) return NULL; if (!PyArg_ParseTuple(args, "O!OO|s", &PyUniverseSpec_Type, &self->universe_spec, &self->data[0], &self->data[1], &name)) return NULL; self->evaluator_name = "pose dihedral angle"; self->term_names[0] = allocstring(name); if (self->term_names[0] == NULL) return PyErr_NoMemory(); Py_INCREF(self->universe_spec); Py_INCREF(self->data[0]); Py_INCREF(self->data[1]); self->n = ((PyArrayObject *)self->data[0])->dimensions[0]; self->nterms = 1; self->eval_func = pose_dihedral_evaluator; self->threaded = 1; self->thread_safe = 1; self->nbarriers = 0; self->parallelized = 1; return (PyObject *)self; }
static PyObject * ListOfNParticleTerms(PyObject *args, ff_eterm_function f, char *eval_name, char *default_term_name) { PyFFEnergyTermObject *self; char *name = default_term_name; self = PyFFEnergyTerm_New(); if (self == NULL) return NULL; if (!PyArg_ParseTuple(args, "O!OO|s", &PyUniverseSpec_Type, &self->universe_spec, &self->data[0], &self->data[1], &name)) return NULL; self->evaluator_name = eval_name; self->term_names[0] = allocstring(name); if (self->term_names[0] == NULL) return PyErr_NoMemory(); Py_INCREF(self->universe_spec); Py_INCREF(self->data[0]); /* indices */ Py_INCREF(self->data[1]); /* parameters */ self->n = ((PyArrayObject *)self->data[0])->dimensions[0]; self->nterms = 1; self->eval_func = f; self->threaded = 1; self->thread_safe = 1; self->nbarriers = 0; self->parallelized = 1; return (PyObject *)self; }
/* The next function is meant to be called from Python. It creates the energy term object at the C level and stores all the parameters in there in a form that is convient to access for the C routine above. This is the routine that is imported into and called by the Python module, HarmonicOscillatorFF.py. */ static PyObject * HarmonicOscillatorTerm(PyObject *dummy, PyObject *args) { PyFFEnergyTermObject *self; int atom_index; double x, y, z; double force_constant; /* Create a new energy term object and return if the creation fails. */ self = PyFFEnergyTerm_New(); if (self == NULL) return NULL; /* Convert the parameters to C data types. */ if (!PyArg_ParseTuple(args, "O!idddd", &PyUniverseSpec_Type, &self->universe_spec, &atom_index, &x, &y, &z, &force_constant)) return NULL; /* We keep a reference to the universe_spec in the newly created energy term object, so we have to increase the reference count. */ Py_INCREF(self->universe_spec); /* A pointer to the evaluation routine. */ self->eval_func = harmonic_evaluator; /* The name of the energy term object. */ self->evaluator_name = "harmonic_oscillator"; /* The names of the individual energy terms - just one here. */ self->term_names[0] = allocstring("harmonic_oscillator"); if (self->term_names[0] == NULL) return PyErr_NoMemory(); self->nterms = 1; /* self->param is a storage area for parameters. Note that there are only 40 slots (double) there, if you need more space, you can use self->data, an array for up to 40 Python object pointers. */ self->param[0] = x; self->param[1] = y; self->param[2] = z; self->param[3] = force_constant; self->param[4] = (double) atom_index; /* Return the energy term object. */ return (PyObject *)self; }
/* The next function is meant to be called from Python. It creates the energy term object at the C level and stores all the parameters in there in a form that is convient to access for the C routine above. This is the routine that is imported into and called by the Python module, ElectricField.py. */ static PyObject * ElectricFieldTerm_z(PyObject *dummy, PyObject *args) { PyFFEnergyTermObject *self; PyArrayObject *charges; double z; /* Create a new energy term object and return if the creation fails. */ self = PyFFEnergyTerm_New(); if (self == NULL) return NULL; /* Convert the parameters to C data types. */ if (!PyArg_ParseTuple(args, "O!O!d", &PyUniverseSpec_Type, &self->universe_spec, &PyArray_Type, &charges, &z)) return NULL; /* We keep a reference to the universe_spec in the newly created energy term object, so we have to increase the reference count. */ Py_INCREF(self->universe_spec); /* A pointer to the evaluation routine. */ self->eval_func = ef_evaluator; /* The name of the energy term object. */ self->evaluator_name = "electric_field_z"; /* The names of the individual energy terms - just one here. */ self->term_names[0] = allocstring("electric_field_z"); if (self->term_names[0] == NULL) return PyErr_NoMemory(); self->nterms = 1; /* self->param is a storage area for parameters. Note that there are only 40 slots (double) there. */ self->param[2] = z; /* self->data is the other storage area for parameters. There are 40 Python object slots there */ self->data[0] = (PyObject *)charges; Py_INCREF(charges); /* Return the energy term object. */ return (PyObject *)self; }
/* The next function is meant to be called from Python. It creates the energy term object at the C level and stores all the parameters in there in a form that is convient to access for the C routine above. This is the routine that is imported into and called by the Python module, OBC.py. */ static PyObject * OBCTerm(PyObject *dummy, PyObject *args) { PyFFEnergyTermObject *self; int numParticles; PyArrayObject *charges; PyArrayObject *atomicRadii; PyArrayObject *scaleFactors; double strength; /* Create a new energy term object and return if the creation fails. */ self = PyFFEnergyTerm_New(); if (self == NULL) return NULL; /* Convert the parameters to C data types. */ if (!PyArg_ParseTuple(args, "O!idO!O!O!", &PyUniverseSpec_Type, &self->universe_spec, &numParticles, &strength, &PyArray_Type, &charges, &PyArray_Type, &atomicRadii, &PyArray_Type, &scaleFactors)) return NULL; /* We keep a reference to the universe_spec in the newly created energy term object, so we have to increase the reference count. */ Py_INCREF(self->universe_spec); /* A pointer to the evaluation routine. */ self->eval_func = ef_evaluator; /* The name of the energy term object. */ self->evaluator_name = "OBC"; /* The names of the individual energy terms - just one here. */ self->term_names[0] = allocstring("OBC"); if (self->term_names[0] == NULL) return PyErr_NoMemory(); self->nterms = 1; struct ObcParameters* obcParameters = newObcParameters( numParticles, strength, (double *)charges->data, (double *)atomicRadii->data, (double *)scaleFactors->data); struct ReferenceObc* obc = newReferenceObc(obcParameters); /* self->param is a storage area for parameters. Note that there are only 40 slots (double) there. */ self->param[0] = (double) numParticles; self->param[1] = strength; /* self->data is the other storage area for parameters. There are 40 Python object slots there */ self->data[0] = (PyObject *)charges; Py_INCREF(charges); self->data[1] = (PyObject *)atomicRadii; Py_INCREF(atomicRadii); self->data[2] = (PyObject *)scaleFactors; Py_INCREF(scaleFactors); self->data[3] = (PyObject *)obcParameters; Py_INCREF(obcParameters); // Seems to increment the number of particles setNumberOfAtoms(obcParameters, numParticles); self->data[4] = (PyObject *)obc; Py_INCREF(obc); /* Return the energy term object. */ return (PyObject *)self; }