def write_vtk(self, file_name, fields, compressor=None): from pyvisfile.vtk import ( UnstructuredGrid, DataArray, AppendedDataXMLGenerator, VTK_TETRA, VF_LIST_OF_VECTORS, VF_LIST_OF_COMPONENTS) grid = UnstructuredGrid( (self.nodes.shape[-1], DataArray("points", self.nodes, vector_format=VF_LIST_OF_COMPONENTS)), cells=self.vis_simplices, cell_types=np.asarray([VTK_TETRA] * self.discr.K*self.nsimplices_per_el, dtype=np.uint8)) for name, field in fields: grid.add_pointdata(DataArray(name, field.reshape(-1), vector_format=VF_LIST_OF_COMPONENTS)) from os.path import exists if exists(file_name): raise RuntimeError("output file '%s' already exists" % file_name) outf = open(file_name, "w") AppendedDataXMLGenerator(compressor)(grid).write(outf) outf.close()
def write_vtk(self, file_name, fields, compressor=None): from pyvisfile.vtk import (UnstructuredGrid, DataArray, AppendedDataXMLGenerator, VTK_TETRA, VF_LIST_OF_VECTORS, VF_LIST_OF_COMPONENTS) grid = UnstructuredGrid( (self.nodes.shape[-1], DataArray( "points", self.nodes, vector_format=VF_LIST_OF_COMPONENTS)), cells=self.vis_simplices, cell_types=np.asarray([VTK_TETRA] * self.discr.K * self.nsimplices_per_el, dtype=np.uint8)) for name, field in fields: grid.add_pointdata( DataArray(name, field.reshape(-1), vector_format=VF_LIST_OF_COMPONENTS)) from os.path import exists if exists(file_name): raise RuntimeError("output file '%s' already exists" % file_name) outf = open(file_name, "w") AppendedDataXMLGenerator(compressor)(grid).write(outf) outf.close()
def test_vtk_unstructured_points(n): points = np.random.randn(n, 3) data = [ ("p", np.random.randn(n)), ("vel", np.random.randn(3, n)), ] file_name = f"points_{n}.vtu" compressor = None grid = UnstructuredGrid( (n, DataArray("points", points, vector_format=VF_LIST_OF_VECTORS)), cells=np.arange(n, dtype=np.uint32), cell_types=np.asarray([VTK_VERTEX] * n, dtype=np.uint8)) for name, field in data: grid.add_pointdata( DataArray(name, field, vector_format=VF_LIST_OF_COMPONENTS)) from os.path import exists if exists(file_name): raise RuntimeError("output file '%s' already exists" % file_name) outf = open(file_name, "w") AppendedDataXMLGenerator(compressor)(grid).write(outf) outf.close()
def _dump_arrays(self, filename): from pyvisfile.vtk import (UnstructuredGrid, DataArray, AppendedDataXMLGenerator, VTK_VERTEX) n = self.numPoints da = DataArray("points", self.points) grid = UnstructuredGrid((n, da), cells=np.arange(n), cell_types=np.asarray([VTK_VERTEX] * n)) for name, field in self.data: da = DataArray(name, field) grid.add_pointdata(da) with open(filename + '.vtu', "w") as f: AppendedDataXMLGenerator(None)(grid).write(f)
def write_vtk_file(self, file_name, names_and_fields, compressor=None, real_only=False): from pyvisfile.vtk import ( UnstructuredGrid, DataArray, AppendedDataXMLGenerator, VTK_LINE, VTK_TRIANGLE, VTK_TETRA, VF_LIST_OF_COMPONENTS) el_types = { 1: VTK_LINE, 2: VTK_TRIANGLE, 3: VTK_TETRA, } el_type = el_types[self.vis_discr.dim] with cl.CommandQueue(self.vis_discr.cl_context) as queue: nodes = self.vis_discr.nodes().with_queue(queue).get() names_and_fields = [ (name, self._resample_and_get(queue, fld)) for name, fld in names_and_fields] connectivity = self._vis_connectivity() nprimitive_elements = ( connectivity.shape[0] * connectivity.shape[1]) grid = UnstructuredGrid( (self.vis_discr.nnodes, DataArray("points", nodes.reshape(self.vis_discr.ambient_dim, -1), vector_format=VF_LIST_OF_COMPONENTS)), cells=connectivity.reshape(-1), cell_types=np.asarray([el_type] * nprimitive_elements, dtype=np.uint8)) # for name, field in separate_by_real_and_imag(cell_data, real_only): # grid.add_celldata(DataArray(name, field, # vector_format=VF_LIST_OF_COMPONENTS)) for name, field in separate_by_real_and_imag(names_and_fields, real_only): grid.add_pointdata(DataArray(name, field, vector_format=VF_LIST_OF_COMPONENTS)) from os.path import exists if exists(file_name): raise RuntimeError("output file '%s' already exists" % file_name) with open(file_name, "w") as outf: AppendedDataXMLGenerator(compressor)(grid).write(outf)
def write_vtk_file(self, file_name, names_and_fields, compressor=None, real_only=False): from pyvisfile.vtk import (UnstructuredGrid, DataArray, AppendedDataXMLGenerator, VTK_LINE, VTK_TRIANGLE, VTK_TETRA, VF_LIST_OF_COMPONENTS) el_types = { 1: VTK_LINE, 2: VTK_TRIANGLE, 3: VTK_TETRA, } el_type = el_types[self.vis_discr.dim] with cl.CommandQueue(self.vis_discr.cl_context) as queue: nodes = self.vis_discr.nodes().with_queue(queue).get() names_and_fields = [(name, self._resample_and_get(queue, fld)) for name, fld in names_and_fields] connectivity = self._vis_connectivity() nprimitive_elements = (connectivity.shape[0] * connectivity.shape[1]) grid = UnstructuredGrid( (self.vis_discr.nnodes, DataArray("points", nodes.reshape(self.vis_discr.ambient_dim, -1), vector_format=VF_LIST_OF_COMPONENTS)), cells=connectivity.reshape(-1), cell_types=np.asarray([el_type] * nprimitive_elements, dtype=np.uint8)) # for name, field in separate_by_real_and_imag(cell_data, real_only): # grid.add_celldata(DataArray(name, field, # vector_format=VF_LIST_OF_COMPONENTS)) for name, field in separate_by_real_and_imag(names_and_fields, real_only): grid.add_pointdata( DataArray(name, field, vector_format=VF_LIST_OF_COMPONENTS)) from os.path import exists if exists(file_name): raise RuntimeError("output file '%s' already exists" % file_name) with open(file_name, "w") as outf: AppendedDataXMLGenerator(compressor)(grid).write(outf)
def write_vertex_vtk_file(mesh, file_name, compressor=None, overwrite=False): from pyvisfile.vtk import (UnstructuredGrid, DataArray, AppendedDataXMLGenerator, VF_LIST_OF_COMPONENTS) # {{{ create cell_types from pyvisfile.vtk import (VTK_LINE, VTK_TRIANGLE, VTK_TETRA, VTK_QUAD, VTK_HEXAHEDRON) from meshmode.mesh import TensorProductElementGroup, SimplexElementGroup cell_types = np.empty(mesh.nelements, dtype=np.uint8) cell_types.fill(255) for egrp in mesh.groups: if isinstance(egrp, SimplexElementGroup): vtk_cell_type = { 1: VTK_LINE, 2: VTK_TRIANGLE, 3: VTK_TETRA, }[egrp.dim] elif isinstance(egrp, TensorProductElementGroup): vtk_cell_type = { 1: VTK_LINE, 2: VTK_QUAD, 3: VTK_HEXAHEDRON, }[egrp.dim] else: raise NotImplementedError("mesh vtk file writing for " "element group of type '%s'" % type(egrp).__name__) cell_types[ egrp.element_nr_base: egrp.element_nr_base + egrp.nelements] = \ vtk_cell_type assert (cell_types != 255).all() # }}} grid = UnstructuredGrid( (mesh.nvertices, DataArray( "points", mesh.vertices, vector_format=VF_LIST_OF_COMPONENTS)), cells=np.hstack( [vgrp.vertex_indices.reshape(-1) for vgrp in mesh.groups]), cell_types=cell_types) import os from meshmode import FileExistsError if os.path.exists(file_name): if overwrite: os.remove(file_name) else: raise FileExistsError("output file '%s' already exists" % file_name) with open(file_name, "w") as outf: AppendedDataXMLGenerator(compressor)(grid).write(outf)
def __init__(self, discr, pcontext=None, basename=None, compressor=None): hedge.tools.Closable.__init__(self) from pytools import assert_not_a_file if basename is not None: self.pvd_name = basename+".pvd" assert_not_a_file(self.pvd_name) else: self.pvd_name = None self.pcontext = pcontext self.compressor = compressor if self.pcontext is None or self.pcontext.is_head_rank: self.timestep_to_pathnames = {} else: self.timestep_to_pathnames = None from pyvisfile.vtk import UnstructuredGrid, DataArray, \ VTK_LINE, VTK_TRIANGLE, VTK_TETRA, VF_LIST_OF_VECTORS from hedge.mesh.element import Interval, Triangle, Tetrahedron # For now, we use IntVector here because the Python allocator # is somewhat reluctant to return allocated chunks of memory # to the OS. from hedge._internal import IntVector cells = IntVector() cell_types = IntVector() for eg in discr.element_groups: ldis = eg.local_discretization smi = ldis.get_submesh_indices() cells.reserve(len(cells)+len(smi)*len(eg.members)) for el, el_slice in zip(eg.members, eg.ranges): for element in smi: for j in element: cells.append(el_slice.start+j) if ldis.geometry is Interval: vtk_eltype = VTK_LINE elif ldis.geometry is Triangle: vtk_eltype = VTK_TRIANGLE elif ldis.geometry is Tetrahedron: vtk_eltype = VTK_TETRA else: raise RuntimeError("unsupported element type: %s" % ldis.geometry) cell_types.extend([vtk_eltype] * len(smi) * len(eg.members)) self.grid = UnstructuredGrid( (len(discr), DataArray("points", discr.nodes, vector_format=VF_LIST_OF_VECTORS)), numpy.asarray(cells), cell_types=numpy.asarray(cell_types, dtype=numpy.uint8))
def write_nodal_adjacency_vtk_file(file_name, mesh, compressor=None, overwrite=False): from pyvisfile.vtk import ( UnstructuredGrid, DataArray, AppendedDataXMLGenerator, VTK_LINE, VF_LIST_OF_COMPONENTS) centroids = np.empty( (mesh.ambient_dim, mesh.nelements), dtype=mesh.vertices.dtype) for grp in mesh.groups: iel_base = grp.element_nr_base centroids[:, iel_base:iel_base+grp.nelements] = ( np.sum(mesh.vertices[:, grp.vertex_indices], axis=-1) / grp.vertex_indices.shape[-1]) adj = mesh.nodal_adjacency nconnections = len(adj.neighbors) connections = np.empty((nconnections, 2), dtype=np.int32) nb_starts = adj.neighbors_starts for iel in range(mesh.nelements): connections[nb_starts[iel]:nb_starts[iel+1], 0] = iel connections[:, 1] = adj.neighbors grid = UnstructuredGrid( (mesh.nelements, DataArray("points", centroids, vector_format=VF_LIST_OF_COMPONENTS)), cells=connections.reshape(-1), cell_types=np.asarray([VTK_LINE] * nconnections, dtype=np.uint8)) import os from meshmode import FileExistsError if os.path.exists(file_name): if overwrite: os.remove(file_name) else: raise FileExistsError("output file '%s' already exists" % file_name) with open(file_name, "w") as outf: AppendedDataXMLGenerator(compressor)(grid).write(outf)
def write_vtk_file(self, file_name, names_and_fields, compressor=None, real_only=False, overwrite=False): from pyvisfile.vtk import ( UnstructuredGrid, DataArray, AppendedDataXMLGenerator, VF_LIST_OF_COMPONENTS) with cl.CommandQueue(self.vis_discr.cl_context) as queue: nodes = self.vis_discr.nodes().with_queue(queue).get() names_and_fields = [ (name, self._resample_and_get(queue, fld)) for name, fld in names_and_fields] vc_groups = self._vis_connectivity() # {{{ create cell_types nsubelements = sum(vgrp.nsubelements for vgrp in vc_groups) cell_types = np.empty(nsubelements, dtype=np.uint8) cell_types.fill(255) for vgrp in vc_groups: cell_types[ vgrp.subelement_nr_base: vgrp.subelement_nr_base + vgrp.nsubelements] = \ vgrp.vtk_cell_type assert (cell_types < 255).all() # }}} if self.element_shrink_factor != 1: for vgrp in self.vis_discr.groups: nodes_view = vgrp.view(nodes) el_centers = np.mean(nodes_view, axis=-1) nodes_view[:] = ( (self.element_shrink_factor * nodes_view) + (1-self.element_shrink_factor) * el_centers[:, :, np.newaxis]) grid = UnstructuredGrid( (self.vis_discr.nnodes, DataArray("points", nodes.reshape(self.vis_discr.ambient_dim, -1), vector_format=VF_LIST_OF_COMPONENTS)), cells=np.hstack([ vgrp.vis_connectivity.reshape(-1) for vgrp in vc_groups]), cell_types=cell_types) # for name, field in separate_by_real_and_imag(cell_data, real_only): # grid.add_celldata(DataArray(name, field, # vector_format=VF_LIST_OF_COMPONENTS)) for name, field in separate_by_real_and_imag(names_and_fields, real_only): grid.add_pointdata(DataArray(name, field, vector_format=VF_LIST_OF_COMPONENTS)) import os from meshmode import FileExistsError if os.path.exists(file_name): if overwrite: os.remove(file_name) else: raise FileExistsError("output file '%s' already exists" % file_name) with open(file_name, "w") as outf: AppendedDataXMLGenerator(compressor)(grid).write(outf)
def write_vtk_file(self, file_name, names_and_fields, compressor=None, real_only=False, overwrite=False, use_high_order=None, par_manifest_filename=None, par_file_names=None): """Write a Vtk XML file (typical extension ``.vtu``) containing the visualization data in *names_and_fields*. Can optionally also write manifests for distributed memory simulation (typical extension ``.pvtu``). See also :meth:`write_parallel_vtk_file` for a convenience wrapper. :arg names_and_fields: A list of tuples ``(name, value)``, where *name* is a string and *value* is a :class:`~meshmode.dof_array.DOFArray` or a constant, or an object array of those. *value* may also be a data class (see :mod:`dataclasses`), whose attributes will be inserted into the visualization with their names prefixed by *name*. If *value* is *None*, then there is no data to write and the corresponding *name* will not appear in the data file. If *value* is *None*, it should be *None* collectively across all ranks for parallel writes; otherwise the behavior of this routine is undefined. :arg overwrite: If *True*, silently overwrite existing files. :arg use_high_order: Writes arbitrary order Lagrange VTK elements. These elements are described in `this blog post <https://blog.kitware.com/modeling-arbitrary-order-lagrange-finite-elements-in-the-visualization-toolkit/>`__ and are available in VTK 8.1 and newer. :arg par_manifest_filename: If not *None* write a distributed-memory manifest with this file name if *file_name* matches the first entry in *par_file_names*. :arg par_file_names: A list of file names of visualization files to include in the distributed-memory manifest. .. versionchanged:: 2020.2 - Added *par_manifest_filename* and *par_file_names*. - Added *use_high_order*. """ # noqa if use_high_order is None: use_high_order = False if use_high_order: if not self.is_equidistant: raise RuntimeError("Cannot visualize high-order Lagrange elements " "using a non-equidistant visualizer. " "Call 'make_visualizer' with 'force_equidistant=True'.") connectivity = self._vtk_lagrange_connectivity else: connectivity = self._vtk_connectivity from pyvisfile.vtk import ( UnstructuredGrid, DataArray, AppendedDataXMLGenerator, ParallelXMLGenerator, VF_LIST_OF_COMPONENTS) nodes = self._vis_nodes_numpy() names_and_fields = preprocess_fields(names_and_fields) names_and_fields = [ (name, resample_to_numpy(self.connection, fld)) for name, fld in names_and_fields ] # {{{ create cell_types nsubelements = sum(vgrp.nsubelements for vgrp in connectivity.groups) cell_types = np.empty(nsubelements, dtype=np.uint8) cell_types.fill(255) for vgrp in connectivity.groups: isubelements = np.s_[ vgrp.subelement_nr_base: vgrp.subelement_nr_base + vgrp.nsubelements] cell_types[isubelements] = vgrp.vtk_cell_type assert (cell_types < 255).all() # }}} # {{{ shrink elements if abs(self.element_shrink_factor - 1.0) > 1.0e-14: node_nr_base = 0 for vgrp in self.vis_discr.groups: nodes_view = ( nodes[:, node_nr_base:node_nr_base + vgrp.ndofs] .reshape(nodes.shape[0], vgrp.nelements, vgrp.nunit_dofs)) el_centers = np.mean(nodes_view, axis=-1) nodes_view[:] = ( (self.element_shrink_factor * nodes_view) + (1-self.element_shrink_factor) * el_centers[:, :, np.newaxis]) node_nr_base += vgrp.ndofs # }}} # {{{ create grid nodes = nodes.reshape(self.vis_discr.ambient_dim, -1) points = DataArray("points", nodes, vector_format=VF_LIST_OF_COMPONENTS) grid = UnstructuredGrid( (nodes.shape[1], points), cells=connectivity.cells, cell_types=cell_types) for name, field in separate_by_real_and_imag(names_and_fields, real_only): grid.add_pointdata( DataArray(name, field, vector_format=VF_LIST_OF_COMPONENTS) ) # }}} # {{{ write # {{{ write either both the vis file and the manifest, or neither import os responsible_for_writing_par_manifest = ( par_file_names and par_file_names[0] == file_name) if os.path.exists(file_name): if overwrite: # we simply overwrite below, no need to remove pass else: raise FileExistsError("output file '%s' already exists" % file_name) if (responsible_for_writing_par_manifest and par_manifest_filename is not None): if os.path.exists(par_manifest_filename): if overwrite: # we simply overwrite below, no need to remove pass else: raise FileExistsError("output file '%s' already exists" % par_manifest_filename) else: pass # }}} with open(file_name, "w") as outf: generator = AppendedDataXMLGenerator( compressor=compressor, vtk_file_version=connectivity.version) generator(grid).write(outf) if par_file_names is not None: if par_manifest_filename is None: raise ValueError("must specify par_manifest_filename if " "par_file_names are given") if responsible_for_writing_par_manifest: with open(par_manifest_filename, "w") as outf: generator = ParallelXMLGenerator(par_file_names) generator(grid).write(outf)
class VtkVisualizer(Visualizer, hedge.tools.Closable): def __init__(self, discr, pcontext=None, basename=None, compressor=None): hedge.tools.Closable.__init__(self) from pytools import assert_not_a_file if basename is not None: self.pvd_name = basename+".pvd" assert_not_a_file(self.pvd_name) else: self.pvd_name = None self.pcontext = pcontext self.compressor = compressor if self.pcontext is None or self.pcontext.is_head_rank: self.timestep_to_pathnames = {} else: self.timestep_to_pathnames = None from pyvisfile.vtk import UnstructuredGrid, DataArray, \ VTK_LINE, VTK_TRIANGLE, VTK_TETRA, VF_LIST_OF_VECTORS from hedge.mesh.element import Interval, Triangle, Tetrahedron # For now, we use IntVector here because the Python allocator # is somewhat reluctant to return allocated chunks of memory # to the OS. from hedge._internal import IntVector cells = IntVector() cell_types = IntVector() for eg in discr.element_groups: ldis = eg.local_discretization smi = ldis.get_submesh_indices() cells.reserve(len(cells)+len(smi)*len(eg.members)) for el, el_slice in zip(eg.members, eg.ranges): for element in smi: for j in element: cells.append(el_slice.start+j) if ldis.geometry is Interval: vtk_eltype = VTK_LINE elif ldis.geometry is Triangle: vtk_eltype = VTK_TRIANGLE elif ldis.geometry is Tetrahedron: vtk_eltype = VTK_TETRA else: raise RuntimeError("unsupported element type: %s" % ldis.geometry) cell_types.extend([vtk_eltype] * len(smi) * len(eg.members)) self.grid = UnstructuredGrid( (len(discr), DataArray("points", discr.nodes, vector_format=VF_LIST_OF_VECTORS)), numpy.asarray(cells), cell_types=numpy.asarray(cell_types, dtype=numpy.uint8)) def update_pvd(self): if self.pvd_name and self.timestep_to_pathnames: from pyvisfile.vtk import XMLRoot, XMLElement, make_vtkfile collection = XMLElement("Collection") vtkf = make_vtkfile(collection.tag, compressor=None) xmlroot = XMLRoot(vtkf) vtkf.add_child(collection) from os.path import relpath, dirname rel_path_start = dirname(self.pvd_name) tsteps = self.timestep_to_pathnames.keys() tsteps.sort() for i, time in enumerate(tsteps): for part, pathname in enumerate(self.timestep_to_pathnames[time]): collection.add_child(XMLElement( "DataSet", timestep=time, part=part, file=relpath(pathname, rel_path_start))) outf = open(self.pvd_name, "w") xmlroot.write(outf) outf.close() def do_close(self): self.update_pvd() def make_file(self, pathname): """ An appropriate extension (including the dot) is automatically appended to *pathname*. """ if self.pcontext is None or len(self.pcontext.ranks) == 1: return VtkFile(pathname+"."+self.grid.vtk_extension(), self.grid.copy(), compressor=self.compressor ) else: from os.path import basename filename_pattern = ( pathname + "-%05d." + self.grid.vtk_extension()) if self.pcontext.is_head_rank: return ParallelVtkFile( filename_pattern % self.pcontext.rank, self.grid.copy(), index_pathname="%s.p%s" % ( pathname, self.grid.vtk_extension()), pathnames=[ basename(filename_pattern % rank) for rank in self.pcontext.ranks], compressor=self.compressor ) else: return VtkFile( filename_pattern % self.pcontext.rank, self.grid.copy(), compressor=self.compressor ) def register_pathname(self, time, pathname): if time is not None and self.timestep_to_pathnames is not None: self.timestep_to_pathnames.setdefault(time, []).append(pathname) # When we are run under MPI and cancelled by Ctrl+C, destructors # do not get called. Therefore, we just spend the (hopefully negligible) # time to update the PVD index every few data additions. if len(self.timestep_to_pathnames) % 5 == 0: self.update_pvd() def add_data(self, visf, variables=[], scalars=[], vectors=[], time=None, step=None, scale_factor=1): if scalars or vectors: import warnings warnings.warn("`scalars' and `vectors' arguments are deprecated", DeprecationWarning) variables = scalars + vectors from pyvisfile.vtk import DataArray, VF_LIST_OF_COMPONENTS for name, field in variables: visf.grid.add_pointdata(DataArray(name, scale_factor*field, vector_format=VF_LIST_OF_COMPONENTS)) self.register_pathname(time, visf.get_head_pathname())
class VtkVisualizer(Visualizer, hedge.tools.Closable): def __init__(self, discr, pcontext=None, basename=None, compressor=None): logger.info("init vtk visualizer: start") hedge.tools.Closable.__init__(self) from pytools import assert_not_a_file if basename is not None: self.pvd_name = basename + ".pvd" assert_not_a_file(self.pvd_name) else: self.pvd_name = None self.pcontext = pcontext self.compressor = compressor if self.pcontext is None or self.pcontext.is_head_rank: self.timestep_to_pathnames = {} else: self.timestep_to_pathnames = None from pyvisfile.vtk import UnstructuredGrid, DataArray, \ VTK_LINE, VTK_TRIANGLE, VTK_TETRA, VF_LIST_OF_VECTORS from hedge.mesh.element import Interval, Triangle, Tetrahedron # For now, we use IntVector here because the Python allocator # is somewhat reluctant to return allocated chunks of memory # to the OS. from hedge._internal import IntVector cells = IntVector() cell_types = IntVector() for eg in discr.element_groups: ldis = eg.local_discretization smi = ldis.get_submesh_indices() cells.reserve(len(cells) + len(smi) * len(eg.members)) for el, el_slice in zip(eg.members, eg.ranges): for element in smi: for j in element: cells.append(el_slice.start + j) if ldis.geometry is Interval: vtk_eltype = VTK_LINE elif ldis.geometry is Triangle: vtk_eltype = VTK_TRIANGLE elif ldis.geometry is Tetrahedron: vtk_eltype = VTK_TETRA else: raise RuntimeError("unsupported element type: %s" % ldis.geometry) cell_types.extend([vtk_eltype] * len(smi) * len(eg.members)) self.grid = UnstructuredGrid( (len(discr), DataArray("points", discr.nodes, vector_format=VF_LIST_OF_VECTORS)), np.asarray(cells), cell_types=np.asarray(cell_types, dtype=np.uint8)) logger.info("init vtk visualizer: done") def update_pvd(self): if self.pvd_name and self.timestep_to_pathnames: from pyvisfile.vtk import XMLRoot, XMLElement, make_vtkfile collection = XMLElement("Collection") vtkf = make_vtkfile(collection.tag, compressor=None) xmlroot = XMLRoot(vtkf) vtkf.add_child(collection) from os.path import relpath, dirname rel_path_start = dirname(self.pvd_name) tsteps = self.timestep_to_pathnames.keys() tsteps.sort() for i, time in enumerate(tsteps): for part, pathname in enumerate( self.timestep_to_pathnames[time]): collection.add_child( XMLElement("DataSet", timestep=time, part=part, file=relpath(pathname, rel_path_start))) outf = open(self.pvd_name, "w") xmlroot.write(outf) outf.close() def do_close(self): self.update_pvd() def make_file(self, pathname): """ An appropriate extension (including the dot) is automatically appended to *pathname*. """ if self.pcontext is None or len(self.pcontext.ranks) == 1: return VtkFile(pathname + "." + self.grid.vtk_extension(), self.grid.copy(), compressor=self.compressor) else: from os.path import basename filename_pattern = (pathname + "-%05d." + self.grid.vtk_extension()) if self.pcontext.is_head_rank: return ParallelVtkFile(filename_pattern % self.pcontext.rank, self.grid.copy(), index_pathname="%s.p%s" % (pathname, self.grid.vtk_extension()), pathnames=[ basename(filename_pattern % rank) for rank in self.pcontext.ranks ], compressor=self.compressor) else: return VtkFile(filename_pattern % self.pcontext.rank, self.grid.copy(), compressor=self.compressor) def register_pathname(self, time, pathname): if time is not None and self.timestep_to_pathnames is not None: self.timestep_to_pathnames.setdefault(time, []).append(pathname) # When we are run under MPI and cancelled by Ctrl+C, destructors # do not get called. Therefore, we just spend the (hopefully negligible) # time to update the PVD index every few data additions. if len(self.timestep_to_pathnames) % 5 == 0: self.update_pvd() def add_data(self, visf, variables=[], scalars=[], vectors=[], time=None, step=None, scale_factor=1): if scalars or vectors: import warnings warnings.warn("`scalars' and `vectors' arguments are deprecated", DeprecationWarning) variables = scalars + vectors from pyvisfile.vtk import DataArray, VF_LIST_OF_COMPONENTS for name, field in variables: visf.grid.add_pointdata( DataArray(name, scale_factor * field, vector_format=VF_LIST_OF_COMPONENTS)) self.register_pathname(time, visf.get_head_pathname())
def write_vertex_vtk_file(mesh, file_name, compressor=None, overwrite=False): from pyvisfile.vtk import ( UnstructuredGrid, DataArray, AppendedDataXMLGenerator, VF_LIST_OF_COMPONENTS) # {{{ create cell_types from pyvisfile.vtk import ( VTK_LINE, VTK_TRIANGLE, VTK_TETRA, VTK_QUAD, VTK_HEXAHEDRON) from meshmode.mesh import TensorProductElementGroup, SimplexElementGroup cell_types = np.empty(mesh.nelements, dtype=np.uint8) cell_types.fill(255) for egrp in mesh.groups: if isinstance(egrp, SimplexElementGroup): vtk_cell_type = { 1: VTK_LINE, 2: VTK_TRIANGLE, 3: VTK_TETRA, }[egrp.dim] elif isinstance(egrp, TensorProductElementGroup): vtk_cell_type = { 1: VTK_LINE, 2: VTK_QUAD, 3: VTK_HEXAHEDRON, }[egrp.dim] else: raise NotImplementedError("mesh vtk file writing for " "element group of type '%s'" % type(egrp).__name__) cell_types[ egrp.element_nr_base: egrp.element_nr_base + egrp.nelements] = \ vtk_cell_type assert (cell_types != 255).all() # }}} # {{{ create cell connectivity cells = np.empty( sum(egrp.vertex_indices.size for egrp in mesh.groups), dtype=mesh.vertex_id_dtype) # NOTE: vtk uses z-order for the linear quads tensor_order = { 1: (0, 1), 2: (0, 1, 3, 2), 3: (0, 1, 3, 2, 4, 5, 7, 6) } vertex_nr_base = 0 for egrp in mesh.groups: i = np.s_[vertex_nr_base:vertex_nr_base + egrp.vertex_indices.size] if isinstance(egrp, SimplexElementGroup): cells[i] = egrp.vertex_indices.reshape(-1) elif isinstance(egrp, TensorProductElementGroup): cells[i] = egrp.vertex_indices[:, tensor_order[egrp.dim]].reshape(-1) else: raise TypeError("unsupported group type") vertex_nr_base += egrp.vertex_indices.size # }}} grid = UnstructuredGrid( (mesh.nvertices, DataArray("points", mesh.vertices, vector_format=VF_LIST_OF_COMPONENTS)), cells=cells, cell_types=cell_types) import os if os.path.exists(file_name): if overwrite: os.remove(file_name) else: raise FileExistsError("output file '%s' already exists" % file_name) with open(file_name, "w") as outf: AppendedDataXMLGenerator(compressor)(grid).write(outf)
def __init__(self, discr, pcontext=None, basename=None, compressor=None): logger.info("init vtk visualizer: start") hedge.tools.Closable.__init__(self) from pytools import assert_not_a_file if basename is not None: self.pvd_name = basename + ".pvd" assert_not_a_file(self.pvd_name) else: self.pvd_name = None self.pcontext = pcontext self.compressor = compressor if self.pcontext is None or self.pcontext.is_head_rank: self.timestep_to_pathnames = {} else: self.timestep_to_pathnames = None from pyvisfile.vtk import UnstructuredGrid, DataArray, \ VTK_LINE, VTK_TRIANGLE, VTK_TETRA, VF_LIST_OF_VECTORS from hedge.mesh.element import Interval, Triangle, Tetrahedron # For now, we use IntVector here because the Python allocator # is somewhat reluctant to return allocated chunks of memory # to the OS. from hedge._internal import IntVector cells = IntVector() cell_types = IntVector() for eg in discr.element_groups: ldis = eg.local_discretization smi = ldis.get_submesh_indices() cells.reserve(len(cells) + len(smi) * len(eg.members)) for el, el_slice in zip(eg.members, eg.ranges): for element in smi: for j in element: cells.append(el_slice.start + j) if ldis.geometry is Interval: vtk_eltype = VTK_LINE elif ldis.geometry is Triangle: vtk_eltype = VTK_TRIANGLE elif ldis.geometry is Tetrahedron: vtk_eltype = VTK_TETRA else: raise RuntimeError("unsupported element type: %s" % ldis.geometry) cell_types.extend([vtk_eltype] * len(smi) * len(eg.members)) self.grid = UnstructuredGrid( (len(discr), DataArray("points", discr.nodes, vector_format=VF_LIST_OF_VECTORS)), np.asarray(cells), cell_types=np.asarray(cell_types, dtype=np.uint8)) logger.info("init vtk visualizer: done")
from pyvisfile.vtk import (UnstructuredGrid, DataArray, AppendedDataXMLGenerator, VTK_VERTEX, VF_LIST_OF_VECTORS, VF_LIST_OF_COMPONENTS) n = 5000 points = np.random.randn(n, 3) data = [ ("p", np.random.randn(n)), ("vel", np.random.randn(3, n)), ] file_name = "points.vtu" compressor = None grid = UnstructuredGrid( (n, DataArray("points", points, vector_format=VF_LIST_OF_VECTORS)), cells=np.arange(n, dtype=np.uint32), cell_types=np.asarray([VTK_VERTEX] * n, dtype=np.uint8)) for name, field in data: grid.add_pointdata( DataArray(name, field, vector_format=VF_LIST_OF_COMPONENTS)) from os.path import exists if exists(file_name): raise RuntimeError("output file '%s' already exists" % file_name) outf = open(file_name, "w") AppendedDataXMLGenerator(compressor)(grid).write(outf) outf.close()
UnstructuredGrid, DataArray, AppendedDataXMLGenerator, VTK_VERTEX, VF_LIST_OF_VECTORS, VF_LIST_OF_COMPONENTS) n = 5000 points = np.random.randn(n, 3) data = [ ("p", np.random.randn(n)), ("vel", np.random.randn(3, n)), ] file_name = "points.vtu" compressor = None grid = UnstructuredGrid( (n, DataArray("points", points, vector_format=VF_LIST_OF_VECTORS)), cells=np.arange(n, dtype=np.uint32), cell_types=np.asarray([VTK_VERTEX] * n, dtype=np.uint8)) for name, field in data: grid.add_pointdata(DataArray(name, field, vector_format=VF_LIST_OF_COMPONENTS)) from os.path import exists if exists(file_name): raise RuntimeError("output file '%s' already exists" % file_name) outf = open(file_name, "w") AppendedDataXMLGenerator(compressor)(grid).write(outf) outf.close()
def write_vtk_file(self, file_name, names_and_fields, compressor=None, real_only=False, overwrite=False): from pyvisfile.vtk import (UnstructuredGrid, DataArray, AppendedDataXMLGenerator, VF_LIST_OF_COMPONENTS) with cl.CommandQueue(self.vis_discr.cl_context) as queue: nodes = self.vis_discr.nodes().with_queue(queue).get() names_and_fields = [(name, self._resample_and_get(queue, fld)) for name, fld in names_and_fields] vc_groups = self._vis_connectivity() # {{{ create cell_types nsubelements = sum(vgrp.nsubelements for vgrp in vc_groups) cell_types = np.empty(nsubelements, dtype=np.uint8) cell_types.fill(255) for vgrp in vc_groups: cell_types[ vgrp.subelement_nr_base: vgrp.subelement_nr_base + vgrp.nsubelements] = \ vgrp.vtk_cell_type assert (cell_types < 255).all() # }}} if self.element_shrink_factor != 1: for vgrp in self.vis_discr.groups: nodes_view = vgrp.view(nodes) el_centers = np.mean(nodes_view, axis=-1) nodes_view[:] = ((self.element_shrink_factor * nodes_view) + (1 - self.element_shrink_factor) * el_centers[:, :, np.newaxis]) grid = UnstructuredGrid( (self.vis_discr.nnodes, DataArray("points", nodes.reshape(self.vis_discr.ambient_dim, -1), vector_format=VF_LIST_OF_COMPONENTS)), cells=np.hstack( [vgrp.vis_connectivity.reshape(-1) for vgrp in vc_groups]), cell_types=cell_types) # for name, field in separate_by_real_and_imag(cell_data, real_only): # grid.add_celldata(DataArray(name, field, # vector_format=VF_LIST_OF_COMPONENTS)) for name, field in separate_by_real_and_imag(names_and_fields, real_only): grid.add_pointdata( DataArray(name, field, vector_format=VF_LIST_OF_COMPONENTS)) import os from meshmode import FileExistsError if os.path.exists(file_name): if overwrite: os.remove(file_name) else: raise FileExistsError("output file '%s' already exists" % file_name) with open(file_name, "w") as outf: AppendedDataXMLGenerator(compressor)(grid).write(outf)