class ElectrostaticInteractionsTests(ut.TestCase): # Handle to espresso system system = espressomd.System(box_l=[1.0, 1.0, 1.0]) def paramsMatch(self, inParams, outParams): """Check, if the parameters set and gotten back match. Only check keys present in inParams. """ for k in inParams.keys(): if k not in outParams: print(k, "missing from returned parameters") return False if outParams[k] != inParams[k]: print("Mismatch in parameter ", k, inParams[k], outParams[k]) return False return True def setUp(self): if len(self.system.part) == 0 : self.system.periodicity=[0,0,1] self.system.cell_system.set_n_square() self.system.box_l = 10, 10, 10 self.system.part.add(id=0, pos = [0, 0, 0]) self.system.part.add(id=1, pos = [0.1, 0.1, 0.1]) self.system.part[0].q = 1 self.system.part[1].q = -1 def generateTestForElectrostaticInteraction(_interClass, _params): """Generates test cases for checking interaction parameters set and gotten back from Es actually match. Only keys which are present in _params are checked 1st: Interaction parameters as dictionary, i.e., {"k"=1.,"r_0"=0. 2nd: Name of the interaction property to set (i.e. "P3M") """ params = _params interClass = _interClass def func(self): # This code is run at the execution of the generated function. # It will use the state of the variables in the outer function, # which was there, when the outer function was called # set Parameter Inter = interClass(**params) Inter.validate_params() Inter._set_params_in_es_core() self.system.actors.add(Inter) # Read them out again outParams = Inter._get_params_from_es_core() self.assertTrue(self.paramsMatch(params, outParams), "Missmatch of parameters.\nParameters set " + params.__str__() + " vs. output parameters " + outParams.__str__()) return func if espressomd.has_features("ELECTROSTATICS", "PARTIAL_PERIODIC"): test_mmm1d = generateTestForElectrostaticInteraction(MMM1D, dict(prefactor=2.0, maxPWerror= 0.001, far_switch_radius = 3, tune=False))
import espressomd.electrokinetics import espressomd.shapes from espressomd import * import numpy as np import sys import math from ek_common import * ########################################################################## # Set up the System # ########################################################################## # Set the slit pore geometry the width is the non-periodic part of the geometry # the padding is used to ensure that there is no field inside outside the slit @ut.skipIf(not espressomd.has_features(["ELECTROKINETICS", "EK_BOUNDARIES"]), "Features not available, skipping test!") class ek_eof_one_species_x(ut.TestCase): es = espressomd.System(box_l=[1.0, 1.0, 1.0]) def test(self): system = self.es pi = math.pi box_x = 6 box_y = 6 width = 50 padding = 6 box_z = width + 2 * padding
class Dipolar_p3m_mdlc_p2nfft(ut.TestCase): """Tests mdlc (2d) as well as dipolar p3m and dipolar p2nfft (3d) against stored data. Validity of the stored data: 2d: as long as this test AND the scafacos_dipolar_1d_2d test passes, we are save. 3d: As long as the independently written p3m and p2nfft agree, we are save. """ s = espressomd.System(box_l=[1.0, 1.0, 1.0]) s.seed = s.cell_system.get_state()['n_nodes'] * [1234] s.time_step = 0.01 s.cell_system.skin = .4 s.periodicity = 1, 1, 1 s.thermostat.turn_off() def test_mdlc(self): s = self.s s.part.clear() rho = 0.3 # This is only for box size calculation. The actual particle numbwe is # lower, because particles are removed from the mdlc gap region n_particle = 100 particle_radius = 0.5 box_l = pow(((4 * n_particle * 3.141592654) / (3 * rho)), 1.0 / 3.0) * particle_radius s.box_l = box_l, box_l, box_l f = open(abspath("data/mdlc_reference_data_energy.dat")) ref_E = float(f.readline()) f.close() # Particles data = np.genfromtxt( abspath("data/mdlc_reference_data_forces_torques.dat")) for p in data[:, :]: s.part.add(id=int(p[0]), pos=p[1:4], dip=p[4:7]) s.part[:].rotation = (1, 1, 1) p3m = magnetostatics.DipolarP3M(prefactor=1, mesh=32, accuracy=1E-4) dlc = magnetostatic_extensions.DLC(maxPWerror=1E-5, gap_size=2.) s.actors.add(p3m) s.actors.add(dlc) s.thermostat.turn_off() s.integrator.run(0) err_f = np.sum(np.sqrt(np.sum( (s.part[:].f - data[:, 7:10])**2, 1)), 0) / np.sqrt(data.shape[0]) err_t = np.sum( np.sqrt(np.sum((s.part[:].torque_lab - data[:, 10:13])**2, 1)), 0) / np.sqrt(data.shape[0]) err_e = s.analysis.energy()["dipolar"] - ref_E print("Energy difference", err_e) print("Force difference", err_f) print("Torque difference", err_t) tol_f = 2E-3 tol_t = 2E-3 tol_e = 1E-3 self.assertLessEqual(abs(err_e), tol_e, "Energy difference too large") self.assertLessEqual(abs(err_t), tol_t, "Torque difference too large") self.assertLessEqual(abs(err_f), tol_f, "Force difference too large") s.part.clear() del s.actors[0] del s.actors[0] def test_p3m(self): s = self.s s.part.clear() rho = 0.09 # This is only for box size calculation. The actual particle numbwe is # lower, because particles are removed from the mdlc gap region n_particle = 1000 particle_radius = 1 box_l = pow(((4 * n_particle * 3.141592654) / (3 * rho)), 1.0 / 3.0) * particle_radius s.box_l = box_l, box_l, box_l # Particles data = np.genfromtxt(abspath("data/p3m_magnetostatics_system.data")) for p in data[:, :]: s.part.add(id=int(p[0]), pos=p[1:4], dip=p[4:7]) s.part[:].rotation = (1, 1, 1) p3m = magnetostatics.DipolarP3M(prefactor=1, mesh=32, accuracy=1E-6, epsilon="metallic") s.actors.add(p3m) s.integrator.run(0) expected = np.genfromtxt( abspath("data/p3m_magnetostatics_expected.data"))[:, 1:] err_f = np.sum(np.sqrt(np.sum((s.part[:].f - expected[:, 0:3])**2, 1)), 0) / np.sqrt(data.shape[0]) err_t = np.sum( np.sqrt(np.sum((s.part[:].torque_lab - expected[:, 3:6])**2, 1)), 0) / np.sqrt(data.shape[0]) ref_E = 5.570 err_e = s.analysis.energy()["dipolar"] - ref_E print("Energy difference", err_e) print("Force difference", err_f) print("Torque difference", err_t) tol_f = 2E-3 tol_t = 2E-3 tol_e = 1E-3 self.assertLessEqual(abs(err_e), tol_e, "Energy difference too large") self.assertLessEqual(abs(err_t), tol_t, "Torque difference too large") self.assertLessEqual(abs(err_f), tol_f, "Force difference too large") s.part.clear() del s.actors[0] @ut.skipIf(not espressomd.has_features("SCAFACOS_DIPOLES"), "Skipped, because test requires SCAFACOS_DIPOLES") def test_scafacos_dipoles(self): s = self.s s.part.clear() rho = 0.09 # This is only for box size calculation. The actual particle numbwe is # lower, because particles are removed from the mdlc gap region n_particle = 1000 particle_radius = 1 box_l = pow(((4 * n_particle * 3.141592654) / (3 * rho)), 1.0 / 3.0) * particle_radius s.box_l = box_l, box_l, box_l # Particles data = np.genfromtxt(abspath("data/p3m_magnetostatics_system.data")) for p in data[:, :]: s.part.add(id=int(p[0]), pos=p[1:4], dip=p[4:7], rotation=(1, 1, 1)) scafacos = magnetostatics.Scafacos(prefactor=1, method_name="p2nfft", method_params={ "p2nfft_verbose_tuning": 0, "pnfft_N": "32,32,32", "pnfft_n": "32,32,32", "pnfft_window_name": "bspline", "pnfft_m": "4", "p2nfft_ignore_tolerance": "1", "pnfft_diff_ik": "0", "p2nfft_r_cut": "11", "p2nfft_alpha": "0.31" }) s.actors.add(scafacos) s.integrator.run(0) expected = np.genfromtxt( abspath("data/p3m_magnetostatics_expected.data"))[:, 1:] err_f = np.sum(np.sqrt(np.sum((s.part[:].f - expected[:, 0:3])**2, 1)), 0) / np.sqrt(data.shape[0]) err_t = np.sum( np.sqrt(np.sum((s.part[:].torque_lab - expected[:, 3:6])**2, 1)), 0) / np.sqrt(data.shape[0]) ref_E = 5.570 err_e = s.analysis.energy()["dipolar"] - ref_E print("Energy difference", err_e) print("Force difference", err_f) print("Torque difference", err_t) tol_f = 2E-3 tol_t = 2E-3 tol_e = 1E-3 self.assertLessEqual(abs(err_e), tol_e, "Energy difference too large") self.assertLessEqual(abs(err_t), tol_t, "Torque difference too large") self.assertLessEqual(abs(err_f), tol_f, "Force difference too large") s.part.clear() del s.actors[0]
class ParticleProperties(ut.TestCase): # Particle id to work on pid = 17 # Error tolerance when comparing arrays/tuples... tol = 1E-9 # Handle for espresso system system = espressomd.System(box_l=[100.0, 100.0, 100.0]) system.cell_system.skin = 0 system.time_step = 0.01 f1 = FeneBond(k=1, d_r_max=2) system.bonded_inter.add(f1) f2 = FeneBond(k=1, d_r_max=2) system.bonded_inter.add(f2) def setUp(self): if not self.system.part.exists(self.pid): self.system.part.add(id=self.pid, pos=(0, 0, 0)) def tearDown(self): self.system.part.clear() def generateTestForVectorProperty(_propName, _value): """Generates test cases for vectorial particle properties such as position, velocity... 1st arg: name of the property (e.g., "pos"), 2nd array: value to be used for testing. Has to be numpy.array of floats """ # This is executed, when generateTestForVectorProperty() is called propName = _propName value = _value def func(self): # This code is run at the execution of the generated function. # It will use the state of the variables in the outer function, # which was there, when the outer function was called setattr(self.system.part[self.pid], propName, value) np.testing.assert_allclose( np.array(getattr(self.system.part[self.pid], propName)), value, err_msg=propName + ": value set and value gotten back differ.", atol=self.tol) return func def generateTestForScalarProperty(_propName, _value): """Generates test cases for scalar particle properties such as type, mass, charge... 1st arg: name of the property (e.g., "type"), 2nd array: value to be used for testing. int or float """ # This is executed, when generateTestForVectorProperty() is called propName = _propName value = _value def func(self): # This code is run at the execution of the generated function. # It will use the state of the variables in the outer function, # which was there, when the outer function was called setattr(self.system.part[self.pid], propName, value) self.assertEqual( getattr(self.system.part[self.pid], propName), value, propName + ": value set and value gotten back differ.") return func test_pos = generateTestForVectorProperty("pos", np.array([0.1, 0.2, 0.3])) test_v = generateTestForVectorProperty("v", np.array([0.2, 0.3, 0.4])) test_f = generateTestForVectorProperty("f", np.array([0.2, 0.3, 0.7])) test_type = generateTestForScalarProperty("type", int(3)) test_mol_id = generateTestForScalarProperty("mol_id", int(3)) test_bonds_property = generateTestForScalarProperty( "bonds", ((f1, 1), (f2, 2))) if espressomd.has_features(["MASS"]): test_mass = generateTestForScalarProperty("mass", 1.3) if espressomd.has_features(["ROTATION"]): for x in 0, 1: for y in 0, 1: for z in 0, 1: test_rotation = generateTestForVectorProperty( "rotation", np.array([x, y, z], dtype=int)) test_omega_lab = generateTestForVectorProperty("omega_lab", np.array([4., 2., 1.])) test_omega_body = generateTestForVectorProperty( "omega_body", np.array([4., 72., 1.])) test_torque_lab = generateTestForVectorProperty( "torque_lab", np.array([4., 72., 3.7])) # The tested value has to be normalized! test_quat = generateTestForVectorProperty( "quat", np.array([0.5, 0.5, 0.5, 0.5])) if espressomd.has_features(["LANGEVIN_PER_PARTICLE"]): if espressomd.has_features(["PARTICLE_ANISOTROPY"]): test_gamma = generateTestForVectorProperty( "gamma", np.array([2., 9., 0.23])) def test_gamma_single(self): self.system.part[self.pid].gamma = 17.4 np.testing.assert_array_equal( np.copy(self.system.part[self.pid].gamma), np.array([17.4, 17.4, 17.4]), "gamma: value set and value gotten back differ.") else: test_gamma = generateTestForScalarProperty("gamma", 17.3) if espressomd.has_features(["PARTICLE_ANISOTROPY"]): test_gamma_rot = generateTestForVectorProperty( "gamma_rot", np.array([5., 10., 0.33])) def test_gamma_rot_single(self): self.system.part[self.pid].gamma_rot = 15.4 np.testing.assert_array_equal( np.copy(self.system.part[self.pid].gamma_rot), np.array([15.4, 15.4, 15.4]), "gamma_rot: value set and value gotten back differ.") else: test_gamma_rot = generateTestForScalarProperty( "gamma_rot", 14.23) # test_director=generateTestForVectorProperty("director", # np.array([0.5,0.4,0.3])) if espressomd.has_features(["ELECTROSTATICS"]): test_charge = generateTestForScalarProperty("q", -19.7) if espressomd.has_features(["EXTERNAL_FORCES"]): test_ext_force = generateTestForVectorProperty("ext_force", [0.1, 0.2, 0.3]) test_fix = generateTestForVectorProperty("fix", [True, False, True]) if espressomd.has_features(["EXTERNAL_FORCES", "ROTATION"]): test_ext_torque = generateTestForVectorProperty( "ext_torque", [.4, .5, .6]) if espressomd.has_features(["DIPOLES"]): test_dip = generateTestForVectorProperty("dip", np.array([0.5, -0.5, 3])) test_dipm = generateTestForScalarProperty("dipm", -9.7) if espressomd.has_features(["VIRTUAL_SITES"]): test_virtual = generateTestForScalarProperty("virtual", 1) if espressomd.has_features(["VIRTUAL_SITES_RELATIVE"]): def test_yy_vs_relative(self): self.system.part.add(id=0, pos=(0, 0, 0)) self.system.part.add(id=1, pos=(0, 0, 0)) self.system.part[1].vs_relative = (0, 5.0, (0.5, -0.5, -0.5, -0.5)) self.system.part[1].vs_quat = [1, 2, 3, 4] np.testing.assert_array_equal(self.system.part[1].vs_quat, [1, 2, 3, 4]) res = self.system.part[1].vs_relative self.assertEqual(res[0], 0, "vs_relative: " + res.__str__()) self.assertEqual(res[1], 5.0, "vs_relative: " + res.__str__()) np.testing.assert_allclose(res[2], np.array((0.5, -0.5, -0.5, -0.5)), err_msg="vs_relative: " + res.__str__(), atol=self.tol) @utx.skipIfMissingFeatures("DIPOLES") def test_contradicting_properties_dip_dipm(self): with self.assertRaises(ValueError): self.system.part.add(pos=[0, 0, 0], dip=[1, 1, 1], dipm=1.0) @utx.skipIfMissingFeatures(["DIPOLES", "ROTATION"]) def test_contradicting_properties_dip_quat(self): with self.assertRaises(ValueError): self.system.part.add(pos=[0, 0, 0], dip=[1, 1, 1], quat=[1.0, 1.0, 1.0, 1.0]) @utx.skipIfMissingFeatures("ELECTROSTATICS") def test_particle_selection(self): s = self.system s.part.clear() positions = ((0.2, 0.3, 0.4), (0.4, 0.2, 0.3), (0.7, 0.7, 0.7)) charges = [0, 1E-6, -1, 1] # Place particles i = 0 for pos in positions: for q in charges: s.part.add(pos=pos, q=q, id=i) i += 1 # Scalar property res = s.part.select(q=0) self.assertEqual(len(res.id), len(positions)) for p in res: self.assertAlmostEqual(p.q, 0, places=13) # Vectorial property res = s.part.select(pos=(0.2, 0.3, 0.4)) self.assertEqual(len(res.id), len(charges)) for p in res: np.testing.assert_allclose((0.2, 0.3, 0.4), np.copy(p.pos), atol=1E-12) # Two criteria res = s.part.select(pos=(0.2, 0.3, 0.4), q=0) self.assertEqual(tuple(res.id), (0, )) # Empty result res = s.part.select(q=17) self.assertEqual(tuple(res.id), ()) # User-specified criterion res = s.part.select(lambda p: p.pos[0] < 0.5) self.assertEqual(tuple(sorted(res.id)), (0, 1, 2, 3, 4, 5, 6, 7)) def test_image_box(self): s = self.system s.part.clear() pos = 1.5 * s.box_l s.part.add(pos=pos) np.testing.assert_equal(np.copy(s.part[0].image_box), [1, 1, 1]) def test_accessing_invalid_id_raises(self): self.system.part.clear() handle_to_non_existing_particle = self.system.part[42] with self.assertRaises(RuntimeError): handle_to_non_existing_particle.id def test_parallel_property_setters(self): s = self.system s.part.clear() s.part.add(pos=s.box_l * np.random.random((100, 3))) # Copy individual properties of particle 0 print( "If this test hangs, there is an mpi deadlock in a particle property setter." ) for p in espressomd.particle_data.particle_attributes: # Uncomment to identify guilty property # print( p) if not hasattr(s.part[0], p): raise Exception( "Inconsistency between ParticleHandle and particle_data.particle_attributes" ) try: setattr(s.part[:], p, getattr(s.part[0], p)) except AttributeError: print("Skipping read-only", p) # Cause a different mpi callback to uncover deadlock immediately x = getattr(s.part[:], p) def test_zz_remove_all(self): for id in self.system.part[:].id: self.system.part[id].remove() self.system.part.add(pos=np.random.random( (100, 3)) * self.system.box_l, id=np.arange(100, dtype=int)) ids = self.system.part[:].id np.random.shuffle(ids) for id in ids: self.system.part[id].remove() with self.assertRaises(Exception): self.system.part[17].remove() def test_coord_fold_corner_cases(self): system = self.system system.time_step = .5 system.cell_system.set_domain_decomposition(use_verlet_lists=False) system.cell_system.skin = 0 system.min_global_cut = 3 system.part.clear() p1 = system.part.add(pos=3 * [np.nextafter(0., -1.)], v=system.box_l / 3) print(p1.pos) p2 = system.part.add(pos=np.nextafter(system.box_l, 2 * system.box_l), v=system.box_l / 3) print(p2.pos) p3 = system.part.add(pos=np.nextafter(system.box_l, (0, 0, 0)), v=system.box_l / 3) print(p3.pos) p4 = system.part.add(pos=3 * [np.nextafter(0., 1.)], v=system.box_l / 3) print(p4.pos) system.integrator.run(3) for p in system.part: for i in range(3): self.assertGreaterEqual(p.pos_folded[i], 0) self.assertLess(p.pos_folded[i], system.box_l[i]) # Force resort system.part.add(pos=(0, 0, 0)) system.integrator.run(9) for p in system.part: for i in range(3): self.assertGreaterEqual(p.pos_folded[i], 0) self.assertLess(p.pos_folded[i], system.box_l[i])
# ESPResSo is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # # Integration test for exclusions from __future__ import print_function import unittest as ut import espressomd import numpy as np @ut.skipIf(not espressomd.has_features(['EXCLUSIONS']), "Skipping test") class Exclusions(ut.TestCase): s = espressomd.System(box_l=[1.0, 1.0, 1.0]) s.seed = s.cell_system.get_state()['n_nodes'] * [1234] def setUp(self): self.s.part.clear() self.s.box_l = 3 * [10] self.s.cell_system.skin = 0.4 self.s.time_step = 0.01 def test_add_remove(self): self.s.part.add(id=0, pos=[0, 0, 0]) self.s.part.add(id=1, pos=[0, 0, 0]) self.s.part.add(id=2, pos=[0, 0, 0])
from __future__ import division, print_function import unittest as ut import espressomd from espressomd.shapes import SimplePore, Cylinder # Integration test for simple pore # The radional is to hit the pore everywhere with particles # and check that it does not blow up. The cylinder is needed # because the pore is tilted with respect to the box, without # it particles could enter the constraint over the periodic boundarys, # leading to force jumps. @ut.skipIf(not espressomd.has_features(["CONSTRAINTS", "LENNARD_JONES"]), "Features not available, skipping test!") class SimplePoreConstraint(ut.TestCase): def test(self): s = espressomd.System(box_l=[1.0, 1.0, 1.0]) box_yz = 15. box_x = 20. s.box_l = [box_x, box_yz, box_yz] s.time_step = 0.01 s.cell_system.skin = 0.4 lj_eps = 1.0 lj_sig = 1.0 lj_cut = lj_sig * 2**(1. / 6.) s.constraints.add(particle_type=0, penetrable=0, only_positive=0,
class test_minimize_energy(ut.TestCase): np.random.seed(42) system = espressomd.System(box_l=[10.0, 10.0, 10.0]) test_rotation = espressomd.has_features(("ROTATION", "DIPOLES")) if test_rotation: from espressomd.constraints import HomogeneousMagneticField box_l = 10.0 density = 0.6 vol = box_l**3 n_part = int(vol * density) lj_eps = 1.0 lj_sig = 1.0 lj_cut = 1.12246 def setUp(self): self.system.box_l = 3 * [self.box_l] self.system.cell_system.skin = 0.4 self.system.time_step = 0.01 self.system.non_bonded_inter[0, 0].lennard_jones.set_params( epsilon=self.lj_eps, sigma=self.lj_sig, cutoff=self.lj_cut, shift="auto") if self.test_rotation: self.system.constraints.add( self.HomogeneousMagneticField(H=[-0.5, 0, 0])) def tearDown(self): self.system.part.clear() self.system.integrator.set_vv() def test_relaxation(self): for i in range(self.n_part): p = self.system.part.add( id=i, pos=np.random.random(3) * self.system.box_l) if self.test_rotation: p.dip = np.random.random(3) p.dipm = 1 p.rotation = (1, 1, 1) self.assertNotAlmostEqual( self.system.analysis.energy()["total"], 0, places=10) self.system.integrator.set_steepest_descent( f_max=0.0, gamma=0.1, max_displacement=0.05) self.system.integrator.run(500) self.system.constraints.clear() # Check self.assertAlmostEqual( self.system.analysis.energy()["total"], 0, places=10) np.testing.assert_allclose(np.copy(self.system.part[:].f), 0.) if self.test_rotation: np.testing.assert_allclose(np.copy(self.system.part[:].dip), np.hstack((-np.ones((self.n_part, 1)), np.zeros((self.n_part, 1)), np.zeros((self.n_part, 1)))), atol=1E-9) def test_rescaling(self): self.system.part.add(pos=[5., 5., 4.9], type=0) self.system.part.add(pos=[5., 5., 5.1], type=0) self.system.non_bonded_inter[0, 0].lennard_jones.set_params( epsilon=self.lj_eps, sigma=self.lj_sig, cutoff=self.lj_cut, shift="auto") self.system.integrator.run(0) f_old = np.copy(self.system.part[:].f) # No-op, because gamma = 0. self.system.integrator.set_steepest_descent( f_max=0.0, gamma=0.0, max_displacement=0.001) self.system.integrator.run(1) np.testing.assert_allclose(f_old, np.copy(self.system.part[:].f))
class IntegratorSteepestDescent(ut.TestCase): np.random.seed(42) system = espressomd.System(box_l=[10.0, 10.0, 10.0]) test_rotation = espressomd.has_features(("ROTATION", "DIPOLES")) if test_rotation: from espressomd.constraints import HomogeneousMagneticField box_l = 10.0 density = 0.6 vol = box_l**3 n_part = int(vol * density) lj_eps = 1.0 lj_sig = 1.0 lj_cut = 2**(1 / 6) def setUp(self): self.system.box_l = 3 * [self.box_l] self.system.cell_system.skin = 0.4 self.system.time_step = 0.01 self.system.non_bonded_inter[0, 0].lennard_jones.set_params( epsilon=self.lj_eps, sigma=self.lj_sig, cutoff=self.lj_cut, shift="auto") if self.test_rotation: self.system.constraints.add( self.HomogeneousMagneticField(H=[-0.5, 0, 0])) def tearDown(self): self.system.part.clear() self.system.integrator.set_vv() def test_relaxation_integrator(self): self.system.part.add(pos=np.random.random((self.n_part, 3)) * self.system.box_l) if self.test_rotation: self.system.part[:].dip = np.random.random((self.n_part, 3)) self.system.part[:].dipm = 1 self.system.part[:].rotation = (1, 1, 1) self.assertNotAlmostEqual(self.system.analysis.energy()["total"], 0, places=10) sd_params = {"f_max": 0.0, "gamma": 0.1, "max_displacement": 0.05} self.system.integrator.set_steepest_descent(**sd_params) self.system.integrator.run(500) self.system.constraints.clear() # Check self.assertAlmostEqual(self.system.analysis.energy()["total"], 0, places=10) np.testing.assert_allclose(np.copy(self.system.part[:].f), 0.) if self.test_rotation: np.testing.assert_allclose(np.copy(self.system.part[:].dip), self.n_part * [(-1, 0, 0)], atol=1E-9) def test_integration(self): max_disp = 0.05 self.system.part.add(pos=[0, 0, 0], type=0) self.system.part.add(pos=[0, 0, self.lj_cut - max_disp / 2], type=0) sd_params = {"f_max": 1e-6, "gamma": 0.1, "max_displacement": max_disp} self.system.integrator.set_steepest_descent(**sd_params) # no displacement for 0 steps positions = np.copy(self.system.part[:].pos) steps = self.system.integrator.run(0) np.testing.assert_allclose(np.copy(self.system.part[:].pos), positions) np.testing.assert_allclose(np.copy(self.system.part[:].v), 0.) np.testing.assert_allclose(self.system.part[:].f[:, 0:2], 0.) self.assertAlmostEqual(np.sum(self.system.part[:].f[:, 2]), 0.) self.assertLess(self.system.part[:].f[0, 2], -1.) self.assertEqual(steps, 0) # displacement = max_disp for 1 step positions[:, 2] += [-max_disp, max_disp] steps = self.system.integrator.run(1) np.testing.assert_allclose(np.copy(self.system.part[:].pos), positions) np.testing.assert_allclose(np.copy(self.system.part[:].v), 0.) np.testing.assert_allclose(np.copy(self.system.part[:].f), 0.) self.assertEqual(steps, 1) # no displacement after convergence steps = self.system.integrator.run(1) np.testing.assert_allclose(np.copy(self.system.part[:].pos), positions) np.testing.assert_allclose(np.copy(self.system.part[:].v), 0.) np.testing.assert_allclose(np.copy(self.system.part[:].f), 0.) self.assertEqual(steps, 0) # never converges, even when the system is in an energy minimum, # because f_max = 0. sd_params["f_max"] = 0.0 self.system.integrator.set_steepest_descent(**sd_params) steps = self.system.integrator.run(10) np.testing.assert_allclose(np.copy(self.system.part[:].pos), positions) np.testing.assert_allclose(np.copy(self.system.part[:].v), 0.) np.testing.assert_allclose(np.copy(self.system.part[:].f), 0.) self.assertEqual(steps, 10) def test_rescaling(self): self.system.part.add(pos=[5., 5., 4.9], type=0) self.system.part.add(pos=[5., 5., 5.1], type=0) self.system.non_bonded_inter[0, 0].lennard_jones.set_params( epsilon=self.lj_eps, sigma=self.lj_sig, cutoff=self.lj_cut, shift="auto") self.system.integrator.run(0) f_old = np.copy(self.system.part[:].f) # No-op, because gamma = 0. sd_params = {"f_max": 0.0, "gamma": 0.0, "max_displacement": 0.001} self.system.integrator.set_steepest_descent(**sd_params) self.system.integrator.run(1) np.testing.assert_allclose(f_old, np.copy(self.system.part[:].f)) def test_integrator_exceptions(self): # invalid parameters should throw exceptions with self.assertRaises(RuntimeError): self.system.integrator.set_steepest_descent(f_max=-1, gamma=1, max_displacement=1) with self.assertRaises(RuntimeError): self.system.integrator.set_steepest_descent(f_max=0, gamma=-1, max_displacement=1) with self.assertRaises(RuntimeError): self.system.integrator.set_steepest_descent(f_max=0, gamma=1, max_displacement=-1) def test_integrator_recovery(self): # the system is still in a valid state after a failure system = self.system sd_params = {"f_max": 0, "gamma": 1, "max_displacement": 0.01} positions_start = np.array([[0, 0, 0], [1., 0, 0]]) positions_ref = np.array([[-0.01, 0, 0], [1.01, 0, 0]]) system.part.add(pos=positions_start) system.integrator.set_steepest_descent(**sd_params) # get the positions after one step with the chosen parameters system.integrator.run(1) positions_ref = np.copy(system.part[:].pos) # resetting the SD integrator with incorrect values doesn't leave the # system in an undefined state (the old parameters aren't overwritten) with self.assertRaises(RuntimeError): system.integrator.set_steepest_descent(f_max=-10, gamma=1, max_displacement=0.01) with self.assertRaises(RuntimeError): system.integrator.set_steepest_descent(f_max=0, gamma=-1, max_displacement=0.01) with self.assertRaises(RuntimeError): system.integrator.set_steepest_descent(f_max=0, gamma=1, max_displacement=-1) # the core state is unchanged system.part[:].pos = positions_start system.integrator.run(1) np.testing.assert_allclose(np.copy(system.part[:].pos), positions_ref) # setting another integrator with incorrect values doesn't leave the # system in an undefined state (the old integrator is still active) if espressomd.has_features("NPT"): with self.assertRaises(RuntimeError): system.integrator.set_isotropic_npt(ext_pressure=1, piston=-1) # the interface state is unchanged state = system.integrator.get_state() self.assertIsInstance(state['integrator'], espressomd.integrate.SteepestDescent) params = state['integrator'].get_params() self.assertEqual(params["f_max"], sd_params["f_max"]) self.assertEqual(params["gamma"], sd_params["gamma"]) self.assertEqual(params["max_displacement"], sd_params["max_displacement"]) # the core state is unchanged system.part[:].pos = positions_start system.integrator.run(1) np.testing.assert_allclose(np.copy(system.part[:].pos), positions_ref) # setting the SD integrator with incorrect values doesn't leave the # system in an undefined state (the old integrator is still active) system.integrator.set_vv() system.part[:].pos = positions_start with self.assertRaises(RuntimeError): system.integrator.set_steepest_descent(f_max=0, gamma=1, max_displacement=-1) # the interface state is unchanged self.assertIsInstance(system.integrator.get_state()['integrator'], espressomd.integrate.VelocityVerlet) # the core state is unchanged system.integrator.run(1) np.testing.assert_allclose( np.copy(system.part[:].pos), positions_start + np.array([[-1.2e-3, 0, 0], [1.2e-3, 0, 0]]))
import espressomd import espressomd.lb import os import numpy as np try: import vtk except ImportError: print("Module \"vtk\" not available, skipping test!") exit() @ut.skipIf(not espressomd.gpu_available() or not espressomd.has_features(["ENGINE", "LB_GPU"]), "Features or gpu not available, skipping test!") class SwimmerTest(ut.TestCase): def prepare(self, S): boxl = 12 tstep = 0.01 S.box_l = [boxl, boxl, boxl] S.cell_system.skin = 0.1 S.time_step = tstep S.part.add(id=0, pos=[6.0, 3.0, 2.0], swimming={ "mode": "pusher", "v_swim": 0.10,
class ScafacosInterface(ut.TestCase): system = espressomd.System(box_l=3 * [5]) system.time_step = 0.01 system.cell_system.skin = 0.5 system.periodicity = [1, 1, 1] def tearDown(self): self.system.part.clear() self.system.actors.clear() def test_available_methods(self): # all methods that are accessible from the ScaFaCoS bridge in ESPResSo scafacos_methods = { "direct", "ewald", "fmm", "memd", "mmm1d", "mmm2d", "p2nfft", "p3m", "pepc", "pp3mg", "vmg", "wolf"} # all methods that were compiled in when building ScaFaCoS available_methods = espressomd.scafacos.available_methods() self.assertGreaterEqual(len(available_methods), 1) for method in available_methods: self.assertIn(method, scafacos_methods) @ut.skipIf(not espressomd.has_features('SCAFACOS') or 'p3m' not in espressomd.scafacos.available_methods(), 'Skipping test: missing ScaFaCoS p3m method') def test_actor_exceptions(self): system = self.system if espressomd.has_features('SCAFACOS_DIPOLES'): with self.assertRaisesRegex(ValueError, "Dipolar prefactor has to be >= 0"): system.actors.add(espressomd.magnetostatics.Scafacos( prefactor=-1, method_name="p3m", method_params={"p3m_cao": 7})) system.actors.clear() with self.assertRaisesRegex(ValueError, "Coulomb prefactor has to be >= 0"): system.actors.add(espressomd.electrostatics.Scafacos( prefactor=-1, method_name="p3m", method_params={"p3m_cao": 7})) system.actors.clear() with self.assertRaisesRegex(ValueError, "method 'impossible' is unknown or not compiled in ScaFaCoS"): system.actors.add(espressomd.electrostatics.Scafacos( prefactor=1, method_name="impossible", method_params={"p3m_cao": 7})) system.actors.clear() with self.assertRaisesRegex(ValueError, "ScaFaCoS methods require at least 1 parameter"): system.actors.add(espressomd.electrostatics.Scafacos( prefactor=1, method_name="p3m", method_params={})) system.actors.clear() @ut.skipIf(not espressomd.has_features('SCAFACOS') or 'p3m' not in espressomd.scafacos.available_methods(), 'Skipping test: missing ScaFaCoS p3m method') def test_actor_coulomb(self): system = self.system system.actors.add(espressomd.electrostatics.Scafacos( prefactor=0.5, method_name="p3m", method_params={ "p3m_r_cut": 1.0, "p3m_alpha": 2.799269, "p3m_grid": 32, "p3m_cao": 7})) actor = system.actors[0] params = actor.get_params() self.assertEqual(params["prefactor"], 0.5) self.assertEqual(params["method_name"], "p3m") self.assertEqual(params["method_params"], {'p3m_cao': '7', 'p3m_r_cut': '1.0', 'p3m_grid': '32', 'p3m_alpha': '2.799269'}) @ut.skipIf(not espressomd.has_features('SCAFACOS_DIPOLES') or 'p2nfft' not in espressomd.scafacos.available_methods(), 'Skipping test: missing ScaFaCoS p2nfft method') def test_actor_dipoles(self): system = self.system method_params = { "p2nfft_verbose_tuning": "0", "pnfft_N": "32,32,32", "pnfft_n": "32,32,32", "pnfft_window_name": "bspline", "pnfft_m": "4", "p2nfft_ignore_tolerance": "1", "pnfft_diff_ik": "0", "p2nfft_r_cut": "11", "p2nfft_alpha": "0.37"} system.actors.add(espressomd.magnetostatics.Scafacos( prefactor=1.2, method_name="p2nfft", method_params=method_params)) actor = system.actors[0] params = actor.get_params() self.assertEqual(params["prefactor"], 1.2) self.assertEqual(params["method_name"], "p2nfft") self.assertEqual(params["method_params"], method_params) def p3m_data(self): system = self.system p3m = espressomd.electrostatics.P3M( prefactor=0.5, accuracy=5e-4, mesh=32, cao=7, r_cut=1.0) system.actors.add(p3m) dp3m = espressomd.magnetostatics.DipolarP3M( prefactor=1.0, accuracy=1e-5, cao=7, mesh=48, r_cut=1.88672, epsilon="metallic") system.actors.add(dp3m) system.integrator.run(0, recalc_forces=True) ref_E_coulomb = system.analysis.energy()["coulomb"] ref_E_dipoles = system.analysis.energy()["dipolar"] ref_forces = np.copy(system.part[:].f) ref_torques = np.copy(system.part[:].torque_lab) system.actors.clear() return (ref_E_coulomb, ref_E_dipoles, ref_forces, ref_torques) def fcs_data(self): system = self.system scafacos_coulomb = espressomd.electrostatics.Scafacos( prefactor=0.5, method_name="p2nfft", method_params={ "p2nfft_verbose_tuning": 0, "pnfft_N": "32,32,32", "pnfft_n": "32,32,32", "tolerance_field": "5e-4", "pnfft_window_name": "bspline", "pnfft_m": "4", "p2nfft_ignore_tolerance": "1", "pnfft_diff_ik": "0", "p2nfft_r_cut": "1.0", "p2nfft_alpha": "2.92"}) system.actors.add(scafacos_coulomb) scafacos_dipoles = espressomd.magnetostatics.Scafacos( prefactor=1.0, method_name="p2nfft", method_params={ "p2nfft_verbose_tuning": 0, "pnfft_N": "32,32,32", "pnfft_n": "32,32,32", "pnfft_window_name": "bspline", "pnfft_m": "4", "p2nfft_ignore_tolerance": "1", "pnfft_diff_ik": "0", "p2nfft_r_cut": "11", "p2nfft_alpha": "0.37"}) system.actors.add(scafacos_dipoles) system.integrator.run(0, recalc_forces=True) ref_E_coulomb = system.analysis.energy()["coulomb"] ref_E_dipoles = system.analysis.energy()["dipolar"] ref_forces = np.copy(system.part[:].f) ref_torques = np.copy(system.part[:].torque_lab) system.actors.clear() return (ref_E_coulomb, ref_E_dipoles, ref_forces, ref_torques) @utx.skipIfMissingFeatures(["LENNARD_JONES", "P3M"]) @ut.skipIf(not espressomd.has_features('SCAFACOS_DIPOLES') or 'p2nfft' not in espressomd.scafacos.available_methods(), 'Skipping test: missing SCAFACOS_DIPOLES or p2nfft method') def test_electrostatics_plus_magnetostatics(self): # check that two instances of ScaFaCoS can be used system = self.system # add particles N = 100 np.random.seed(42) system.part.add(pos=np.random.uniform(0, system.box_l[0], (N, 3)), dip=np.random.uniform(0, 1, (N, 3)), q=np.sign((np.arange(N) % 2) * 2 - 1), rotation=N * [(1, 1, 1)]) # minimize system system.non_bonded_inter[0, 0].lennard_jones.set_params( epsilon=1.0, sigma=1.0, cutoff=2**(1.0 / 6.0), shift="auto") system.integrator.set_steepest_descent( f_max=10, gamma=0.001, max_displacement=0.01) system.integrator.run(100) # compute forces and energies p3m_E_coulomb, p3m_E_dipoles, p3m_forces, p3m_torques = self.p3m_data() fcs_E_coulomb, fcs_E_dipoles, fcs_forces, fcs_torques = self.fcs_data() self.assertAlmostEqual(fcs_E_coulomb, p3m_E_coulomb, delta=1e-4) self.assertAlmostEqual(fcs_E_dipoles, p3m_E_dipoles, delta=1e-4) np.testing.assert_allclose(fcs_forces, p3m_forces, rtol=1e-2) np.testing.assert_allclose(fcs_torques, p3m_torques, rtol=1e-3)
def test_integrator_recovery(self): # the system is still in a valid state after a failure system = self.system sd_params = {"f_max": 0, "gamma": 1, "max_displacement": 0.01} positions_start = np.array([[0, 0, 0], [1., 0, 0]]) positions_ref = np.array([[-0.01, 0, 0], [1.01, 0, 0]]) system.part.add(pos=positions_start) system.integrator.set_steepest_descent(**sd_params) # get the positions after one step with the chosen parameters system.integrator.run(1) positions_ref = np.copy(system.part[:].pos) # resetting the SD integrator with incorrect values doesn't leave the # system in an undefined state (the old parameters aren't overwritten) with self.assertRaises(RuntimeError): system.integrator.set_steepest_descent(f_max=-10, gamma=1, max_displacement=0.01) with self.assertRaises(RuntimeError): system.integrator.set_steepest_descent(f_max=0, gamma=-1, max_displacement=0.01) with self.assertRaises(RuntimeError): system.integrator.set_steepest_descent(f_max=0, gamma=1, max_displacement=-1) # the core state is unchanged system.part[:].pos = positions_start system.integrator.run(1) np.testing.assert_allclose(np.copy(system.part[:].pos), positions_ref) # setting another integrator with incorrect values doesn't leave the # system in an undefined state (the old integrator is still active) if espressomd.has_features("NPT"): with self.assertRaises(RuntimeError): system.integrator.set_isotropic_npt(ext_pressure=1, piston=-1) # the interface state is unchanged state = system.integrator.get_state() self.assertIsInstance(state['integrator'], espressomd.integrate.SteepestDescent) params = state['integrator'].get_params() self.assertEqual(params["f_max"], sd_params["f_max"]) self.assertEqual(params["gamma"], sd_params["gamma"]) self.assertEqual(params["max_displacement"], sd_params["max_displacement"]) # the core state is unchanged system.part[:].pos = positions_start system.integrator.run(1) np.testing.assert_allclose(np.copy(system.part[:].pos), positions_ref) # setting the SD integrator with incorrect values doesn't leave the # system in an undefined state (the old integrator is still active) system.integrator.set_vv() system.part[:].pos = positions_start with self.assertRaises(RuntimeError): system.integrator.set_steepest_descent(f_max=0, gamma=1, max_displacement=-1) # the interface state is unchanged self.assertIsInstance(system.integrator.get_state()['integrator'], espressomd.integrate.VelocityVerlet) # the core state is unchanged system.integrator.run(1) np.testing.assert_allclose( np.copy(system.part[:].pos), positions_start + np.array([[-1.2e-3, 0, 0], [1.2e-3, 0, 0]]))
# GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import unittest as ut import numpy as np import os import espressomd import espressomd.checkpointing import espressomd.electrostatics import espressomd.interactions import espressomd.virtual_sites import espressomd.accumulators import espressomd.observables if espressomd.has_features("LB_BOUNDARIES") or espressomd.has_features("LB_BOUNDARIES_GPU"): from espressomd.lbboundaries import LBBoundary import espressomd.lb import espressomd.electrokinetics from espressomd.shapes import Wall, Sphere modes = {x for mode in set("@TEST_COMBINATION@".upper().split('-')) for x in [mode, mode.split('.')[0]]} # use a box with 3 different dimensions system = espressomd.System(box_l=[12.0, 14.0, 16.0]) system.cell_system.skin = 0.1 system.seed = system.cell_system.get_state()["n_nodes"] * [1234] system.time_step = 0.01 system.min_global_cut = 2.0
from __future__ import print_function import math import unittest as ut import numpy as np from numpy import linalg as la from numpy.random import random, seed import espressomd from espressomd.interactions import * from espressomd.magnetostatics import * from espressomd.analyze import * from tests_common import * from espressomd import assert_features, has_features, missing_features @ut.skipIf(not has_features(["DIPOLAR_BARNES_HUT"]), "Features not available, skipping test!") class BHGPUTest(ut.TestCase): longMessage = True # Handle for espresso system system = espressomd.System(box_l=[1,1,1]) system.seed = system.cell_system.get_state()['n_nodes'] * [1234] np.random.seed(system.seed) def vectorsTheSame(self,a,b): tol = 5E-2 vec_len = la.norm(a - b) rel = 2 * vec_len / (la.norm(a) + la.norm(b)) if rel <= tol: return True else:
class Observables(ut.TestCase): N_PART = 1000 # Handle for espresso system system = espressomd.System(box_l=[10.0, 10.0, 10.0]) system.seed = system.cell_system.get_state()['n_nodes'] * [1234] def setUp(self): if not self.system.part: for i in range(self.N_PART): self.system.part.add(pos=random(3) * 10, v=random(3), id=i) if espressomd.has_features(["MASS"]): self.system.part[i].mass = random() if espressomd.has_features(["DIPOLES"]): self.system.part[i].dip = random(3) if espressomd.has_features(["ROTATION"]): self.system.part[i].omega_lab = random(3) if espressomd.has_features("ELECTROSTATICS"): self.system.part[i].q = (1 if i % 2 == 0 else -1) if espressomd.has_features("VIRTUAL_SITES"): self.system.part[randint(self.N_PART)].virtual = True def generate_test_for_pid_observable( _obs_name, _pprop_name, _agg_type=None): """Generates test cases for observables working on particle id lists. """ pprop_name = _pprop_name obs_name = _obs_name agg_type = _agg_type def func(self): # This code is run at the execution of the generated function. # It will use the state of the variables in the outer function, # which was there, when the outer function was called # Get data from particles id_list = range(self.N_PART) part_data = getattr(self.system.part[id_list], pprop_name) # Reshape and aggregate to linear array if len(part_data.shape) > 1: if (agg_type == "average"): part_data = np.average(part_data, 0) if (agg_type == "sum"): part_data = np.sum(part_data, 0) if (agg_type == 'com'): part_data = calc_com_x(self.system, pprop_name) part_data = part_data.flatten() # Data from observable observable = obs_name(ids=id_list) obs_data = observable.calculate() self.assertEqual(observable.n_values(), len(part_data)) np.testing.assert_array_almost_equal( obs_data, part_data, err_msg="Data did not agree for observable " + str(obs_name) + " and particle property " + pprop_name, decimal=9) return func test_pos = generate_test_for_pid_observable( espressomd.observables.ParticlePositions, "pos") test_v = generate_test_for_pid_observable( espressomd.observables.ParticleVelocities, "v") test_f = generate_test_for_pid_observable( espressomd.observables.ParticleForces, "f") test_com_position = generate_test_for_pid_observable( espressomd.observables.ComPosition, 'pos', 'com') test_com_velocity = generate_test_for_pid_observable( espressomd.observables.ComVelocity, 'v', 'com') test_com_force = generate_test_for_pid_observable( espressomd.observables.ComForce, 'f', 'com') if espressomd.has_features(["DIPOLES"]): test_mag_dip = generate_test_for_pid_observable( espressomd.observables.MagneticDipoleMoment, "dip", "sum") if espressomd.has_features(["ROTATION"]): test_body_angular_velocity = generate_test_for_pid_observable( espressomd.observables.ParticleBodyAngularVelocities, "omega_body") test_lab_angular_velocity = generate_test_for_pid_observable( espressomd.observables.ParticleAngularVelocities, "omega_lab") @utx.skipIfMissingFeatures(['ROTATION']) def test_particle_body_velocities(self): obs = espressomd.observables.ParticleBodyVelocities( ids=range(self.N_PART)) obs_data = obs.calculate() part_data = np.array([p.convert_vector_space_to_body(p.v) for p in self.system.part]) np.testing.assert_array_almost_equal(part_data.flatten(), obs_data, err_msg="Data did not agree for observable ParticleBodyVelocities and particle derived values.", decimal=9) def test_stress_tensor(self): s = self.system.analysis.stress_tensor()["total"].reshape(9) obs_data = np.array(espressomd.observables.StressTensor().calculate()) self.assertEqual( espressomd.observables.StressTensor().n_values(), len(s)) np.testing.assert_array_almost_equal( s, obs_data, err_msg="Stress tensor from analysis and observable did not agree", decimal=9) @utx.skipIfMissingFeatures('ELECTROSTATICS') def test_current(self): obs_data = espressomd.observables.Current( ids=range(self.N_PART)).calculate() part_data = self.system.part[:].q.dot(self.system.part[:].v) self.assertEqual(espressomd.observables.Current( ids=range(self.N_PART)).n_values(), len(part_data.flatten())) np.testing.assert_array_almost_equal( obs_data, part_data, err_msg="Data did not agree for observable 'Current'", decimal=9) @utx.skipIfMissingFeatures('ELECTROSTATICS') def test_dipolemoment(self): obs = espressomd.observables.DipoleMoment(ids=range(self.N_PART)) obs_data = obs.calculate() part_data = self.system.part[:].q.dot(self.system.part[:].pos) self.assertEqual(obs.n_values(), len(part_data.flatten())) np.testing.assert_array_almost_equal( obs_data, part_data, err_msg="Data did not agree for observable 'DipoleMoment'", decimal=9)
import unittest as ut import tests_common import espressomd import espressomd.lb import os import numpy as np try: import vtk except ImportError: print("Module \"vtk\" not available, skipping test!") exit() @ut.skipIf(not espressomd.has_features(["ENGINE", "LB_GPU"]), "Features not available, skipping test!") class SwimmerTest(ut.TestCase): def prepare(self, S): boxl = 12 tstep = 0.01 S.box_l = [boxl, boxl, boxl] S.cell_system.skin = 0.1 S.time_step = tstep S.part.add(id=0, pos=[6.0, 3.0, 2.0], swimming={"mode": "pusher", "v_swim": 0.10, "dipole_length": 1.0, "rotational_friction": 2.0}, quat=[np.sqrt(.5), np.sqrt(.5), 0, 0]) S.part.add(
# use a box with 3 different dimensions system = espressomd.System(box_l=[12.0, 14.0, 16.0]) system.cell_system.skin = 0.1 system.seed = system.cell_system.get_state()["n_nodes"] * [1234] system.time_step = 0.01 system.min_global_cut = 2.0 # create checkpoint folder idx = "mycheckpoint_@TEST_COMBINATION@_@TEST_BINARY@".replace(".", "__") checkpoint = espressomd.checkpointing.Checkpoint( checkpoint_id=idx, checkpoint_path="@CMAKE_CURRENT_BINARY_DIR@") LB_implementation = None if 'LB.CPU' in modes: LB_implementation = espressomd.lb.LBFluid elif espressomd.gpu_available() and espressomd.has_features( 'CUDA') and 'LB.GPU' in modes: LB_implementation = espressomd.lb.LBFluidGPU if LB_implementation: lbf = LB_implementation(agrid=0.5, visc=1.3, dens=1.5, tau=0.01) system.actors.add(lbf) EK_implementation = None if espressomd.gpu_available() and espressomd.has_features( 'ELECTROKINETICS') and 'EK.GPU' in modes: EK_implementation = espressomd.electrokinetics ek = EK_implementation.Electrokinetics(agrid=0.5, lb_density=26.15, viscosity=1.7, friction=0.0, T=1.1, prefactor=0.88,
class CoulombCloudWall(ut.TestCase): """This compares p3m, p3m_gpu, scafacos_p3m and scafacos_p2nfft electrostatic forces and energy against stored data. """ S = espressomd.System(box_l=[1.0, 1.0, 1.0]) S.seed = S.cell_system.get_state()['n_nodes'] * [1234] forces = {} tolerance = 1E-3 # Reference energy from p3m in the tcl test case reference_energy = 148.94229549 def setUp(self): self.S.box_l = (10, 10, 10) self.S.time_step = 0.01 self.S.cell_system.skin = 0.4 # Clear actors that might be left from prev tests if self.S.actors: del self.S.actors[0] self.S.part.clear() data = np.genfromtxt( tests_common.abspath("data/coulomb_cloud_wall_system.data")) # Add particles to system and store reference forces in hash # Input format: id pos q f for particle in data: id = particle[0] pos = particle[1:4] q = particle[4] f = particle[5:] self.S.part.add(id=int(id), pos=pos, q=q) self.forces[id] = f def compare(self, method_name, energy=True, prefactor=None): # Compare forces and energy now in the system to stored ones # Force force_abs_diff = 0. for p in self.S.part: force_abs_diff += np.linalg.norm(p.f / prefactor - self.forces[p.id]) force_abs_diff /= len(self.S.part) print(method_name, "force difference", force_abs_diff) # Energy if energy: energy_abs_diff = abs(self.S.analysis.energy()["total"] / prefactor - self.reference_energy) print(method_name, "energy difference", energy_abs_diff) self.assertLessEqual( energy_abs_diff, self.tolerance, "Absolute energy difference " + str(energy_abs_diff) + " too large for " + method_name) self.assertLessEqual( force_abs_diff, self.tolerance, "Absolute force difference " + str(force_abs_diff) + " too large for method " + method_name) # Tests for individual methods @utx.skipIfMissingFeatures(["P3M"]) def test_p3m_direct_caf(self): """ This checks P3M with using the charge assignment function (window function) directly by setting the `inter` parameter to zero. """ self.S.actors.add( espressomd.electrostatics.P3M(prefactor=3, r_cut=1.001, accuracy=1e-3, mesh=64, cao=7, alpha=2.70746, tune=False, inter=0)) self.S.integrator.run(0) self.compare("p3m", energy=True, prefactor=3) @utx.skipIfMissingFeatures(["P3M"]) def test_p3m_interpolated_caf(self): """ This checks P3M with using an interpolated charge assignment function (window function), which is the default. """ self.S.actors.add( espressomd.electrostatics.P3M(prefactor=3, r_cut=1.001, accuracy=1e-3, mesh=64, cao=7, alpha=2.70746, tune=False)) self.S.integrator.run(0) self.compare("p3m", energy=True, prefactor=3) @utx.skipIfMissingGPU(skip_ci_amd=True) def test_p3m_gpu(self): self.S.actors.add( espressomd.electrostatics.P3MGPU(prefactor=2.2, r_cut=1.001, accuracy=1e-3, mesh=64, cao=7, alpha=2.70746, tune=False)) self.S.integrator.run(0) self.compare("p3m_gpu", energy=False, prefactor=2.2) @ut.skipIf(not espressomd.has_features(["SCAFACOS"]) or 'p3m' not in scafacos.available_methods(), 'Skipping test: missing feature SCAFACOS or p3m method') def test_scafacos_p3m(self): self.S.actors.add( espressomd.electrostatics.Scafacos(prefactor=0.5, method_name="p3m", method_params={ "p3m_r_cut": 1.001, "p3m_grid": 64, "p3m_cao": 7, "p3m_alpha": 2.70746 })) self.S.integrator.run(0) self.compare("scafacos_p3m", energy=True, prefactor=0.5) @ut.skipIf(not espressomd.has_features("SCAFACOS") or 'p2nfft' not in scafacos.available_methods(), 'Skipping test: missing feature SCAFACOS or p2nfft method') def test_scafacos_p2nfft(self): self.S.actors.add( espressomd.electrostatics.Scafacos(prefactor=2.8, method_name="p2nfft", method_params={ "p2nfft_r_cut": 1.001, "tolerance_field": 1E-4 })) self.S.integrator.run(0) self.compare("scafacos_p2nfft", energy=True, prefactor=2.8) def test_zz_deactivation(self): # Is the energy and force 0, if no methods active self.assertEqual(self.S.analysis.energy()["total"], 0.0) self.S.integrator.run(0, recalc_forces=True) for p in self.S.part: self.assertAlmostEqual(np.linalg.norm(p.f), 0, places=11)
# # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import sys import numpy as np import unittest as ut import espressomd import espressomd.observables import espressomd.lb from espressomd import utils import tests_common @ut.skipIf( not ( espressomd.has_features( 'LB') or espressomd.has_features( 'LB_GPU')), "Both LB and LB_GPU not compiled in, can not check functionality.") class TestCylindricalLBObservable(ut.TestCase): """ Testcase for the CylindricalFluxDensityObservable. """ system = espressomd.System(box_l=(10, 10, 10)) system.time_step = 0.01 system.cell_system.skin = 0.4 positions = [] params = { 'ids': range(10),
import sys import numpy as np import unittest as ut import espressomd import espressomd.lb @ut.skipIf(not espressomd.has_features(['LB_GPU']) or espressomd.has_features("SHANCHEN"), "Features not available, skipping test!") class LBGPUViscous(ut.TestCase): system = espressomd.System(box_l=[10.0]*3) system.time_step = 0.01 system.cell_system.skin = 0.4 agrid = 0.5 dens = 0.85 viscosity = 30.0 friction = 3.5 def test_viscous_coupling(self): self.system.thermostat.turn_off() self.system.actors.clear() self.system.part.clear() v_part = np.array([1, 2, 3]) v_fluid = np.array([1.2, 4.3, 0.2]) self.lbf = espressomd.lb.LBFluidGPU(visc=self.viscosity, dens=self.dens, agrid=self.agrid,tau=self.system.time_step, fric=self.friction) self.system.actors.add(self.lbf) self.system.part.add(pos=[0.5 * self.agrid] * 3, v=v_part, fix=[1, 1, 1]) self.lbf[0, 0, 0].velocity = v_fluid self.system.integrator.run(1) np.testing.assert_allclose(np.copy(self.system.part[0].f), -self.friction * (v_part - v_fluid), atol=1e-3)
class TestCylindricalLBObservable(ut.TestCase): """ Testcase for the CylindricalFluxDensityObservable. """ system = espressomd.System(box_l=(10, 10, 10)) system.time_step = 0.01 system.cell_system.skin = 0.4 positions = [] params = { 'ids': range(10), 'center': [5.0, 5.0, 5.0], # center of the histogram 'axis': 'y', 'n_r_bins': 10, # number of bins in r 'n_phi_bins': 2, # -*- in phi 'n_z_bins': 2, # -*- in z 'min_r': 0.0, 'min_phi': -np.pi, 'min_z': -5.0, 'max_r': 5.0, 'max_phi': np.pi, 'max_z': 5.0, } @classmethod def setUpClass(self): if espressomd.has_features('LB_GPU'): self.lbf_gpu = espressomd.lb.LBFluidGPU( agrid=1.0, dens=1.0, visc=1.0, tau=0.01) if espressomd.has_features('LB'): self.lbf_cpu = espressomd.lb.LBFluid( agrid=1.0, dens=1.0, visc=1.0, tau=0.01) def tearDown(self): del self.positions[:] def swap_axis(self, arr, axis): if axis == 'x': arr = np.dot(tests_common.rotation_matrix( [0, 1, 0], np.pi / 2.0), arr) elif axis == 'y': arr = np.dot(tests_common.rotation_matrix( [1, 0, 0], -np.pi / 2.0), arr) return arr def swap_axis_inverse(self, arr, axis): if axis == 'x': arr = np.dot(tests_common.rotation_matrix( [0, 1, 0], -np.pi / 2.0), arr) elif axis == 'y': arr = np.dot(tests_common.rotation_matrix( [1, 0, 0], np.pi / 2.0), arr) return arr def pol_coords(self): positions = np.zeros((len(self.positions), 3)) for i, p in enumerate(self.positions): tmp = p - np.array(self.params['center']) tmp = self.swap_axis_inverse(tmp, self.params['axis']) positions[i, :] = tests_common.transform_pos_from_cartesian_to_polar_coordinates( tmp) return positions def set_particles(self): self.system.part.clear() self.system.part.add(pos=self.positions) def set_fluid_velocity(self): del self.positions[:] # Choose the cartesian velocities such that each particle gets the same # v_r, v_phi and v_z, respectively. self.v_r = .75 self.v_phi = 2.5 self.v_z = 1.5 node_positions = np.arange(-4.5, 5.0, 1.0) for i, value in enumerate(node_positions): position = np.array( [node_positions[i], node_positions[i], node_positions[i]]) v_y = (position[0] * np.sqrt(position[0]**2.0 + position[1]**2.0) * self.v_phi + position[1] * self.v_r) / np.sqrt(position[0]**2.0 + position[1]**2.0) v_x = ( self.v_r * np.sqrt(position[0]**2.0 + position[1]**2.0) - position[1] * v_y) / position[0] velocity = np.array([v_x, v_y, self.v_z]) velocity = self.swap_axis(velocity, self.params['axis']) position = self.swap_axis(position, self.params['axis']) position += np.array(self.params['center']) self.positions.append(position) self.lbf[np.array(position, dtype=int)].velocity = velocity def set_fluid_velocity_on_all_nodes(self): self.system.part.clear() self.v_r = .75 self.v_phi = 2.5 self.v_z = 1.5 node_positions = np.arange(-4.5, 5.0, 1.0) for x in node_positions: for y in node_positions: for z in node_positions: position = np.array([x, y, z]) v_y = (position[0] * np.sqrt(position[0]**2.0 + position[1]**2.0) * self.v_phi + position[1] * self.v_r) / np.sqrt(position[0]**2.0 + position[1]**2.0) v_x = ( self.v_r * np.sqrt(position[0]**2.0 + position[1]**2.0) - position[1] * v_y) / position[0] velocity = np.array([v_x, v_y, self.v_z]) velocity = self.swap_axis(velocity, self.params['axis']) position = self.swap_axis(position, self.params['axis']) position += np.array(self.params['center']) self.positions.append(position) self.lbf[np.array(position, dtype=int)].velocity = velocity def normalize_with_bin_volume(self, histogram): bin_volume = tests_common.get_cylindrical_bin_volume( self.params['n_r_bins'], self.params['n_phi_bins'], self.params['n_z_bins'], self.params['min_r'], self.params['max_r'], self.params['min_phi'], self.params['max_phi'], self.params['min_z'], self.params['max_z']) # Normalization for i in range(self.params['n_r_bins']): histogram[i, :, :] /= bin_volume[i] return histogram def LB_fluxdensity_profile_test(self): self.set_fluid_velocity() self.set_particles() # Set up the Observable. p = espressomd.observables.CylindricalLBFluxDensityProfileAtParticlePositions( **self.params) core_hist = np.array( p.calculate()).reshape( self.params['n_r_bins'], self.params['n_phi_bins'], self.params['n_z_bins'], 3) core_hist_v_r = core_hist[:, :, :, 0] core_hist_v_phi = core_hist[:, :, :, 1] core_hist_v_z = core_hist[:, :, :, 2] self.pol_positions = self.pol_coords() np_hist, _ = np.histogramdd( self.pol_positions, bins=(self.params['n_r_bins'], self.params[ 'n_phi_bins'], self.params[ 'n_z_bins']), range=[(self.params['min_r'], self.params['max_r']), (self.params['min_phi'], self.params['max_phi']), (self.params['min_z'], self.params['max_z'])]) np_hist = self.normalize_with_bin_volume(np_hist) np.testing.assert_array_almost_equal(np_hist * self.v_r, core_hist_v_r) np.testing.assert_array_almost_equal( np_hist * self.v_phi, core_hist_v_phi) np.testing.assert_array_almost_equal(np_hist * self.v_z, core_hist_v_z) self.assertEqual(p.n_values(), len(np_hist.flatten()) * 3) def LB_velocity_profile_at_particle_positions_test(self): self.set_fluid_velocity() self.set_particles() # Set up the Observable. p = espressomd.observables.CylindricalLBVelocityProfileAtParticlePositions( **self.params) core_hist = np.array( p.calculate()).reshape( self.params['n_r_bins'], self.params['n_phi_bins'], self.params['n_z_bins'], 3) core_hist_v_r = core_hist[:, :, :, 0] core_hist_v_phi = core_hist[:, :, :, 1] core_hist_v_z = core_hist[:, :, :, 2] self.pol_positions = self.pol_coords() np_hist, _ = np.histogramdd( self.pol_positions, bins=(self.params['n_r_bins'], self.params[ 'n_phi_bins'], self.params[ 'n_z_bins']), range=[(self.params['min_r'], self.params['max_r']), (self.params['min_phi'], self.params['max_phi']), (self.params['min_z'], self.params['max_z'])]) for x in np.nditer(np_hist, op_flags=['readwrite']): if x[...] > 0.0: x[...] /= x[...] np.testing.assert_array_almost_equal(np_hist * self.v_r, core_hist_v_r) np.testing.assert_array_almost_equal( np_hist * self.v_phi, core_hist_v_phi) np.testing.assert_array_almost_equal(np_hist * self.v_z, core_hist_v_z) self.assertEqual(p.n_values(), len(np_hist.flatten()) * 3) def LB_velocity_profile_test(self): self.set_fluid_velocity_on_all_nodes() # Set up the Observable. local_params = self.params.copy() del local_params['ids'] local_params['sampling_delta_x'] = 1 local_params['sampling_delta_y'] = 1 local_params['sampling_delta_z'] = 1 local_params['sampling_offset_x'] = 0.5 local_params['sampling_offset_y'] = 0.5 local_params['sampling_offset_z'] = 0.5 local_params['allow_empty_bins'] = True p = espressomd.observables.CylindricalLBVelocityProfile( **local_params) core_hist = np.array( p.calculate()).reshape( self.params['n_r_bins'], self.params['n_phi_bins'], self.params['n_z_bins'], 3) core_hist_v_r = core_hist[:, :, :, 0] core_hist_v_phi = core_hist[:, :, :, 1] core_hist_v_z = core_hist[:, :, :, 2] self.pol_positions = self.pol_coords() np_hist, _ = np.histogramdd( self.pol_positions, bins=(self.params['n_r_bins'], self.params[ 'n_phi_bins'], self.params[ 'n_z_bins']), range=[(self.params['min_r'], self.params['max_r']), (self.params['min_phi'], self.params['max_phi']), (self.params['min_z'], self.params['max_z'])]) for x in np.nditer(np_hist, op_flags=['readwrite']): if x[...] > 0.0: x[...] /= x[...] np.testing.assert_array_almost_equal(np_hist * self.v_r, core_hist_v_r) np.testing.assert_array_almost_equal( np_hist * self.v_phi, core_hist_v_phi) np.testing.assert_array_almost_equal(np_hist * self.v_z, core_hist_v_z) self.assertEqual(p.n_values(), len(np_hist.flatten()) * 3) @ut.skipIf(not espressomd.has_features('LB'), "LB not compiled in, skipping test.") def test_x_axis_cpu(self): self.params['axis'] = 'x' self.lbf = self.lbf_cpu self.system.actors.add(self.lbf) self.LB_fluxdensity_profile_test() self.LB_velocity_profile_test() self.LB_velocity_profile_at_particle_positions_test() self.system.actors.remove(self.lbf) @ut.skipIf(not espressomd.has_features('LB'), "LB not compiled in, skipping test.") def test_y_axis_cpu(self): self.params['axis'] = 'y' self.lbf = self.lbf_cpu self.system.actors.add(self.lbf) self.LB_fluxdensity_profile_test() self.LB_velocity_profile_test() self.LB_velocity_profile_at_particle_positions_test() self.system.actors.remove(self.lbf) @ut.skipIf(not espressomd.has_features('LB'), "LB not compiled in, skipping test.") def test_z_axis_cpu(self): self.params['axis'] = 'z' self.lbf = self.lbf_cpu self.system.actors.add(self.lbf) self.LB_fluxdensity_profile_test() self.LB_velocity_profile_test() self.LB_velocity_profile_at_particle_positions_test() self.system.actors.remove(self.lbf) @ut.skipIf(not espressomd.gpu_available() or not espressomd.has_features('LB_GPU'), "LB_GPU not compiled in, skipping test.") def test_x_axis_gpu(self): self.params['axis'] = 'x' self.lbf = self.lbf_gpu self.system.actors.add(self.lbf) self.LB_fluxdensity_profile_test() self.LB_velocity_profile_at_particle_positions_test() self.LB_velocity_profile_test() self.system.actors.remove(self.lbf) @ut.skipIf(not espressomd.gpu_available() or not espressomd.has_features('LB_GPU'), "LB_GPU not compiled in or no gpu present, skipping test.") def test_y_axis_gpu(self): self.params['axis'] = 'y' self.lbf = self.lbf_gpu self.system.actors.add(self.lbf) self.LB_fluxdensity_profile_test() self.LB_velocity_profile_at_particle_positions_test() self.LB_velocity_profile_test() self.system.actors.remove(self.lbf) @ut.skipIf(not espressomd.gpu_available() or not espressomd.has_features('LB_GPU'), "LB_GPU not compiled in, skipping test.") def test_z_axis_gpu(self): self.params['axis'] = 'z' self.lbf = self.lbf_gpu self.system.actors.add(self.lbf) self.LB_fluxdensity_profile_test() self.LB_velocity_profile_at_particle_positions_test() self.LB_velocity_profile_test() self.system.actors.remove(self.lbf)
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # # Tests particle property setters/getters from __future__ import print_function import unittest as ut import espressomd import numpy as np from time import time from itertools import product @ut.skipIf(not espressomd.has_features("DPD"), "Skipped because feature is disabled") class DPDThermostat(ut.TestCase): """Tests the velocity distribution created by the dpd thermostat against the single component Maxwell distribution.""" s = espressomd.System(box_l=[1.0, 1.0, 1.0]) s.box_l = 3 * [10] s.time_step = 0.01 s.cell_system.skin = 0.4 def setUp(self): self.s.seed = range(self.s.cell_system.get_state()["n_nodes"]) np.random.seed(16) def tearDown(self):
# # ESPResSo is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from __future__ import print_function import sys import unittest as ut import espressomd from espressomd.interactions import HarmonicBond @ut.skipIf(not espressomd.has_features("LENNARD_JONES"), "Skipped because LENNARD_JONES turned off.") class AnalyzeEnergy(ut.TestCase): system = espressomd.System(box_l=[1.0, 1.0, 1.0]) harmonic = HarmonicBond(r_0=0.0, k=3) @classmethod def setUpClass(self): box_l = 20 self.system.box_l = [box_l, box_l, box_l] self.system.cell_system.skin = 0.4 self.system.time_step = 0.01 self.system.non_bonded_inter[0, 0].lennard_jones.set_params( epsilon=1.0, sigma=1.0, cutoff=2**(1. / 6.), shift="auto") self.system.non_bonded_inter[0, 1].lennard_jones.set_params(
# # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. import unittest as ut import numpy as np import os import espressomd import espressomd.checkpointing import espressomd.electrostatics import espressomd.interactions import espressomd.virtual_sites import espressomd.accumulators import espressomd.observables from espressomd import has_features if any(has_features(i) for i in ["LB_BOUNDARIES", "LB_BOUNDARIES_GPU"]): from espressomd.lbboundaries import LBBoundary import espressomd.lb import espressomd.electrokinetics from espressomd.shapes import Wall, Sphere from espressomd import constraints modes = { x for mode in set("@TEST_COMBINATION@".upper().split('-')) for x in [mode, mode.split('.')[0]] } # use a box with 3 different dimensions system = espressomd.System(box_l=[12.0, 14.0, 16.0]) system.cell_system.skin = 0.1
class AnalyzeEnergy(ut.TestCase): system = espressomd.System(box_l=[1.0, 1.0, 1.0]) harmonic = HarmonicBond(r_0=0.0, k=3) @classmethod def setUpClass(self): box_l = 20 self.system.box_l = [box_l, box_l, box_l] self.system.cell_system.skin = 0.4 self.system.time_step = 0.01 self.system.non_bonded_inter[0, 0].lennard_jones.set_params( epsilon=1.0, sigma=1.0, cutoff=2**(1. / 6.), shift="auto") self.system.non_bonded_inter[0, 1].lennard_jones.set_params( epsilon=1.0, sigma=1.0, cutoff=2**(1. / 6.), shift="auto") self.system.non_bonded_inter[1, 1].lennard_jones.set_params( epsilon=1.0, sigma=1.0, cutoff=2**(1. / 6.), shift="auto") self.system.thermostat.set_langevin(kT=0., gamma=1., seed=42) self.system.bonded_inter.add(self.harmonic) def setUp(self): self.system.part.clear() self.system.part.add(id=0, pos=[1, 2, 2], type=0) self.system.part.add(id=1, pos=[5, 2, 2], type=0) def test_kinetic(self): self.system.part[0].pos = [1, 2, 2] self.system.part[1].pos = [5, 2, 2] self.system.part[0].v = [3, 4, 5] self.system.part[1].v = [0, 0, 0] # single moving particle energy = self.system.analysis.energy() self.assertAlmostEqual(energy["total"], 25., delta=1e-7) self.assertAlmostEqual(energy["kinetic"], 25., delta=1e-7) self.assertAlmostEqual(energy["bonded"], 0., delta=1e-7) self.assertAlmostEqual(energy["non_bonded"], 0., delta=1e-7) # two moving particles self.system.part[1].v = [3, 4, 5] energy = self.system.analysis.energy() self.assertAlmostEqual(energy["total"], 50., delta=1e-7) self.assertAlmostEqual(energy["kinetic"], 50., delta=1e-7) self.assertAlmostEqual(energy["bonded"], 0., delta=1e-7) self.assertAlmostEqual(energy["non_bonded"], 0., delta=1e-7) self.system.part[0].v = [0, 0, 0] self.system.part[1].v = [0, 0, 0] def test_non_bonded(self): self.system.part[0].pos = [1, 2, 2] self.system.part[1].pos = [2, 2, 2] energy = self.system.analysis.energy() self.assertAlmostEqual(energy["total"], 1., delta=1e-5) self.assertAlmostEqual(energy["kinetic"], 0., delta=1e-7) self.assertAlmostEqual(energy["bonded"], 0., delta=1e-7) self.assertAlmostEqual(energy["non_bonded"], 1., delta=1e-7) # add another pair of particles self.system.part.add(id=2, pos=[3, 2, 2], type=1) self.system.part.add(id=3, pos=[4, 2, 2], type=1) energy = self.system.analysis.energy() self.assertAlmostEqual(energy["total"], 3., delta=1e-7) self.assertAlmostEqual(energy["kinetic"], 0., delta=1e-7) self.assertAlmostEqual(energy["bonded"], 0., delta=1e-7) self.assertAlmostEqual(energy["non_bonded"], 3., delta=1e-7) self.assertAlmostEqual( energy["non_bonded", 0, 1], energy["non_bonded", 1, 0], delta=1e-7) self.assertAlmostEqual(energy["non_bonded", 0, 0] + energy["non_bonded", 0, 1] + energy["non_bonded", 1, 1], energy["total"], delta=1e-7) self.system.part[2].remove() self.system.part[3].remove() def test_bonded(self): self.system.part[0].pos = [1, 2, 2] self.system.part[1].pos = [3, 2, 2] self.system.part[0].v = [0, 0, 0] self.system.part[1].v = [0, 0, 0] # single bond self.system.part[0].add_bond((self.harmonic, 1)) energy = self.system.analysis.energy() self.assertAlmostEqual(energy["total"], 6, delta=1e-7) self.assertAlmostEqual(energy["kinetic"], 0., delta=1e-7) self.assertAlmostEqual(energy["bonded"], 6, delta=1e-7) self.assertAlmostEqual(energy["non_bonded"], 0., delta=1e-7) # two bonds self.system.part[1].add_bond((self.harmonic, 0)) energy = self.system.analysis.energy() self.assertAlmostEqual(energy["total"], 12, delta=1e-7) self.assertAlmostEqual(energy["kinetic"], 0., delta=1e-7) self.assertAlmostEqual(energy["bonded"], 12, delta=1e-7) self.assertAlmostEqual(energy["non_bonded"], 0., delta=1e-7) # bonds deleted self.system.part[0].delete_all_bonds() self.system.part[1].delete_all_bonds() energy = self.system.analysis.energy() self.assertAlmostEqual(energy["total"], 0., delta=1e-7) self.assertAlmostEqual(energy["kinetic"], 0., delta=1e-7) self.assertAlmostEqual(energy["bonded"], 0, delta=1e-7) self.assertAlmostEqual(energy["non_bonded"], 0., delta=1e-7) def test_all(self): self.system.part[0].pos = [1, 2, 2] self.system.part[1].pos = [2, 2, 2] self.system.part[0].v = [3, 4, 5] self.system.part[1].v = [3, 4, 5] # single bond self.system.part[0].add_bond((self.harmonic, 1)) energy = self.system.analysis.energy() self.assertAlmostEqual(energy["total"], 50. + 3. / 2. + 1., delta=1e-7) self.assertAlmostEqual(energy["kinetic"], 50., delta=1e-7) self.assertAlmostEqual(energy["bonded"], 3. / 2., delta=1e-7) self.assertAlmostEqual(energy["non_bonded"], 1., delta=1e-7) # two bonds self.system.part[1].add_bond((self.harmonic, 0)) energy = self.system.analysis.energy() self.assertAlmostEqual(energy["total"], 50. + 3 + 1., delta=1e-7) self.assertAlmostEqual(energy["kinetic"], 50., delta=1e-7) self.assertAlmostEqual(energy["bonded"], 3., delta=1e-7) self.assertAlmostEqual(energy["non_bonded"], 1., delta=1e-7) # add another pair of particles self.system.part.add(id=2, pos=[1, 5, 5], type=1) self.system.part.add(id=3, pos=[2, 5, 5], type=1) energy = self.system.analysis.energy() self.assertAlmostEqual( energy["total"], 50. + 3 + (1. + 1.), delta=1e-7) self.assertAlmostEqual(energy["kinetic"], 50., delta=1e-7) self.assertAlmostEqual(energy["bonded"], 3., delta=1e-7) self.assertAlmostEqual(energy["non_bonded"], 1. + 1., delta=1e-7) self.system.part[2].remove() self.system.part[3].remove() self.system.part[0].delete_all_bonds() features = ["ELECTROSTATICS", "P3M"] @ut.skipIf(not espressomd.has_features(*features), "Missing features: " + ", ".join(espressomd.missing_features(*features))) def test_electrostatics(self): from espressomd import electrostatics self.system.part[0].pos = [1, 2, 2] self.system.part[1].pos = [3, 2, 2] self.system.part[0].q = 1 self.system.part[1].q = -1 p3m = electrostatics.P3M(prefactor=1.0, accuracy=9.910945054074526e-08, mesh=[22, 22, 22], cao=7, r_cut=8.906249999999998, alpha=0.387611049779351, tune=False) self.system.actors.add(p3m) # did not verify if this is correct, but looks pretty good (close to # 1/2) u_p3m = -0.501062398379 energy = self.system.analysis.energy() self.assertAlmostEqual(energy["total"], u_p3m, delta=1e-5) self.assertAlmostEqual(energy["kinetic"], 0., delta=1e-7) self.assertAlmostEqual(energy["bonded"], 0., delta=1e-7) self.assertAlmostEqual(energy["non_bonded"], 0, delta=1e-7) self.assertAlmostEqual(energy["coulomb"], u_p3m, delta=1e-7) self.system.part[0].q = 0 self.system.part[1].q = 0 self.system.part[0].pos = [1, 2, 2] self.system.part[1].pos = [5, 2, 2]
class Exclusions(ut.TestCase): s = espressomd.System(box_l=[1.0, 1.0, 1.0]) s.seed = s.cell_system.get_state()['n_nodes'] * [1234] def setUp(self): self.s.part.clear() self.s.box_l = 3 * [10] self.s.cell_system.skin = 0.4 self.s.time_step = 0.01 def test_add_remove(self): self.s.part.add(id=0, pos=[0, 0, 0]) self.s.part.add(id=1, pos=[0, 0, 0]) self.s.part.add(id=2, pos=[0, 0, 0]) self.s.part[0].add_exclusion(1) self.s.part[0].add_exclusion(2) self.assertTrue( (self.s.part[0].exclusions == [1, 2]).all() ) self.s.part[0].delete_exclusion(1) self.assertEqual(self.s.part[0].exclusions, [2]) self.s.part[0].delete_exclusion(2) self.assertEqual( list(self.s.part[0].exclusions), []) def test_transfer(self): self.s.part.add(id=0, pos=[0, 0, 0], v=[1., 1., 1]) self.s.part.add(id=1, pos=[0, 0, 0]) self.s.part.add(id=2, pos=[0, 0, 0]) self.s.part.add(id=3, pos=[0, 0, 0]) self.s.part[0].exclusions = [1, 2, 3] for i in range(15): self.s.integrator.run(100) self.assertTrue( (self.s.part[0].exclusions == [1, 2, 3]).all() ) @ut.skipIf(not espressomd.has_features(['LENNARD_JONES']), "Skipping test") def test_particle_property(self): self.s.non_bonded_inter[0, 0].lennard_jones.set_params( epsilon=1., sigma=2., cutoff=1.5, shift=0.0) self.s.part.add(id=0, pos=[0, 0, 0], type=0) self.s.part.add(id=1, pos=[1, 0, 0], type=0) pair_energy = self.s.analysis.energy()['total'] self.assertGreater(pair_energy, 0.) pair_pressure = self.s.analysis.pressure()['total'] self.assertGreater(pair_pressure, 0.) self.s.integrator.run(0) pair_force = self.s.part[0].f[0] self.assertGreater(abs(pair_force), 0.) self.assertAlmostEqual(self.s.part[1].f[0], -pair_force, places=7) self.s.part.add(id=2, pos=[2, 0, 0], type=0) self.s.integrator.run(0) self.assertAlmostEqual(self.s.analysis.energy()[ 'total'], 2 * pair_energy) self.assertAlmostEqual(self.s.analysis.pressure()[ 'total'], 2 * pair_pressure) self.assertAlmostEqual(self.s.part[2].f[0], -pair_force, places=7) self.s.part[1].exclusions = [0, 2] self.s.integrator.run(0) self.assertAlmostEqual(self.s.analysis.energy()['total'], 0) self.assertAlmostEqual(self.s.analysis.pressure()['total'], 0) self.assertAlmostEqual(self.s.part[0].f[0], 0, places=7) self.assertAlmostEqual(self.s.part[1].f[0], 0, places=7) self.assertAlmostEqual(self.s.part[2].f[0], 0, places=7) self.s.part[1].exclusions = [0] self.assertAlmostEqual(self.s.analysis.energy()['total'], pair_energy) self.assertAlmostEqual(self.s.analysis.pressure()['total'], pair_pressure) self.s.integrator.run(0) self.assertAlmostEqual(self.s.part[0].f[0], 0, places=7) self.assertAlmostEqual(self.s.part[1].f[0], pair_force, places=7) self.assertAlmostEqual(self.s.part[2].f[0], -pair_force, places=7) self.s.part[1].exclusions = [] self.assertAlmostEqual(self.s.analysis.energy()[ 'total'], 2 * pair_energy) self.assertAlmostEqual(self.s.analysis.pressure()[ 'total'], 2 * pair_pressure) self.s.integrator.run(0) self.assertAlmostEqual(self.s.part[0].f[0], pair_force, places=7) self.assertAlmostEqual(self.s.part[1].f[0], 0, places=7) self.assertAlmostEqual(self.s.part[2].f[0], -pair_force, places=7) self.s.part[1].exclusions = [0] self.assertAlmostEqual(self.s.analysis.energy()['total'], pair_energy) self.assertAlmostEqual(self.s.analysis.pressure()['total'], pair_pressure) self.s.integrator.run(0) self.assertAlmostEqual(self.s.part[0].f[0], 0, places=7) self.assertAlmostEqual(self.s.part[1].f[0], pair_force, places=7) self.assertAlmostEqual(self.s.part[2].f[0], -pair_force, places=7) @ut.skipIf(not espressomd.has_features(['P3M']), "Skipping test") def test_electrostatics_not_excluded(self): from espressomd.electrostatics import P3M self.s.part.add(id=0, pos=[0, 0, 0], type=0, q=+1.) self.s.part.add(id=1, pos=[1, 0, 0], type=0, q=-1.) # Small alpha means large short-range contribution self.s.actors.add(P3M(prefactor=1, r_cut=3.0, accuracy=1e-3, mesh=32, cao=7, alpha=0.1, tune=False)) # Only short-range part of the coulomb energy pair_energy = self.s.analysis.energy()[('coulomb', 0)] self.assertGreater(abs(pair_energy), 0.) self.s.integrator.run(0) pair_force = self.s.part[0].f[0] self.assertGreater(abs(pair_force), 0.) self.assertAlmostEqual(self.s.part[1].f[0], -pair_force, places=7) pair_pressure = self.s.analysis.pressure()[('coulomb', 0)] self.assertGreater(abs(pair_pressure), 0.) self.s.part[0].exclusions = [1] # Force and energy should not be changed by the exclusion self.s.integrator.run(0) self.assertAlmostEqual(self.s.part[0].f[0], pair_force, places=7) self.assertAlmostEqual(self.s.part[1].f[0], -pair_force, places=7) self.assertAlmostEqual(self.s.analysis.energy()[('coulomb', 0)], pair_energy, places=7) self.assertAlmostEqual(self.s.analysis.pressure()[('coulomb', 0)], pair_pressure, places=7)
# but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # from __future__ import print_function import unittest as ut import espressomd import numpy as np from espressomd import electrostatics from tests_common import * @ut.skipIf(not espressomd.has_features(["ELECTROSTATICS"]), "Features not available, skipping test!") class ElectrostaticInteractionsTests(ut.TestCase): # Handle to espresso system system = espressomd.System(box_l=[1.0, 1.0, 1.0]) def setUp(self): self.system.box_l = [20, 20, 20] self.system.time_step = 0.01 if not self.system.part.exists(0): self.system.part.add(id=0, pos=(1.0, 2.0, 2.0), q=1) if not self.system.part.exists(1): self.system.part.add(id=1, pos=(3.0, 2.0, 2.0), q=-1) print("ut.TestCase setUp")
# along with this program. If not, see <http://www.gnu.org/licenses/>. # This tests the scafacos p2nfft dipolar calculations by matching against # reference data from direct summation. In 2d, reference data from the mdlc # test case is used from __future__ import print_function import espressomd import espressomd.magnetostatics as magnetostatics import espressomd.magnetostatic_extensions as magnetostatic_extensions import numpy as np import unittest as ut from tests_common import abspath @ut.skipIf(not espressomd.has_features(["DIPOLES", "FFTW"]), "Features not available, skipping test!") class Dipolar_p3m_mdlc_p2nfft(ut.TestCase): """Tests mdlc (2d) as well as dipolar p3m and dipolar p2nfft (3d) against stored data. Validity of the stored data: 2d: as long as this test AND the scafacos_dipolar_1d_2d test passes, we are save. 3d: As long as the independently written p3m and p2nfft agree, we are save. """ s = espressomd.System(box_l=[1.0, 1.0, 1.0]) s.seed = s.cell_system.get_state()['n_nodes'] * [1234] s.time_step = 0.01 s.cell_system.skin = .4 s.periodicity = 1, 1, 1 s.thermostat.turn_off() def test_mdlc(self):
class ElectrostaticInteractionsTests(ut.TestCase): # Handle to espresso system system = espressomd.System(box_l=[1.0, 1.0, 1.0]) def setUp(self): self.system.box_l = [20, 20, 20] self.system.time_step = 0.01 if not self.system.part.exists(0): self.system.part.add(id=0, pos=(1.0, 2.0, 2.0), q=1) if not self.system.part.exists(1): self.system.part.add(id=1, pos=(3.0, 2.0, 2.0), q=-1) print("ut.TestCase setUp") def calc_dh_potential(self, r, df_params): kT = 1.0 q1 = self.system.part[0].q q2 = self.system.part[1].q u = np.zeros_like(r) # r<r_cut i = np.where(r < df_params['r_cut'])[0] u[i] = df_params['prefactor'] * kT * q1 * \ q2 * np.exp(-df_params['kappa'] * r[i]) / r[i] return u @ut.skipIf(not espressomd.has_features(["P3M"]), "Features not available, skipping test!") def test_p3m(self): self.system.part[0].pos = [1.0, 2.0, 2.0] self.system.part[1].pos = [3.0, 2.0, 2.0] # results, p3m_energy = -0.501062398379 p3m_force = 2.48921612e-01 test_P3M = generate_test_for_class( self.system, electrostatics.P3M, dict(accuracy=9.910945054074526e-08, mesh=[22, 22, 22], cao=7, r_cut=8.906249999999998, alpha=0.387611049779351, tune=False)) p3m = espressomd.electrostatics.P3M(prefactor=1.0, accuracy=9.910945054074526e-08, mesh=[22, 22, 22], cao=7, r_cut=8.906249999999998, alpha=0.387611049779351, tune=False) self.system.actors.add(p3m) self.assertAlmostEqual(self.system.analysis.energy()['coulomb'], p3m_energy) # need to update forces self.system.integrator.run(0) np.testing.assert_allclose(np.copy(self.system.part[0].f), [p3m_force, 0, 0], atol=1E-5) np.testing.assert_allclose(np.copy(self.system.part[1].f), [-p3m_force, 0, 0], atol=1E-10) self.system.actors.remove(p3m) def test_dh(self): dh_params = dict(prefactor=1.0, kappa=2.0, r_cut=2.0) test_DH = generate_test_for_class(self.system, electrostatics.DH, dh_params) dh = espressomd.electrostatics.DH(prefactor=dh_params['prefactor'], kappa=dh_params['kappa'], r_cut=dh_params['r_cut']) self.system.actors.add(dh) dr = 0.001 r = np.arange(.5, 1.01 * dh_params['r_cut'], dr) u_dh = self.calc_dh_potential(r, dh_params) f_dh = -np.gradient(u_dh, dr) # zero the discontinuity, and re-evaluate the derivitive as a backwards # difference i_cut = np.argmin((dh_params['r_cut'] - r)**2) f_dh[i_cut] = 0 f_dh[i_cut - 1] = (u_dh[i_cut - 2] - u_dh[i_cut - 1]) / dr u_dh_core = np.zeros_like(r) f_dh_core = np.zeros_like(r) # need to update forces for i, ri in enumerate(r): self.system.part[1].pos = self.system.part[0].pos + [ri, 0, 0] self.system.integrator.run(0) u_dh_core[i] = self.system.analysis.energy()['coulomb'] f_dh_core[i] = self.system.part[0].f[0] np.testing.assert_allclose(u_dh_core, u_dh, atol=1e-7) np.testing.assert_allclose(f_dh_core, -f_dh, atol=1e-2) self.system.actors.remove(dh)
def check_rng(self, per_particle_gamma=False): """Test for RNG consistency.""" kT = 1.1 gamma = 3.5 def reset_particle(): self.system.part.clear() p = system.part.add(pos=[0, 0, 0]) if espressomd.has_features("ROTATION"): p.rotation = [1, 1, 1] if per_particle_gamma: assert espressomd.has_features("THERMOSTAT_PER_PARTICLE") if espressomd.has_features("PARTICLE_ANISOTROPY"): p.gamma = 3 * [gamma / 2] else: p.gamma = gamma / 2 if espressomd.has_features("ROTATION"): p.gamma_rot = p.gamma * 1.5 return p system = self.system system.time_step = 0.01 system.thermostat.set_langevin(kT=kT, gamma=gamma, seed=41) system.integrator.set_vv() # run(0) does not increase the philox counter and should give the same # force p = reset_particle() system.integrator.run(0, recalc_forces=True) force0 = np.copy(p.f) if espressomd.has_features("ROTATION"): torque0 = np.copy(p.torque_lab) system.integrator.run(0, recalc_forces=True) force1 = np.copy(p.f) np.testing.assert_almost_equal(force0, force1) if espressomd.has_features("ROTATION"): torque1 = np.copy(p.torque_lab) np.testing.assert_almost_equal(torque0, torque1) # run(1) should give a different force p = reset_particle() system.integrator.run(1) force2 = np.copy(p.f) self.assertTrue(np.all(np.not_equal(force1, force2))) if espressomd.has_features("ROTATION"): torque2 = np.copy(p.torque_lab) self.assertTrue(np.all(np.not_equal(torque1, torque2))) # Different seed should give a different force with same counter state # force2: langevin.rng_counter() = 1, langevin.rng_seed() = 41 # force3: langevin.rng_counter() = 1, langevin.rng_seed() = 42 p = reset_particle() system.integrator.run(0, recalc_forces=True) force2 = np.copy(p.f) if espressomd.has_features("ROTATION"): torque2 = np.copy(p.torque_lab) system.thermostat.set_langevin(kT=kT, gamma=gamma, seed=42) system.integrator.run(0, recalc_forces=True) force3 = np.copy(p.f) self.assertTrue(np.all(np.not_equal(force2, force3))) if espressomd.has_features("ROTATION"): torque3 = np.copy(p.torque_lab) self.assertTrue(np.all(np.not_equal(torque2, torque3))) # Same seed should not give the same force with different counter state p = reset_particle() system.thermostat.set_langevin(kT=kT, gamma=gamma, seed=42) system.integrator.run(1) force4 = np.copy(p.f) self.assertTrue(np.all(np.not_equal(force3, force4))) if espressomd.has_features("ROTATION"): torque4 = np.copy(p.torque_lab) self.assertTrue(np.all(np.not_equal(torque3, torque4))) # Seed offset should not give the same force with a lag # force4: langevin.rng_counter() = 2, langevin.rng_seed() = 42 # force5: langevin.rng_counter() = 3, langevin.rng_seed() = 41 reset_particle() system.thermostat.set_langevin(kT=kT, gamma=gamma, seed=41) system.integrator.run(1) p = reset_particle() system.integrator.run(0, recalc_forces=True) force5 = np.copy(p.f) self.assertTrue(np.all(np.not_equal(force4, force5))) if espressomd.has_features("ROTATION"): torque5 = np.copy(p.torque_lab) self.assertTrue(np.all(np.not_equal(torque4, torque5)))
# (at your option) any later version. # # ESPResSo is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # # Tests particle property setters/getters import unittest as ut import espressomd import numpy as np if espressomd.has_features("ELECTROSTATICS", "PARTIAL_PERIODIC"): from espressomd.electrostatics import MMM1D @ut.skipIf(not espressomd.has_features("ELECTROSTATICS", "PARTIAL_PERIODIC"),"Skipped because of feature turned off.") class ElectrostaticInteractionsTests(ut.TestCase): # Handle to espresso system system = espressomd.System(box_l=[1.0, 1.0, 1.0]) def paramsMatch(self, inParams, outParams): """Check, if the parameters set and gotten back match. Only check keys present in inParams. """ for k in inParams.keys(): if k not in outParams: print(k, "missing from returned parameters")