def test_advection(self): self.reset_lb(ext_force_density=[0.1, 0, 0]) # System setup system = self.system box_lw = self.box_lw box_height = self.box_height system.virtual_sites = VirtualSitesInertialessTracers() # Establish steady state flow field system.part.add(id=0, pos=(0, 5.5, 5.5), virtual=True) system.integrator.run(400) system.part[0].pos = (0, 5.5, 5.5) system.time = 0 # Perform integration for i in range(3): system.integrator.run(100) # compute expected position X = self.lbf.get_interpolated_velocity( system.part[0].pos)[0] * system.time self.assertAlmostEqual(system.part[0].pos[0] / X - 1, 0, delta=0.005)
def test_triel(self): system = self.system system.virtual_sites = VirtualSitesInertialessTracers() system.thermostat.set_langevin(kT=0, gamma=1, seed=1) # Add particles: 0-2 are not bonded, 3-5 are bonded non_bound = system.part.add(pos=[[4, 4, 4], [4, 4, 5], [4, 5, 5]]) p3 = system.part.add(pos=[1, 4, 4]) p4 = system.part.add(pos=[1, 4, 5]) p5 = system.part.add(pos=[1, 5, 5]) # Add triel for 3-5 tri = espressomd.interactions.IBM_Triel( ind1=p3.id, ind2=p4.id, ind3=p5.id, elasticLaw="Skalak", k1=15, k2=0, maxDist=2.4) system.bonded_inter.add(tri) p3.add_bond((tri, p4, p5)) system.part[:].pos = system.part[:].pos + np.array(( (0, 0, 0), (1, -.2, .3), (1, 1, 1), (0, 0, 0), (1, -.2, .3), (1, 1, 1))) distorted_pos = np.copy(non_bound.pos) system.integrator.run(110) dist1bound = system.distance(p3, p4) dist2bound = system.distance(p3, p5) # check bonded particles. Distance should restore to initial config self.assertAlmostEqual(dist1bound, 1, delta=0.05) self.assertAlmostEqual(dist2bound, np.sqrt(2), delta=0.05) # check not bonded particles. Positions should still be distorted np.testing.assert_allclose(np.copy(non_bound.pos), distorted_pos)
def test_advection(self): # System setup system = self.system box_lw = self.box_lw box_height = self.box_height system.virtual_sites = VirtualSitesInertialessTracers() self.lbf.set_params(ext_force_density=(0.1, 0., 0.)) # Establish steady state flow field system.part.add(id=0, pos=(0, 5.5, 5.5), virtual=1) system.integrator.run(400) # # system.part[0].pos = (0, 5.5, 5.5) system.time = 0 ## Perform integration print("time, actual position, expected position") for i in range(3): system.integrator.run(100) # compute expected position X = self.lbf.get_interpolated_velocity( system.part[0].pos)[0] * system.time print(system.time, system.part[0].pos[0], X, system.part[0].pos[0] - X) self.assertAlmostEqual(system.part[0].pos[0] / X - 1, 0, delta=0.005)
def test_aa_method_switching(self): # Virtual sites should be disabled by default self.assertIsInstance(self.system.virtual_sites, VirtualSitesOff) # Switch implementation self.system.virtual_sites = VirtualSitesInertialessTracers() self.assertIsInstance(self.system.virtual_sites, VirtualSitesInertialessTracers)
def test_aa_method_switching(self): # Virtual sites should be disabled by default self.assertTrue(isinstance(self.system.virtual_sites, VirtualSitesOff)) # Switch implementation self.system.virtual_sites = VirtualSitesInertialessTracers() self.assertTrue( isinstance(self.system.virtual_sites, VirtualSitesInertialessTracers)) self.assertEqual(self.system.virtual_sites.have_velocity, True)
def test_tribend(self): # two triangles with bending interaction # move nodes, should relax back system = self.system system.virtual_sites = VirtualSitesInertialessTracers() system.thermostat.set_langevin(kT=0, gamma=10, seed=1) # Add four particles p0 = system.part.add(pos=[5, 5, 5]) p1 = system.part.add(pos=[5, 5, 6]) p2 = system.part.add(pos=[5, 6, 6]) p3 = system.part.add(pos=[5, 6, 5]) # Add first triel, weak modulus tri1 = espressomd.interactions.IBM_Triel(ind1=p0.id, ind2=p1.id, ind3=p2.id, elasticLaw="Skalak", k1=0.1, k2=0, maxDist=2.4) system.bonded_inter.add(tri1) p0.add_bond((tri1, p1, p2)) # Add second triel, strong modulus tri2 = espressomd.interactions.IBM_Triel(ind1=p0.id, ind2=p2.id, ind3=p3.id, elasticLaw="Skalak", k1=10, k2=0, maxDist=2.4) system.bonded_inter.add(tri2) p0.add_bond((tri2, p2, p3)) # Add bending tribend = espressomd.interactions.IBM_Tribend(ind1=p0.id, ind2=p1.id, ind3=p2.id, ind4=p3.id, kb=1, refShape="Initial") system.bonded_inter.add(tribend) p0.add_bond((tribend, p1, p2, p3)) # twist system.part[:].pos = system.part[:].pos + np.random.random((4, 3)) # Perform integration system.integrator.run(200) angle = self.compute_dihedral_angle(p0.pos, p1.pos, p2.pos, p3.pos) self.assertLess(angle, 2E-2)
def test_zz_without_lb(self): """Check behaviour without lb. Ignore non-virtual particles, complain on virutal ones. """ system = self.system system.virtual_sites = VirtualSitesInertialessTracers() system.actors.clear() system.part.clear() p = system.part.add(pos=(0, 0, 0)) system.integrator.run(1) p.virtual = 1 with (self.assertRaises(Exception)): system.integrator.run(1)
def test_tribend(self): self.system.actors.clear() # two triangles with bending interaction # move nodes, should relax back system = self.system system.virtual_sites = VirtualSitesInertialessTracers() system.part.clear() # Add four particles system.part.add(id=0, pos=[5, 5, 5], virtual=1) system.part.add(id=1, pos=[5, 5, 6], virtual=1) system.part.add(id=2, pos=[5, 6, 6], virtual=1) system.part.add(id=3, pos=[5, 6, 5], virtual=1) # Add first triel, weak modulus from espressomd.interactions import IBM_Triel tri1 = IBM_Triel( ind1=0, ind2=1, ind3=2, elasticLaw="Skalak", k1=0.1, k2=0, maxDist=2.4) system.bonded_inter.add(tri1) system.part[0].add_bond((tri1, 1, 2)) # Add second triel tri2 = IBM_Triel( ind1=0, ind2=2, ind3=3, elasticLaw="Skalak", k1=10, k2=0, maxDist=2.4) system.bonded_inter.add(tri2) system.part[0].add_bond((tri2, 2, 3)) # Add bending from espressomd.interactions import IBM_Tribend tribend = IBM_Tribend( ind1=0, ind2=1, ind3=2, ind4=3, kb=1, refShape="Initial") system.bonded_inter.add(tribend) system.part[0].add_bond((tribend, 1, 2, 3)) # twist system.part[1].pos = [5.2, 5, 6] self.reset_lb() # Perform integration last_angle = self.compute_angle() for i in range(6): system.integrator.run(430) angle = self.compute_angle() self.assertLess(angle, last_angle) last_angle = angle self.assertLess(angle, 0.03)
def test_advection(self): self.reset_lb(ext_force_density=[0.1, 0, 0]) # System setup system = self.system system.virtual_sites = VirtualSitesInertialessTracers() # Establish steady state flow field p = system.part.add(pos=(0, 5.5, 5.5), virtual=True) system.integrator.run(400) p.pos = (0, 5.5, 5.5) system.time = 0 # Perform integration for _ in range(2): system.integrator.run(100) # compute expected position dist = self.lbf.get_interpolated_velocity(p.pos)[0] * system.time self.assertAlmostEqual(p.pos[0] / dist, 1, delta=0.005)
def test_advection(self): # System setup system = self.s system.virtual_sites = VirtualSitesInertialessTracers() system.time_step = 0.02 system.cell_system.skin = 0.1 box_height = 16. box_lw = 16 system.box_l = box_lw, box_lw, box_height lbf = lb.LBFluidGPU(agrid=1, dens=1, visc=2, tau=system.time_step, fric=1) system.actors.add(lbf) system.thermostat.set_lb(kT=0) # Setup boundaries walls = [lbboundaries.LBBoundary() for k in range(2)] walls[0].set_params(shape=shapes.Wall(normal=[0, 0, 1], dist=0.5)) walls[1].set_params( shape=shapes.Wall(normal=[0, 0, -1], dist=-box_height - 0.5)) for wall in walls: system.lbboundaries.add(wall) # Establish steady state flow field system.part.add(id=0, pos=(0, 5.5, 5.5), virtual=0, ext_force=(10, 0, 0)) for i in range(100): last_t = system.time last_x = system.part[0].pos system.integrator.run(500) print(system.part[0].v, (system.part[0].pos - last_x) / (system.time - last_t))
def test_triel(self): self.system.actors.clear() system = self.system system.virtual_sites = VirtualSitesInertialessTracers() system.virtual_sites = VirtualSitesInertialessTracers() system.part.clear() # Add particles: 0-2 are non-bonded, 3-5 are weakly bonded, 6-8 are # strongly bonded system.part.add(id=0, pos=[5, 5, 5], virtual=True) system.part.add(id=1, pos=[5, 5, 6], virtual=True) system.part.add(id=2, pos=[5, 6, 6], virtual=True) system.part.add(id=3, pos=[2, 5, 5], virtual=True) system.part.add(id=4, pos=[2, 5, 6], virtual=True) system.part.add(id=5, pos=[2, 6, 6], virtual=True) system.part.add(id=6, pos=[4, 7, 7], virtual=True) system.part.add(id=7, pos=[4, 7, 8], virtual=True) system.part.add(id=8, pos=[4, 8, 8], virtual=True) # Add triel, weak modulus for 3-5 from espressomd.interactions import IBM_Triel triWeak = IBM_Triel(ind1=3, ind2=4, ind3=5, elasticLaw="Skalak", k1=5, k2=0, maxDist=2.4) system.bonded_inter.add(triWeak) system.part[3].add_bond((triWeak, 4, 5)) # Add triel, strong modulus for 6-8 triStrong = IBM_Triel(ind1=6, ind2=7, ind3=8, elasticLaw="Skalak", k1=15, k2=0, maxDist=2.4) system.bonded_inter.add(triStrong) system.part[6].add_bond((triStrong, 7, 8)) self.reset_lb(ext_force_density=[0.1, 0, 0]) # Perform integration system.integrator.run(4500) # For the cpu variant, check particle velocities if isinstance(self.lbf, lb.LBFluid): # as opposed to LBFluidGPU for p in system.part: np.testing.assert_allclose( np.copy(p.v), np.copy(self.lbf.get_interpolated_velocity(p.pos)), atol=2E-2) # get new shapes dist1non = np.linalg.norm( np.array(system.part[1].pos - system.part[0].pos)) dist2non = np.linalg.norm( np.array(system.part[2].pos - system.part[0].pos)) dist1weak = np.linalg.norm( np.array(system.part[3].pos - system.part[4].pos)) dist2weak = np.linalg.norm( np.array(system.part[3].pos - system.part[5].pos)) dist1strong = np.linalg.norm( np.array(system.part[6].pos - system.part[7].pos)) dist2strong = np.linalg.norm( np.array(system.part[6].pos - system.part[8].pos)) print("** Distances: non-bonded, weak, strong, expected") print( str(dist1non) + " " + str(dist1weak) + " " + str(dist1strong) + " 1") print( str(dist2non) + " " + str(dist2weak) + " " + str(dist2strong) + " 1.414") # test: # non-bonded should move apart by the flow (control group) # weakly-bonded should stretch somewhat # strongly-bonded should basically not stretch self.assertGreater(dist1non, 1.5) self.assertAlmostEqual(dist1weak, 1, delta=0.2) self.assertAlmostEqual(dist1strong, 1, delta=0.04) self.assertGreater(dist2non, 2) self.assertAlmostEqual(dist2weak, np.sqrt(2), delta=0.3) self.assertAlmostEqual(dist2strong, np.sqrt(2), delta=0.1)
def test_tribend(self): # two triangles with bending interaction # move nodes, should relax back system = self.system system.virtual_sites = VirtualSitesInertialessTracers() self.lbf.set_params(ext_force_density=(0.0, 0., 0.)) self.stop_fluid() system.part.clear() ## Add four particles system.part.add(id=0, pos=[5, 5, 5], virtual=1) system.part.add(id=1, pos=[5, 5, 6], virtual=1) system.part.add(id=2, pos=[5, 6, 6], virtual=1) system.part.add(id=3, pos=[5, 6, 5], virtual=1) ## Add first triel, weak modulus from espressomd.interactions import IBM_Triel tri1 = IBM_Triel(ind1=0, ind2=1, ind3=2, elasticLaw="Skalak", k1=0.1, k2=0, maxDist=2.4) system.bonded_inter.add(tri1) system.part[0].add_bond((tri1, 1, 2)) ## Add second triel tri2 = IBM_Triel(ind1=0, ind2=2, ind3=3, elasticLaw="Skalak", k1=10, k2=0, maxDist=2.4) system.bonded_inter.add(tri2) system.part[0].add_bond((tri2, 2, 3)) ## Add bending from espressomd.interactions import IBM_Tribend tribend = IBM_Tribend(ind1=0, ind2=1, ind3=2, ind4=3, kb=1, refShape="Initial") system.bonded_inter.add(tribend) system.part[0].add_bond((tribend, 1, 2, 3)) ## output before print("Angle before twisting: " + str(self.compute_angle())) ## twist system.part[1].pos = [5.2, 5, 6] ## output after print("Angle after twisting: " + str(self.compute_angle())) ## Perform integrat[ion last_angle = self.compute_angle() for i in range(8): system.integrator.run(500) angle = self.compute_angle() print("Angle after relaxation: ", angle) self.assertLess(angle, last_angle) last_angle = angle self.assertLess(angle, 0.03)
""" import espressomd required_features = ["LB_BOUNDARIES", "VIRTUAL_SITES_INERTIALESS_TRACERS"] espressomd.assert_features(required_features) from espressomd import System, lb, shapes, lbboundaries import numpy as np from espressomd.virtual_sites import VirtualSitesInertialessTracers # System setup boxZ = 20 system = System(box_l=(20, 20, boxZ)) system.time_step = 1 / 6. system.cell_system.skin = 0.1 system.virtual_sites = VirtualSitesInertialessTracers() print("Parallelization: " + str(system.cell_system.node_grid)) force = 0.001 from addSoft import AddSoft k1 = 0.1 k2 = 1 AddSoft(system, 10, 10, 10, k1, k2) ## case without bending and volCons #outputDir = "outputPure" ## case with bending from addBending import AddBending kb = 1 AddBending(system, kb)
def test_volcons(self): '''Check volume conservation forces on a simple mesh (cube).''' system = self.system system.virtual_sites = VirtualSitesInertialessTracers() system.thermostat.set_langevin(kT=0, gamma=1, seed=1) # Place particles on a cube. positions = list(itertools.product((0, 1), repeat=3)) positions = positions[:4] + positions[6:] + positions[4:6] positions = np.array(positions) - 0.5 mesh_center_ref = np.copy(system.box_l) / 2. system.part.add(pos=positions + mesh_center_ref, virtual=8 * [True]) # Divide the cube. All triangle normals must point inside the mesh. # Use the right hand rule to determine the order of the indices. triangles = [(0, 1, 2), (1, 3, 2), (2, 3, 4), (3, 5, 4), (4, 5, 6), (5, 7, 6), (6, 7, 0), (7, 1, 0), (0, 2, 4), (0, 4, 6), (1, 5, 3), (1, 7, 5)] # Add triangle bonds that don't contribute to the force (infinite # elasticity). These bonds are needed to calculate the mesh volume. for id1, id2, id3 in triangles: bond = espressomd.interactions.IBM_Triel( ind1=id3, ind2=id2, ind3=id1, elasticLaw="Skalak", k1=0., k2=0., maxDist=3) system.bonded_inter.add(bond) system.part[id1].add_bond((bond, id2, id3)) # Add volume conservation force. volCons = espressomd.interactions.IBM_VolCons(softID=15, kappaV=1.) system.bonded_inter.add(volCons) for p in system.part: p.add_bond((volCons,)) # Run the integrator to initialize the mesh reference volume. system.integrator.run(0, recalc_forces=True) self.assertAlmostEqual(volCons.current_volume(), 1., delta=1e-10) # The restorative force is zero at the moment. np.testing.assert_almost_equal(np.copy(self.system.part[:].f), 0.) # Double the cube dimensions. The volume increases by a factor of 8. system.part[:].pos = 2. * positions + mesh_center_ref system.integrator.run(0, recalc_forces=True) self.assertAlmostEqual(volCons.current_volume(), 8., delta=1e-10) # Reference forces for that particular mesh geometry. ref_forces = 1.75 * np.array( [(1, 2, 2), (2, 1, -2), (2, -1, 1), (1, -2, -1), (-1, -2, 2), (-2, -1, -2), (-2, 1, 1), (-1, 2, -1)]) np.testing.assert_almost_equal( np.copy(self.system.part[:].f), ref_forces) # IBM doesn't implement energy and pressure kernels. energy = self.system.analysis.energy() pressure = self.system.analysis.pressure() self.assertAlmostEqual(energy['bonded'], 0., delta=1e-10) self.assertAlmostEqual(pressure['bonded'], 0., delta=1e-10) # Add unthermalized LB. system.thermostat.turn_off() lbf = espressomd.lb.LBFluid( kT=0.0, agrid=2, dens=1, visc=1.8, tau=system.time_step) system.actors.add(lbf) system.thermostat.set_lb(LB_fluid=lbf, act_on_virtual=False, gamma=1) # Check the cube is shrinking. The geometrical center shouldn't move. volume_diff_ref = 5.805e-4 # warmup system.integrator.run(80) # sampling previous_volume = volCons.current_volume() for _ in range(10): system.integrator.run(20) current_volume = volCons.current_volume() volume_diff = previous_volume - current_volume self.assertLess(current_volume, previous_volume) self.assertAlmostEqual(volume_diff, volume_diff_ref, places=6) previous_volume = current_volume mesh_center = np.mean(self.system.part[:].pos, axis=0) np.testing.assert_allclose(mesh_center, mesh_center_ref, rtol=1e-3) # Halve the cube dimensions. The volume decreases by a factor of 8. system.part[:].pos = 0.5 * positions + mesh_center_ref system.integrator.run(0, recalc_forces=True) self.assertAlmostEqual(volCons.current_volume(), 1. / 8., delta=1e-10) # Check the cube is expanding. The geometrical center shouldn't move. volume_diff_ref = 6.6066e-7 # warmup system.integrator.run(80) # sampling previous_volume = volCons.current_volume() for _ in range(10): system.integrator.run(20) current_volume = volCons.current_volume() volume_diff = current_volume - previous_volume self.assertGreater(current_volume, previous_volume) self.assertAlmostEqual(volume_diff, volume_diff_ref, places=7) previous_volume = current_volume mesh_center = np.mean(self.system.part[:].pos, axis=0) np.testing.assert_allclose(mesh_center, mesh_center_ref, rtol=1e-3)