def compute_energy(particles, box_length, cut_off, constants, forcefield): r"""Calculates the total energy of the simulation. Parameters ---------- particles: util.particle_dt, array_like Information about the particles. box_length: float Length of a single dimension of the simulation square, in Angstrom. cut_off: float The distance greater than which the energies between particles is taken as zero. constants: float, array_like (optional) The constants associated with the particular forcefield used, e.g. for the function forcefields.lennard_jones, theses are [A, B] forcefield: function (optional) The particular forcefield to be used to find the energy and forces. Returns ------- util.particle_dt, array_like Information about particles, with updated accelerations and forces. float, array_like Current distances between pairs of particles in the simulation. float, array_like Current energies between pairs of particles in the simulation. """ pairs = int((particles["xacceleration"].size - 1) * particles["xacceleration"].size / 2) distances = np.zeros(pairs) energies = np.zeros(pairs) distances, dx, dy = heavy.dist(particles["xposition"], particles["yposition"], box_length) energies = forcefield(distances, constants, force=False) energies[np.where(distances > cut_off)] = 0.0 return distances, energies
def test_dist(self): xpos = np.array([0, 1]) ypos = np.array([0, 1]) box_length = 5. dr, dx, dy = comp.dist(xpos, ypos, box_length) assert_almost_equal(dr, [np.sqrt(2)]) assert_almost_equal(dx, [-1]) assert_almost_equal(dy, [-1])
def compute_force(particles, box_length, cut_off, constants, forcefield, mass): r"""Calculates the forces and therefore the accelerations on each of the particles in the simulation. Parameters ---------- particles: util.particle_dt, array_like Information about the particles. box_length: float Length of a single dimension of the simulation square, in Angstrom. cut_off: float The distance greater than which the forces between particles is taken as zero. constants: float, array_like (optional) The constants associated with the particular forcefield used, e.g. for the function forcefields.lennard_jones, theses are [A, B] forcefield: function (optional) The particular forcefield to be used to find the energy and forces. mass: float (optional) The mass of the particle being simulated (units of atomic mass units). Returns ------- util.particle_dt, array_like Information about particles, with updated accelerations and forces. float, array_like Current distances between pairs of particles in the simulation. float, array_like Current forces between pairs of particles in the simulation. float, array_like Current energies between pairs of particles in the simulation. """ particles["xacceleration"] = np.zeros(particles["xacceleration"].size) particles["yacceleration"] = np.zeros(particles["yacceleration"].size) pairs = int((particles["xacceleration"].size - 1) * particles["xacceleration"].size / 2) forces = np.zeros(pairs) distances = np.zeros(pairs) energies = np.zeros(pairs) atomic_mass_unit = 1.660539e-27 # kilograms mass_amu = mass # amu mass_kg = mass_amu * atomic_mass_unit # kilograms distances, dx, dy = heavy.dist(particles["xposition"], particles["yposition"], box_length) forces = forcefield(distances, constants, force=True) energies = forcefield(distances, constants, force=False) forces[np.where(distances > cut_off)] = 0.0 energies[np.where(distances > cut_off)] = 0.0 particles = update_accelerations(particles, forces, mass_kg, dx, dy, distances) return particles, distances, forces, energies
def calculate_pressure(particles, box_length, temperature, cut_off, constants, forcefield): r"""Calculates the instantaneous pressure of the simulation cell, found with the following relationship: .. math:: p = \langle \rho k_b T \rangle + \bigg\langle \frac{1}{3V}\sum_{i} \sum_{j<i} \mathbf{r}_{ij}\mathbf{f}_{ij} \bigg\rangle Parameters ---------- particles: util.particle_dt, array_like Information about the particles. box_length: float Length of a single dimension of the simulation square, in Angstrom. temperature: float Instantaneous temperature of the simulation. cut_off: float The distance greater than which the forces between particles is taken as zero. constants: float, array_like (optional) The constants associated with the particular forcefield used, e.g. for the function forcefields.lennard_jones, theses are [A, B] forcefield: function (optional) The particular forcefield to be used to find the energy and forces. Returns ------- float: Instantaneous pressure of the simulation. """ distances, dx, dy = heavy.dist(particles["xposition"], particles["yposition"], box_length) forces = forcefield(distances, constants, force=True) forces[np.where(distances > cut_off)] = 0.0 pres = np.sum(forces * distances) boltzmann_constant = 1.3806e-23 # joules / kelvin pres = 1.0 / (2 * box_length * box_length) * pres + ( particles["xposition"].size / (box_length * box_length) * boltzmann_constant * temperature) return pres