[docs]classOcTreeReader(ubcMeshReaderBase):"""This class reads a UBC OcTree Mesh file and builds a ``vtkUnstructuredGrid`` of the data in the file. Model File is optional. Reader will still construct ``vtkUnstructuredGrid`` safely. """__displayname__='UBC OcTree Mesh Reader'__category__='reader'description='PVGeo: UBC OcTree Mesh'def__init__(self,nOutputPorts=1,outputType='vtkUnstructuredGrid',**kwargs):ubcMeshReaderBase.__init__(self,nOutputPorts=nOutputPorts,outputType=outputType,**kwargs)self.__mesh=Noneself.__models=[]
[docs]defubc_octree_mesh(self,FileName,pdo=None):"""This method reads a UBC OcTree Mesh file and builds a ``vtkUnstructuredGrid`` of the data in the file. This method generates the ``vtkUnstructuredGrid`` without any data attributes. Args: FileName (str): The mesh filename as an absolute path for the input mesh file in UBC OcTree format. pdo (vtkUnstructuredGrid): A pointer to the output data object. Return: vtkUnstructuredGrid: a ``vtkUnstructuredGrid`` generated from the UBCMesh grid. Mesh is defined by the input mesh file. No data attributes here, simply an empty mesh. Use the ``place_model_on_octree_mesh()`` method to associate with model data. """try:self.__mesh=discretize.TreeMesh.read_UBC(FileName)except(IOError,OSError)asfe:raise_helpers.PVGeoError(str(fe))ifpdoisNone:pdo=self.__mesh.to_vtk()else:pdo.DeepCopy(self.__mesh.to_vtk())returnpdo
[docs]@staticmethoddefplace_model_on_octree_mesh(mesh,model,data_name='Data'):"""Places model data onto a mesh. This is for the UBC Grid data readers to associate model data with the mesh grid. Args: mesh (vtkUnstructuredGrid): The ``vtkUnstructuredGrid`` that is the mesh to place the model data upon. Needs to have been read in by ubcOcTree model (np.ndarray): A NumPy float array that holds all of the data to place inside of the mesh's cells. data_name (str): The name of the model data array once placed on the ``vtkUnstructuredGrid``. Return: vtkUnstructuredGrid: The input ``vtkUnstructuredGrid`` with model data appended. """ifisinstance(model,dict):forkeyinmodel.keys():mesh=OcTreeReader.place_model_on_octree_mesh(mesh,model[key],data_name=key)returnmesh# Make sure this model file fits the dimensions of the meshnumCells=mesh.GetNumberOfCells()ifnumCells<len(model):raise_helpers.PVGeoError('This model file has more data than the given mesh has cells to hold.')elifnumCells>len(model):raise_helpers.PVGeoError('This model file does not have enough data to fill the given mesh\'s cells.')# This is absolutely crucial!# Do not play with unless you know what you are doing!# Also note that this assumes ``discretize`` handles addin this arrayind_reorder=nps.vtk_to_numpy(mesh.GetCellData().GetArray('index_cell_corner'))model=model[ind_reorder]# Convert data to VTK data structure and append to outputc=interface.convert_array(model,name=data_name,deep=True)# THIS IS CELL DATA! Add the model data to CELL data:mesh.GetCellData().AddArray(c)returnmesh
def__ubc_octree(self,filename_mesh,filename_models,output):"""Wrapper to Read UBC GIF OcTree mesh and model file pairs. UBC OcTree models are defined using a 2-file format. The "mesh" file describes how the data is descritized. The "model" file lists the physical property values for all cells in a mesh. A model file is meaningless without an associated mesh file. This only handles OcTree formats Args: filename_mesh (str): The OcTree Mesh filename as an absolute path for the input mesh file in UBC OcTree Mesh Format filename_models (list(str)): The model filenames as absolute paths for the input model timesteps in UBC OcTree Model Format. output (vtkUnstructuredGrid): The output data object Return: vtkUnstructuredGrid: A ``vtkUnstructuredGrid`` generated from the UBC 2D/3D Mesh grid. Mesh is defined by the input mesh file. Cell data is defined by the input model file. """ifself.need_to_readMesh():# Construct/read the meshself.ubc_octree_mesh(filename_mesh,pdo=output)self.need_to_readMesh(flag=False)output.DeepCopy(self.__mesh.to_vtk())ifself.need_to_readModels()andself.this_has_models():# Read the model dataself.__models=[]forfinfilename_models:# Read the model dataself.__models.append(ubcMeshReaderBase.ubc_model_3d(f))self.need_to_readModels(flag=False)returnoutput
[docs]defRequestData(self,request,inInfo,outInfo):"""Used by pipeline to generate output"""# Get output:output=self.GetOutputData(outInfo,0)# Get requested time indexi=_helpers.get_requested_time(self,outInfo)self.__ubc_octree(self.get_mesh_filename(),self.get_model_filenames(),output)# Place the model data for given timestep onto the meshiflen(self.__models)>i:self.place_model_on_octree_mesh(output,self.__models[i],self.get_data_name())return1
[docs]defRequestInformation(self,request,inInfo,outInfo):"""Pipeline method for handling requests about the grid extents and time step values """# Call parent to handle time stuffubcMeshReaderBase.RequestInformation(self,request,inInfo,outInfo)# Now set whole output extentifself.need_to_readMesh():ext=self._read_extent()info=outInfo.GetInformationObject(0)# Set WHOLE_EXTENT: This is absolutely necessaryinfo.Set(vtk.vtkStreamingDemandDrivenPipeline.WHOLE_EXTENT(),ext,6)return1
[docs]defclear_mesh(self):"""Use to clean/rebuild the mesh."""self.__mesh=vtk.vtkUnstructuredGrid()ubcMeshReaderBase.clear_models(self)
[docs]defclear_models(self):"""Use to clean the models and reread the data"""self.__models=[]ubcMeshReaderBase.clear_models(self)
[docs]classOcTreeAppender(ModelAppenderBase):"""This filter reads a timeseries of models and appends it to an input ``vtkUnstructuredGrid`` """__displayname__='UBC OcTree Mesh Appender'__category__='filter'def__init__(self,**kwargs):ModelAppenderBase.__init__(self,inputType='vtkUnstructuredGrid',outputType='vtkUnstructuredGrid',**kwargs)
[docs]def_read_up_front(self):"""Internal helper to read all data at start"""reader=ubcMeshReaderBase.ubc_model_3dself._models=[]forfinself._model_filenames:# Read the model dataself._models.append(reader(f))self.need_to_read(flag=False)return
[docs]def_place_on_mesh(self,output,idx=0):"""Internal helper to place a model on the mesh for a given index"""OcTreeReader.place_model_on_octree_mesh(output,self._models[idx],self.get_data_name())return