def test_picker_linear_3d(tmpdir): """Test vtk picker in 3D.""" pos = ((0.5, 0.5, 0.5), (0.25, 0.75, 0.25)) err = numpy.array((1.0e-8, 1.0e-8, 1.0e-8)) fname = tmpdir.join('linear3D.vtu').strpath print(fname) def vel(pos): """ Fluid velocity""" return numpy.array((pos[0], pos[1], pos[2])) def pres(pos): """ Fluid pressure""" return pos[0] IO.make_unstructured_grid(MESH3D, vel, pres, 0.0, fname) system = System.System(temporal_cache=temp_cache('linear3D.vtu', tmpdir.strpath)) part = Particles.Particle((0, 0), system=system) for point in pos: fluid_velocity, grad_p = part.picker(point, 0.0) assert all(abs(fluid_velocity - vel(point)) < err) assert all(grad_p == numpy.array((1.0, 0.0, 0.0)))
def test_make_unstructured_grid(tmpdir): """ Test the make_unstructured_grid routine.""" mesh = IO.GmshMesh() mesh.read("/".join((DATA_DIR, 'Structured.msh'))) print("/".join((DATA_DIR, 'Structured.msh'))) num = len(mesh.nodes) vel = numpy.zeros((num, 3)) pres = numpy.zeros((num, )) time = 0 ugrid = IO.make_unstructured_grid( mesh, vel, pres, time, outfile=tmpdir.join('Structured.vtu').strpath) assert num > 0 assert ugrid.GetNumberOfPoints() == num assert ugrid.GetNumberOfCells() == len(mesh.elements) assert filecmp.cmpfiles(DATA_DIR, tmpdir.strpath, 'Structured.vtu') ugrid = IO.make_unstructured_grid( mesh, lambda x: (0, 0, 0), lambda x: 0, time, outfile=tmpdir.join('Structured.vtu').strpath) assert ugrid.GetNumberOfPoints() == num assert ugrid.GetNumberOfCells() == len(mesh.elements) assert filecmp.cmpfiles(DATA_DIR, tmpdir.strpath, 'Structured.vtu')
def test_make_unstructured_grid(tmpdir): """ Test the make_unstructured_grid routine.""" mesh = IO.GmshMesh() mesh.read("/".join((DATA_DIR, 'Structured.msh'))) print "/".join((DATA_DIR, 'Structured.msh')) num = len(mesh.nodes) vel = numpy.zeros((num, 3)) pres = numpy.zeros((num,)) time = 0 ugrid = IO.make_unstructured_grid(mesh, vel, pres, time, outfile=tmpdir.join('Structured.vtu').strpath) assert num > 0 assert ugrid.GetNumberOfPoints() == num assert ugrid.GetNumberOfCells() == len(mesh.elements) assert filecmp.cmpfiles(DATA_DIR, tmpdir.strpath, 'Structured.vtu') ugrid = IO.make_unstructured_grid(mesh, lambda x: (0, 0, 0), lambda x: 0, time, outfile=tmpdir.join('Structured.vtu').strpath) assert ugrid.GetNumberOfPoints() == num assert ugrid.GetNumberOfCells() == len(mesh.elements) assert filecmp.cmpfiles(DATA_DIR, tmpdir.strpath, 'Structured.vtu')
def get_system_from_options(options_file=None, boundary_grid=None, block=None, velocity_name='Velocity', dist=None): """Derive particle system from options file.""" reader = Options.OptionsReader(options_file) if boundary_grid is None: mesh = IO.GmshMesh() mesh.read(reader.get_mesh_filename()) boundary_grid = IO.make_boundary_from_msh(mesh) boundary = IO.BoundaryData(bnd=boundary_grid, outlet_ids=reader.get_outlet_ids(), inlets=reader.get_inlets(), dist=dist) if block is None: system = System(boundary, base_name=reader.get_name(), gravity=reader.get_gravity(), omega=reader.get_rotation()[0], velocity_name=velocity_name) else: system = System(boundary, block=block, gravity=reader.get_gravity(), omega=reader.get_rotation()[0], velocity_name=velocity_name) return system
def test_picker_linear_3d(tmpdir): """Test vtk picker in 3D.""" pos = ((0.5, 0.5, 0.5), (0.25, 0.75, 0.25)) err = numpy.array((1.0e-8, 1.0e-8, 1.0e-8)) fname = tmpdir.join('linear3D.vtu').strpath print fname def vel(pos): """ Fluid velocity""" return numpy.array((pos[0], pos[1], pos[2])) def pres(pos): """ Fluid pressure""" return pos[0] IO.make_unstructured_grid(MESH3D, vel, pres, 0.0, fname) system = System.System(temporal_cache=temp_cache('linear3D.vtu', tmpdir.strpath)) part = Particles.Particle((0, 0), system=system) for point in pos: fluid_velocity, grad_p = part.picker(point, 0.0) assert all(abs(fluid_velocity - vel(point)) < err) assert all(grad_p == numpy.array((1.0, 0.0, 0.0)))
def test_make_pvd(tmpdir): IO.make_pvd( tmpdir.join('test.pvd').strpath, "particle_model/tests/data/gyre", 'vtu') filepath = tmpdir.join('test.pvd').strpath assert os.path.isfile(filepath)
def run(self, time, delta_t=None, write=False, *args, **kwargs): """Drive particles forward until a given time.""" while time - self.time > 1.0e-6 * (delta_t or self.delta_t): self.update(delta_t, *args, **kwargs) if write: global LEVEL IO.write_level_to_polydata(bucket=self, level=LEVEL, basename="dump.vtp") LEVEL += 1
def get_cv_fraction(bucket, data): """Calculate the particle volume fraction using control volumes""" linear_data = IO.get_linear_block(data) is2d = linear_data.GetCell(0).GetCellType()==vtk.VTK_TRIANGLE cvs = vtp.vtkShowCVs() cvs.SetContinuity(-1) if vtk.vtkVersion.GetVTKMajorVersion()<6: cvs.SetInput(linear_data) else: cvs.SetInputData(linear_data) cvs.Update() cv_data = cvs.GetOutput() locator = vtk.vtkCellLocator() locator.SetDataSet(cv_data) locator.BuildLocator() output = numpy.zeros(linear_data.GetNumberOfPoints()) volume = numpy.zeros(linear_data.GetNumberOfPoints()) for _ in range(linear_data.GetNumberOfCells()): cell = linear_data.GetCell(_) pntIds = cell.GetPointIds() cv_mass = IO.get_measure(cell)/cell.GetNumberOfPoints() for dummy_1 in range(pntIds.GetNumberOfIds()): volume[pntIds.GetId(dummy_1)] += cv_mass for par in bucket.particles: index = locator.FindCell(par.pos) if index<0: continue ele, l_id = divmod(index,linear_data.GetCell(0).GetNumberOfPoints()) gid = linear_data.GetCell(ele).GetPointId(l_id) if is2d: output[gid] += par.parameters.get_area() else: output[gid] += par.parameters.get_volume() return output/volume
def test_polydata(tmpdir): """ Test the polydata class """ from numpy import zeros num = 100 pres = zeros((num, 3)) vel = zeros((num, 3)) fields = {"Test": zeros((num, 1))} part = Particles.ParticleBucket(pres, vel, field_data=fields) filepath = tmpdir.join('test.vtp').strpath poly_data = IO.PolyData(tmpdir.join('test.vtp').strpath) assert poly_data poly_data.append_data(part) assert len(poly_data.cell_ids) == num assert poly_data.pnts.GetNumberOfPoints() == num poly_data.write() assert os.path.isfile(filepath) assert poly_data.poly_data.GetNumberOfCells() == num poly_data.append_data(part) assert len(poly_data.cell_ids) == num assert poly_data.pnts.GetNumberOfPoints() == 2 * num
def get_wear_rate_source(bucket, alpha, delta_t, wm, ER): """Calculate wear_rate on the boundary surface""" linear_data = bucket.system.boundary.bnd wear = numpy.zeros((linear_data.GetNumberOfPoints())) volume = numpy.zeros(linear_data.GetNumberOfPoints()) for _ in range(linear_data.GetNumberOfCells()): cell = linear_data.GetCell(_) pnt_ids = cell.GetPointIds() cv_mass = IO.get_measure(cell) / cell.GetNumberOfPoints() for dummy_1 in range(pnt_ids.GetNumberOfIds()): volume[pnt_ids.GetId(dummy_1)] += cv_mass for col in bucket.collisions(): if col.time < bucket.time - bucket.delta_t: continue cell = linear_data.GetCell(col.cell) gid = barocentric_id(cell, col.pos) wear[gid] += col.get_wear(wm, ER) / delta_t wear /= volume print "Lily max wear rate source for %s is %s at %s with %s" % (ER, max(wear), delta_t, max(volume)) print "Lily min wear rate source for %s is %s at %s with %s" % (ER, min(wear), delta_t, min(volume)) return wear
def test_gyre_collision(): """Regression test for Mclaury coefficient""" bndg = IO.BoundaryData('particle_model/tests/data/gyre_boundary.vtu') system = System.System(bndg, coeff=1.0, temporal_cache=temp_cache('gyre_0.vtu')) from math import pi pos = numpy.array((0.8, 0.45, 0.0)) vel = numpy.array((2.0 * pi, 0.0, 0.0)) part = Particles.Particle((pos, vel), delta_t=0.001, parameters=PAR1, system=system) for i in range(100): del i part.update(method="AdamsBashforth2") assert part.pos[0] < 1.0 assert part.pos[1] < 1.0 assert part.pos[0] > 0.0 assert part.pos[1] > 0.0 assert len(part.collisions) == 1 assert part.collisions[0].pos[0] == 1.0 assert abs(Collision.mclaury_mass_coeff(part.collisions[0]) - 16.444037345317486) < 1.0e-8
def _fpick(self, pos, infile, picker, names, nearest=False): """ Extract fluid velocity and pressure from single .vtu file""" if picker.cell_index is None and not nearest: return None, None # picker defaults to velocity if nearest: out = picker.nearest(pos) else: out = picker(pos) if names[1] and picker.cell_index: data_p = IO.get_scalar( infile, self.system.temporal_cache.get(infile, names[1]), names[1], picker.cell_index) else: data_p = None if data_p is not None: dim = picker.cell.GetCellDimension() pts = numpy.array( [picker.cell.GetPoints().GetPoint(i) for i in range(dim + 1)]) grad_p = Math.grad(data_p, pts, dim) else: grad_p = ZERO if len(names) == 3: vdata = self.system.temporal_cache.get(infile, names[2]) gout = picker(pos, vdata) return out, grad_p, gout #otherwise return out, grad_p
def get_system_from_options(options_file=None, boundary_grid=None, block=None, velocity_name='Velocity',dist=None): reader=Options.OptionsReader(options_file) if boundary_grid is None: mesh=IO.GmshMesh() mesh.read(reader.get_mesh_filename()) boundary_grid = IO.make_boundary_from_msh(mesh) boundary = IO.BoundaryData(bnd=boundary_grid, outlet_ids=reader.get_outlet_ids(), inlets=reader.get_inlets(), dist=dist) if block is None: system = System(boundary,base_name=reader.get_name(), gravity=reader.get_gravity(), omega=reader.get_rotation()[0], velocity_name=velocity_name) else: system = System(boundary,block=block, gravity=reader.get_gravity(), omega=reader.get_rotation()[0], velocity_name=velocity_name) return system
def test_stokes_terminal_velocity(): """Test stokes terminal""" bndc = IO.BoundaryData('particle_model/tests/data/boundary_circle.vtu') system = System.System(bndc, base_name='particle_model/tests/data/circle', gravity=numpy.array((0.0, -1.0, 0.0)), rho=0.0, viscosity=1.0) diameter = 1e-3 delta_t = 1.0e-8 par = ParticleBase.PhysicalParticle(diameter=diameter, drag=DragModels.stokes_drag, rho=1.0) pos = numpy.zeros((1, 3)) vel = numpy.zeros((1, 3)) bucket = Particles.ParticleBucket(pos, vel, 0.0, delta_t=delta_t, parameters=par, system=system) bucket.run(100*delta_t, write=False, method="RungeKutta4") assert abs(bucket.time - 100*delta_t) < 1.0e-8 assert all(abs(bucket.particles[0].vel - numpy.array((0, -1.0/18./system.viscosity*par.diameter**2, 0))) < 1.e-8)
def test_clean_unstructured_grid(): """ Test the clean_unstructured_grid routine""" reader = vtk.vtkXMLUnstructuredGridReader() del reader ugrid = vtk.vtkUnstructuredGrid() clean_grid = IO.clean_unstructured_grid(ugrid) assert clean_grid
def fpick(infile, locator,names): """ Extract fluid velocity and pressure from single .vtu file""" locator.BuildLocatorIfNeeded() cell_index = self.find_cell(locator, pos) cell = IO.get_linear_block(infile).GetCell(cell_index) linear_cell = IO.get_linear_cell(cell) pids = cell.GetPointIds() dim = linear_cell.GetNumberOfPoints()-1 upos = numpy.zeros(linear_cell.GetNumberOfPoints()) dummy_func = linear_cell.GetPoints().GetPoint args = [dummy_func(i+1)[:dim] for i in range(dim)] args.append(dummy_func(0)[:dim]) args.append(upos) linear_cell.BarycentricCoords(pos[:dim], *args) # collision == Collision.testInCell(linear_cell, pos) data_u = IO.get_vector(infile, names[0], cell_index) data_p = IO.get_scalar(infile, names[1], cell_index) shape_funs = numpy.zeros(cell.GetNumberOfPoints()) deriv_funs = numpy.zeros(dim*cell.GetNumberOfPoints()) cell.InterpolateFunctions(upos[:3], shape_funs) cell.InterpolateDerivs(upos[:3], deriv_funs) rhs = data_p[1:dim+1]-data_p[0] mat = numpy.zeros((dim, dim)) pts = numpy.array([cell.GetPoints().GetPoint(i) for i in range(dim+1)]) for i in range(dim): mat[i, :] = pts[i+1, :dim] - pts[0, :dim] # mat=la.inv(mat) mat = invert(mat) out = numpy.dot(shape_funs, data_u) grad_p = numpy.zeros(3) grad_p[:dim] = numpy.dot(mat, rhs) return out, grad_p
def test_clean_unstructured_grid(): """ Test the clean_unstructured_grid routine""" reader = vtk.vtkXMLUnstructuredGridReader() del reader ugrid = vtk.vtkUnstructuredGrid() clean_grid = IO.clean_unstructured_grid(ugrid) assert clean_grid
def get_system_from_reader(reader, boundary_grid=None): """Derive system from options reader.""" if boundary_grid is None: mesh = IO.GmshMesh() mesh.read(reader.get_mesh_filename()) boundary_grid = IO.make_boundary_from_msh(mesh) boundary = IO.BoundaryData(bnd=boundary_grid) system = System(boundary, base_name=reader.get_name(), gravity=reader.get_gravity(), omega=reader.get_rotation()[0]) return system
def get_cv_fraction(bucket, data): """Calculate the particle volume fraction using control volumes""" linear_data = IO.get_linear_block(data) is2d = linear_data.GetCell(0).GetCellType() == vtk.VTK_TRIANGLE cvs = vtp.vtkShowCVs() cvs.SetContinuity(-1) if vtk.vtkVersion.GetVTKMajorVersion() < 6: cvs.SetInput(linear_data) else: cvs.SetInputData(linear_data) cvs.Update() cv_data = cvs.GetOutput() locator = vtk.vtkCellLocator() locator.SetDataSet(cv_data) locator.BuildLocator() output = numpy.zeros(linear_data.GetNumberOfPoints()) volume = numpy.zeros(linear_data.GetNumberOfPoints()) for _ in range(linear_data.GetNumberOfCells()): cell = linear_data.GetCell(_) pnt_ids = cell.GetPointIds() cv_mass = IO.get_measure(cell) / cell.GetNumberOfPoints() for dummy_1 in range(pnt_ids.GetNumberOfIds()): volume[pnt_ids.GetId(dummy_1)] += cv_mass for par in bucket: index = locator.FindCell(par.pos) if index < 0: continue ele, l_id = divmod(index, linear_data.GetCell(0).GetNumberOfPoints()) gid = linear_data.GetCell(ele).GetPointId(l_id) if is2d: output[gid] += par.parameters.get_area() else: output[gid] += par.parameters.get_volume() return output / volume
def get_solid_velocity(bucket, data, volfrac): """Calculate the particle volume fraction using control volumes""" linear_data = IO.get_linear_block(data) is2d = linear_data.GetCell(0).GetCellType()==vtk.VTK_TRIANGLE cvs = vtp.vtkShowCVs() cvs.SetContinuity(-1) if vtk.vtkVersion.GetVTKMajorVersion()<6: cvs.SetInput(linear_data) else: cvs.SetInputData(linear_data) cvs.Update() cv_data = cvs.GetOutput() locator = vtk.vtkCellLocator() locator.SetDataSet(cv_data) locator.BuildLocator() if is2d: dim=2 else: dim=3 output = numpy.zeros((linear_data.GetNumberOfPoints(),dim)) volume = numpy.zeros(linear_data.GetNumberOfPoints()) for par in bucket.particles: index = locator.FindCell(par.pos) if index<0: continue ele, l_id = divmod(index,linear_data.GetCell(0).GetNumberOfPoints()) gid = linear_data.GetCell(ele).GetPointId(l_id) if is2d: volume[gid] += par.parameters.get_area() output[gid,:] += par.parameters.get_area()*par.vel[:dim] else: volume[gid] += par.parameters.get_volume() output[gid,:] += par.parameters.get_volume()*par.vel[:dim] for _ in range(linear_data.GetNumberOfPoints()): if volume[_]>0.0: output[_,:] = output[_,:]/volume[_] return output
def picker(self, pos, time, gvel_out=None, nearest=False): """ Extract fluid velocity and pressure from .vtu files at correct time level""" data, alpha, names = self.system.temporal_cache(time) TemporalCache.PICKERS[0].name = names[0][0] TemporalCache.PICKERS[0].grid = IO.get_block(data[0][2], names[0][0]) TemporalCache.PICKERS[0].locator = data[0][3] TemporalCache.PICKERS[0].pos = numpy.asarray(pos, float) TemporalCache.PICKERS[1].name = names[1][0] TemporalCache.PICKERS[1].grid = IO.get_block(data[1][2], names[1][0]) TemporalCache.PICKERS[1].locator = data[1][3] TemporalCache.PICKERS[1].pos = numpy.asarray(pos, float) if len(names[0]) == 3: vel0, grad_p0, gvel_0 = self._fpick(pos, data[0][2], TemporalCache.PICKERS[0], names[0], nearest) vel1, grad_p1, gvel_1 = self._fpick(pos, data[1][2], TemporalCache.PICKERS[1], names[1], nearest) else: vel0, grad_p0 = self._fpick(pos, data[0][2], TemporalCache.PICKERS[0], names[0], nearest) vel1, grad_p1 = self._fpick(pos, data[1][2], TemporalCache.PICKERS[1], names[1], nearest) if vel0 is None or vel1 is None: return None, None if gvel_out: gvel_out = (1.0 - alpha) * gvel_0 + alpha * gvel_1 return ((1.0 - alpha) * vel0 + alpha * vel1, (1.0 - alpha) * grad_p0 + alpha * grad_p1)
def get_velocity(self, pos, time): """ Get the velocity value from the cache at a given position and time.""" data, alpha, names = self(time) data[0][3].BuildLocatorIfNeeded() data[1][3].BuildLocatorIfNeeded() PICKERS[0].name = names[0][0] PICKERS[0].grid = IO.get_block(data[0][2], names[0][0]) PICKERS[0].locator = data[0][3] PICKERS[0].pos = pos PICKERS[1].name = names[1][0] PICKERS[1].grid = IO.get_block(data[1][2], names[1][0]) PICKERS[1].locator = data[1][3] PICKERS[1].pos = pos vel0 = PICKERS[0].nearest(pos) vel1 = PICKERS[1].nearest(pos) if vel0 is None or vel1 is None: raise ValueError # otherwise return alpha * vel1 + (1.0 - alpha) * vel0
def get_system_from_reader(reader, boundary_grid=None): if boundary_grid is None: mesh=IO.GmshMesh() mesh.read(reader.get_mesh_filename()) boundary_grid = IO.make_boundary_from_msh(mesh) boundary = IO.BoundaryData(bnd=boundary_grid) system = System(boundary,base_name=reader.get_name(), gravity=reader.get_gravity(), omega=reader.get_rotation()[0]) return system
def get_solid_velocity(bucket, data, volfrac): """Calculate the particle volume fraction using control volumes""" linear_data = IO.get_linear_block(data) is2d = linear_data.GetCell(0).GetCellType() == vtk.VTK_TRIANGLE if is2d: dim = 2 else: dim = 3 cvs = vtp.vtkShowCVs() cvs.SetContinuity(-1) if vtk.vtkVersion.GetVTKMajorVersion() < 6: cvs.SetInput(linear_data) else: cvs.SetInputData(linear_data) cvs.Update() cv_data = cvs.GetOutput() locator = vtk.vtkCellLocator() locator.SetDataSet(cv_data) locator.BuildLocator() output = numpy.zeros((linear_data.GetNumberOfPoints(), dim)) volume = numpy.zeros(linear_data.GetNumberOfPoints()) for par in bucket.particles: index = locator.FindCell(par.pos) if index < 0: continue ele, l_id = divmod(index, linear_data.GetCell(0).GetNumberOfPoints()) gid = linear_data.GetCell(ele).GetPointId(l_id) if is2d: volume[gid] += par.parameters.get_area() output[gid, :] += par.parameters.get_area() * par.vel[:dim] else: volume[gid] += par.parameters.get_volume() output[gid, :] += par.parameters.get_volume() * par.vel[:dim] for _ in range(linear_data.GetNumberOfPoints()): if volume[_] > 0.0: output[_, :] = output[_, :] / volume[_] return output
def _check_remapping(self, pos_1, pos_0, vel_0, delta_t): """Test for periodic/remapped boundaries""" ### this finds the point of boundary intersection ### pos_i = pos_0 + t_val*(pos_1-pos_0) intersect, pos_i, t_val, cell_index, pcoords = self.system.boundary.test_intersection( pos_0, pos_1) if intersect and cell_index >= 0: surface_id = self.system.boundary.get_surface_id(cell_index) if surface_id is not None: if surface_id in self.system.boundary.mapped_ids: pos_o, vel_o = self.system.boundary.mapped_ids[surface_id]( pos_i, vel_0) pos_f = pos_o + (1.0 - t_val) * delta_t * vel_o vel_i, _ = self.picker(pos_f, self.time + delta_t) par_col = copy.copy(self) if self.system.boundary.dist: cell = self.system.boundary.bnd.GetCell(cell_index) par_col.pos = IO.get_real_x(cell, pcoords) else: par_col.pos = pos_i par_col.vel = vel_0 par_col.time = self.time + t_val * delta_t return pos_f, vel_i elif surface_id in self.system.boundary.outlet_ids: return pos_1, vel_1 else: pos_o = numpy.array(pos_0 * (1.0 - t_val * (0.99)) + pos_1 * t_val * (0.99), dtype=float) vel_i, _ = self.picker(pos_o, self.time + delta_t) if vel_i is None: vel_i = vel_0 return pos_0, vel_0 #otherwise return pos_0, vel_0
def test_particle_bucket_step_do_nothing(): """ Test initializing a full particle bucket.""" from numpy import zeros bndc = IO.BoundaryData('particle_model/tests/data/boundary_circle.vtu') system = System.System(bndc, base_name='particle_model/tests/data/circle') num = 1 pres = zeros((num, 3)) vel = zeros((num, 3)) bucket = Particles.ParticleBucket(pres, vel, 0.0, delta_t=0.5, system=system) bucket.run(5.0, write=False) assert bucket.time == 5.0 assert all(bucket.particles[0].pos == 0.0) assert all(bucket.particles[0].vel == 0.0)
def get_wear_rate_source(bucket, alpha, delta_t): """Calculate wear_rate on the boundary surface""" linear_data = bucket.system.boundary.bnd is2d = linear_data.GetCell(0).GetCellType()==vtk.VTK_LINE if is2d: dim=2 else: dim=3 wear = numpy.zeros((linear_data.GetNumberOfPoints())) volume = numpy.zeros(linear_data.GetNumberOfPoints()) for _ in range(linear_data.GetNumberOfCells()): cell = linear_data.GetCell(_) pntIds = cell.GetPointIds() cv_mass = IO.get_measure(cell)/cell.GetNumberOfPoints() for dummy_1 in range(pntIds.GetNumberOfIds()): volume[pntIds.GetId(dummy_1)] += cv_mass for col in bucket.collisions(): if col.time<bucket.time-bucket.delta_t: continue cell = linear_data.GetCell(col.cell) gid = barocentric_id(cell,col.pos) wear[gid] += col.get_wear()/delta_t wear /= volume return wear
def update_boundary_from_block(self, mblock): """Update boundary object from VTK block.""" self.boundary.update_boundary_file(IO.get_boundary_from_block(mblock))
def update_boundary_from_mesh(self, mesh): """Update boundary object from mesh.""" self.boundary.update_boundary_file(IO.make_boundary_from_msh(mesh))
def collide(self, k, delta_t, vel=None, force=None, pa=None, level=0): """Collision detection routine. Args: k (float): Displacement dt (float): Timestep v (float, optional): velocity f (float, optional): forcing pa (float, optional): starting position in subcycle level (int) count to control maximum depth """ if pa is None: pa = self.pos if level == 10: return k * delta_t, None, vel - self.vel, None pos = pa+delta_t*k s = vtk.mutable(-1.0) x = [0.0, 0.0, 0.0] cell_index = vtk.mutable(0) bndl = self.system.boundary.bndl intersect = bndl.IntersectWithLine(pa, pos, 1.0e-8, s, x, ARGV, ARGI, cell_index) if intersect: if self.system.boundary.bnd.GetCellData().HasArray('SurfaceIds'): if self.system.boundary.bnd.GetCellData().GetScalars('SurfaceIds').GetValue(cell_index) in self.system.boundary.outlet_ids: return pos - pa, None, vel + delta_t * force - self.vel, None data, _, names = self.system.temporal_cache(self.time) # assert IO.test_in_cell(IO.get_linear_block(data[0][2]).GetCell(self.find_cell(data[0][3], pa)), pa) or sum((pa-x)**2)<1.0-10 print 'collision', intersect, cell_index, s, x, pos, pa x = numpy.array(x) old_pos = pos cell = self.system.boundary.bnd.GetCell(cell_index) normal = numpy.zeros(3) vec1 = (numpy.array(cell.GetPoints().GetPoint(1)) -numpy.array(cell.GetPoints().GetPoint(0))) if cell.GetCellType() == vtk.VTK_TRIANGLE: vec2 = (numpy.array(cell.GetPoints().GetPoint(2)) -numpy.array(cell.GetPoints().GetPoint(0))) else: vec2 = numpy.array(((pos-pa)[1]*vec1[2]-(pos-pa)[2]*vec1[1], (pos-pa)[2]*vec1[0]-(pos-pa)[0]*vec1[2], (pos-pa)[0]*vec1[1]-(pos-pa)[1]*vec1[0])) normal[0] = vec1[1]*vec2[2]-vec1[2]*vec2[1] normal[1] = vec1[2]*vec2[0]-vec1[0]*vec2[2] normal[2] = vec1[0]*vec2[1]-vec1[1]*vec2[0] if sum(normal**2) > 1.0e-32: normal = normal / numpy.sqrt(sum(normal**2)) else: print normal print vec1, vec2 raise Collision.CollisionException normal = normal * numpy.sign(numpy.dot(normal, (pos-pa))) coeff = self.system.coefficient_of_restitution(self, cell) pos = x + delta_t * (k - (1.0 + coeff) * normal * (numpy.dot(normal, k))) theta = abs(numpy.arcsin(numpy.dot(normal, (x-pa)) / numpy.sqrt(numpy.dot(x - pa, x - pa)))) coldat = [] if any(vel): vels = vel + s * delta_t * force else: vels = self.vel + s * delta_t * force par_col = copy.copy(self) if self.system.boundary.dist: par_col.pos = IO.get_real_x(cell, ARGV) else: par_col.pos = x par_col.vel = vels par_col.time = self.time + s * delta_t coldat.append(Collision.CollisionInfo(par_col, cell_index, theta, normal)) vels += -(1.0 + coeff)* normal * numpy.dot(normal, vels) px, col, velo, dummy_vel = self.collide(vels, (1 - s) * delta_t, vel=vels, force=force, pa=x + 1.0e-9 * vels, level=level + 1) pos = px + x + 1.0e-9 * vels if col: coldat += col return pos - pa, coldat, velo, vels return pos - pa, None, vel + delta_t * force - self.vel, None
"""Factory function to mock a temporal cache.""" del time reader = vtk.vtkXMLUnstructuredGridReader() reader.SetFileName(self.ldir+'/'+self.fname) reader.Update() locator = vtk.vtkCellLocator() locator.SetDataSet(reader.GetOutput()) locator.BuildLocator() return ([[0.0, self.fname, reader.GetOutput(), locator], [1.0, self.fname, reader.GetOutput(), locator]], 0.0, [['Velocity', 'Pressure'], ['Velocity', 'Pressure']]) BOUNDARY = IO.BoundaryData('particle_model/tests/data/rightward_boundary.vtu') BOUNDARY3D = IO.BoundaryData('particle_model/tests/data/cube_boundary.vtu') SYSTEM = System.System(BOUNDARY, coeff=1.0, temporal_cache=temp_cache(), rho=1.0e3, ) SYSTEM3D = System.System(BOUNDARY3D, coeff=1.0, temporal_cache=temp_cache('cube_0.vtu')) MESH = IO.GmshMesh() MESH.read('particle_model/tests/data/Structured.msh') MESH3D = IO.GmshMesh() MESH3D.read('particle_model/tests/data/Structured_cube.msh') PAR0 = ParticleBase.PhysicalParticle(diameter=1.0e32,rho=1.0) PAR1 = ParticleBase.PhysicalParticle(diameter=100.0e-4,rho=1.0e3) def test_tests():