def test_foo(trajf): # Create a System object from a LIGGGHTS dump file. They keyword 'Particles' is mandatory, since it instructs # System to create an object of type 'Particles' which can be assessed from the instantiated System object. Sys = analysis.System(Particles=trajf) # Go to last frame Sys.goto(-1) assert Sys.frame == 30 # Create a reference to Sys.Particles Particles = Sys.Particles # Any changes made to Particles is reflected in Sys.Particles. To avoid that, a hard copy of Particles should be # created instead: Particles = Sys.Particles.copy() len_parts = len(Particles) assert len_parts > 0 nparts = 0 # Looping over Particles yields a Particles class of length 1 for part in Particles: nparts += len(part) assert nparts == len_parts # Slice Particles into a new class containing the 1st 10 particles Slice = Particles[:10] assert len(Slice) == 10 # Slice Particles into a new class containing particles 1, 2, and 10 Slice = Particles[[1, 2, 10]] assert len(Slice) == 3 # Slice Particles into a new class containing the 1st 10 particles and the last 10 particles Slice = Particles[:10] + Particles[-10:] # More sophisticated slicing can be done with 1 or boolean expressions. For example: # Create a Particles class containing particles smaller than 25% of the mean particle diameter SmallParts = Particles[Particles.radius <= Particles.radius.mean() * 0.25] assert len(SmallParts) == 0 # Create a Particles class containing particles in the positive xy plane SmallParts = Particles[(Particles.y >= 0) & (Particles.x >= 0)] assert len(SmallParts) > 0
def test_foo(trajf): # Create a granular object from a LIGGGHTS dump file Sys = analysis.System(Particles=trajf, units="si") # Go to last frame Sys.goto(-1) # Switch to micro unit system Sys.units("micro") # Compute the radial distribution function g, r, _ = Sys.Particles.computeRDF() assert r.max() > 4.0 # Construct a class for nearest neighbor searching Neigh = analysis.equilibrium.Neighbors(Sys.Particles) # Extract coordination number per particle coon = Neigh.coon
import scipy.spatial from PyGran import analysis from numpy import arange, array import os Gran = analysis.System(Particles='traj.dump') # Go to last frame Gran.goto(-1) # Create a new class containing particles between z=0 and z=1e-3 Particles = Gran.Particles Particles = Particles[Particles.z <= 1e-3 & Particles.z >= 0] # Set image resolution and size resol = 1.24e-6 # microns/pixel size = (512, 512) for i, z in enumerate(arange(0, Particles.z.max() + resol, resol)): zmin, zmax = z, z + resol output = 'output/poured{}.bmp'.format(i) analysis.imaging.slice(Particles, zmin, zmax, 'z', size, resol, output)
from PyGran import analysis import matplotlib.pylab as plt # Create a granular object from a LIGGGHTS dump file Sys = analysis.System( Particles='/home/levnon/Desktop/flow/output/traj/traj*.dump', units='micro') # Go to last frame Sys.goto(-1) # Compute the radial distribution function g, r, _ = Sys.Particles.rdf() # Plot rdf vs radial distance plt.plot(r, g) plt.show() # Construct a class for nearest neighbor searching Neigh = analysis.equilibrium.Neighbors(Sys.Particles) # Extract coordination number per particle coon = Neigh.coon
# Basics # ====== # In this tutorial, a general overview of the Particles object in PyGran is presented. Class instantiation, manipulation (slicing, indexing, etc.), and basic propreties are covered. # Import the analysis module from PyGran from PyGran import analysis import sys # Read particle trajectory input filename pfname = sys.argv[1] # Create a System object from a LIGGGHTS dump file. They keyword 'Particles' is mandatory, since it instructs # System to create an object of type 'Particles' which can be assessed from the instantiated System object. Sys = analysis.System(Particles=pfname) # go to last frame Sys.goto(-1) # Particles Class # =============== # The code below shows how a Particles class and its dynamic attributes can be accessed. # Create a reference to Sys.Particles Particles = Sys.Particles # Any changes made to Particles is reflected in Sys.Particles. to avoid that, a hard copy of Particles should be # created instead: Particles = Sys.Particles.copy() # The length of Particles is the number of particles contained in this class print("Number of particles stored = ", len(Particles))
from PyGran import analysis import matplotlib.pylab as plt from numpy import array # Create a PyGran System from a dump file (default si units) System = analysis.System(Particles="traj*.dump") # Timestep used in simulation (s) dt = 1e-6 # Skip empty frames System.skip() # Extract bed height + timesteps data = array([[ts * dt, System.Particles.z.max()] for ts in System]) # Plot bed height (mm) vs time (ms) plt.plot(data[:, 0] * 1e3, data[:, 1] * 1e3, "-o") plt.xlabel("Time (ms)") plt.ylabel("Height (mm)") plt.grid(linestyle=":") plt.show()
from PyGran import analysis import matplotlib.pylab as plt # Create a granular object from a LIGGGHTS dump file Sys = analysis.System(Particles="traj*.dump", units="micro") # Go to last frame Sys.goto(-1) # Compute the radial distribution function g, r, _ = Sys.Particles.rdf() # Plot rdf vs radial distance plt.plot(r, g) plt.show() # Construct a class for nearest neighbor searching Neigh = analysis.equilibrium.Neighbors(Sys.Particles) # Extract coordination number per particle coon = Neigh.coon
from PyGran import analysis from scipy.linalg import norm from numpy import array, sqrt import matplotlib.pylab as plt # Create a mesh trajectory file for the bed inlet, outlet, and internal files inlet, outlet, inter = "CFD/inlet_*.vtk", "CFD/outlet_*.vtk", "CFD/inter_*.vtk" inlet_args = {"vtk_type": "poly", "avgCellData": True, "skip": 4} outlet_args = {"vtk_type": "poly", "avgCellData": True, "skip": 4} inter_args = {"avgCellData": True, "skip": 4} Meshes = (inlet, inlet_args), (outlet, outlet_args), (inter, inter_args) Bed = analysis.System(Particles="DEM/particles_*.dump", Mesh=Meshes) # Extract the mesh SubSystems from Bed Inlet, Outlet, Inter = Bed.Mesh # Compute bed height (along the z-direction) bed_height = Outlet.Points[:, -1].max() - Inlet.Points[:, -1].min() # bed_height = array([Bed.Particles.z.max() for ts in Bed]) # Compute the pressure drop as a time series press_drop = [Inlet.cells.p - Outlet.cells.p for ts in Bed] # Compute the inlet velocity as a time series ivel = [norm(Inlet.cells.U) for ts in Bed] # Compute the fluid velocity fvel = [norm(Inter.cells.U) for ts in Bed] # Compute the void fraction as a time series
from PyGran import analysis import matplotlib.pylab as plt # Create a granular object from a LIGGGHTS dump file Sys = analysis.System(Particles='traj*.dump', units='micro') # Go to last frame Sys.goto(-1) # Compute the radial distribution function g, r, _ = Sys.Particles.rdf() # Plot rdf vs radial distance plt.plot(r, g) plt.show() # Construct a class for nearest neighbor searching Neigh = analysis.equilibrium.Neighbors(Sys.Particles) # Extract coordination number per particle coon = Neigh.coon
from PyGran import analysis import matplotlib.pylab as plt from numpy import array # Create a PyGran System from a dump file (default si units) System = analysis.System(Particles='traj*.dump') # Timestep used in simulation (s) dt = 1e-6 # Skip empty frames System.skip() # Extract bed height + timesteps data = array([[ts * dt, System.Particles.z.max()] for ts in System]) # Plot bed height (mm) vs time (ms) plt.plot(data[:, 0] * 1e3, data[:, 1] * 1e3, '-o') plt.xlabel('Time (ms)') plt.ylabel('Height (mm)') plt.grid(linestyle=':') plt.show()
from PyGran import analysis import os class CoarseParticles(analysis.Particles): def __init__(self, **args): super().__init__(**args) if 'scale' in args and 'percent' in args: self.scale(args['scale'], ('radius', )) CG = analysis.equilibrium.Neighbors(self).filter( percent=args['percent']) self.__init__(CoarseParticles=CG) if __name__ == '__main__': Traj = analysis.System(CoarseParticles='traj.dump', scale=3, percent=10.0, module='coarseGrained') Traj.CoarseParticles.write('CG.dump')
import scipy.spatial from PyGran import analysis from numpy import arange, array import os Gran = analysis.System(Particles="traj.dump") # Go to last frame Gran.goto(-1) # Create a new class containing particles between z=0 and z=1e-3 Particles = Gran.Particles Particles = Particles[Particles.z <= 1e-3 & Particles.z >= 0] # Set image resolution and size resol = 1.24e-6 # microns/pixel size = (512, 512) for i, z in enumerate(arange(0, Particles.z.max() + resol, resol)): zmin, zmax = z, z + resol output = "output/poured{}.bmp".format(i) analysis.imaging.slice(Particles, zmin, zmax, "z", size, resol, output)
from PyGran import analysis import os class CoarseParticles(analysis.Particles): def __init__(self, **args): super().__init__(**args) if "scale" in args and "percent" in args: self.scale(args["scale"], ("radius", )) CG = analysis.equilibrium.Neighbors(self).filter( percent=args["percent"]) self.__init__(CoarseParticles=CG) if __name__ == "__main__": Traj = analysis.System(CoarseParticles="traj.dump", scale=3, percent=10.0, module="coarseGrained") Traj.CoarseParticles.write("CG.dump")