Source code for steps.API_1.utilities.steps_shadow

####################################################################################
#
#    STEPS - STochastic Engine for Pathway Simulation
#    Copyright (C) 2007-2023 Okinawa Institute of Science and Technology, Japan.
#    Copyright (C) 2003-2006 University of Antwerp, Belgium.
#    
#    See the file AUTHORS for details.
#    This file is part of STEPS.
#    
#    STEPS is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License version 3,
#    as published by the Free Software Foundation.
#    
#    STEPS is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#    GNU General Public License for more details.
#    
#    You should have received a copy of the GNU General Public License
#    along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#################################################################################   
###
from __future__ import print_function

try:
    import cPickle as Pickle
except ImportError:
    import pickle as Pickle

try:
    import steps
    HAS_STEPS = True
except ImportError:
    HAS_STEPS = False

ELEM_VERTEX = 0
ELEM_TRI = 1
ELEM_TET = 2
ELEM_UNDEFINED = 99

################################################################################
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
################################################################################

[docs]class ShadowComp: """ Shadow class for STEPS compartment. Parameters: * name Name of the compartment * mesh ShadowMesh object * indices Indices of the tetrahedrons in the compartment * vsyss List of ids of the associated volume systems """ def __init__(self, name, mesh, indices, vsyss): """ Constructor. """ self.name = name self.indices = indices if not isinstance(vsyss, list): raise Exception("vsyss should be a list of volume system ids.") self.vsyss = vsyss mesh.addComp(self)
[docs] def exportTo(self, file): """ Export data to a given file. Parameters: * file File for the exporting Return: None """ Pickle.dump(self.name, file) Pickle.dump(self.indices, file) Pickle.dump(self.vsyss, file)
[docs] @staticmethod def importFrom(mesh, file): """ Import data from a given file and create a ShadowComp object according to the data. Parameters: * mesh Associated ShadowMesh file * file File for the importing Return: ShadowComp object """ name = Pickle.load(file) indices = Pickle.load(file) vsyss = Pickle.load(file) return ShadowComp(name, mesh, indices, vsyss)
################################################################################ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ################################################################################ class ShadowPatch: """ Shadow class for STEPS patch. Parameters: * name Name of the patch * mesh ShadowMesh object * indices Indices of the triangles in the patch * ssyss List of ids of the associated surface systems * icomp Inner ShadowComp object * ocomp Outer ShadowComp object """ def __init__(self, name, mesh, indices, ssyss, icomp, ocomp = None): """ Constructor. """ self.name = name self.indices = indices if not isinstance(ssyss, list): raise Exception("ssyss should be a list of surface system ids.") self.ssyss = ssyss self.icomp = icomp self.ocomp = ocomp mesh.addPatch(self) def exportTo(self, file): """ Export data to a given file. Parameters: * file File for the exporting Return: None """ Pickle.dump(self.name, file) Pickle.dump(self.indices, file) Pickle.dump(self.ssyss, file) Pickle.dump(self.icomp.name, file) if self.ocomp != None: Pickle.dump(self.ocomp.name, file) else: Pickle.dump(None, file) @staticmethod def importFrom(mesh, file): """ Import data from a given file and create a ShadowPatch object according to the data. Parameters: * mesh Associated ShadowMesh file * file File for the importing Return: ShadowPatch object """ name = Pickle.load(file) indices = Pickle.load(file) ssyss = Pickle.load(file) icomp = mesh.comps[Pickle.load(file)] ocomp = Pickle.load(file) if ocomp != None: ocomp = mesh.comps[ocomp] return ShadowPatch(name, mesh, indices, ssyss, icomp, ocomp) ################################################################################ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ################################################################################ ################################################################################ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ################################################################################
[docs]class ShadowPatch: """ Shadow class for STEPS patch. Parameters: * name Name of the patch * mesh ShadowMesh object * indices Indices of the triangles in the patch * ssyss List of ids of the associated surface systems * icomp Inner ShadowComp object * ocomp Outer ShadowComp object """ def __init__(self, name, mesh, indices, ssyss, icomp, ocomp = None): """ Constructor. """ self.name = name self.indices = indices if not isinstance(ssyss, list): raise Exception("ssyss should be a list of surface system ids.") self.ssyss = ssyss self.icomp = icomp self.ocomp = ocomp mesh.addPatch(self)
[docs] def exportTo(self, file): """ Export data to a given file. Parameters: * file File for the exporting Return: None """ Pickle.dump(self.name, file) Pickle.dump(self.indices, file) Pickle.dump(self.ssyss, file) Pickle.dump(self.icomp.name, file) if self.ocomp != None: Pickle.dump(self.ocomp.name, file) else: Pickle.dump(None, file)
[docs] @staticmethod def importFrom(mesh, file): """ Import data from a given file and create a ShadowPatch object according to the data. Parameters: * mesh Associated ShadowMesh file * file File for the importing Return: ShadowPatch object """ name = Pickle.load(file) indices = Pickle.load(file) ssyss = Pickle.load(file) icomp = mesh.comps[Pickle.load(file)] ocomp = Pickle.load(file) if ocomp != None: ocomp = mesh.comps[ocomp] return ShadowPatch(name, mesh, indices, ssyss, icomp, ocomp)
################################################################################ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ################################################################################
[docs]class ShadowMesh: """ Shadow class for STEPS mesh. Parameters: None """ def __init__(self): self.included_tets = set([]) self.included_tris = set([]) self.comps = {} self.patches = {} self.rois = {}
[docs] def addComp(self, comp): """ Add a compartment to the mesh. Note: Internal method, should use Comp(name, mesh, indices, vsys) instead. """ if comp.name in self.comps: raise Exception("Compartment with name " + comp.name + " already exists.") intersect = self.included_tets & set(comp.indices) if len(intersect) != 0: raise Exception("The following tetrahedrons have been assigned to other compartment: " + str(intersect)) self.comps[comp.name] = comp self.included_tets = self.included_tets | set(comp.indices)
[docs] def addPatch(self, patch): """ Add a patch to the mesh. Note: Internal method, should use Patch(name, mesh, indices, ssys, icomp, ocomp) instead. """ if patch.name in self.patches: raise Exception("Patch with name " + patch.name + " already exists.") intersect = self.included_tris & set(patch.indices) if len(intersect) != 0: raise Exception("The following triangles have been assigned to other patch: " + str(intersect)) if patch.icomp.name not in self.comps: raise Exception("Compartment " + patch.icomp.name + " does not exist.") if patch.ocomp != None: if patch.ocomp.name != None and (patch.ocomp.name not in self.comps): raise Exception("Compartment " + patch.ocomp.name + " does not exist.") self.patches[patch.name] = patch self.included_tris = self.included_tris | set(patch.indices)
[docs] def addROI(self, roi_name, type, indices): """ Add Region of Interest Data. Parameters: * roi_name Name of the region of interest * type Type of the elements * indices Indices of the elements Return: None """ if roi_name in self.rois: raise Exception("Region of Interest " + roi_name + " already exists.") self.rois[roi_name] = {"Type":type, "Indices":set(indices)}
[docs] def removeROI(self, roi_name): """ Remove Region of Interest Data. Parameters: * roi_name Name of the region of interest Return: None """ if roi_name not in self.rois: raise Exception("Region of Interest " + roi_name + " does not exist.") self.rois.pop(roi_name)
[docs] def exportTo(self, file_name): """ Export data to a given file. Parameters: * file File for the exporting Return: None """ with open(file_name, "wb") as file: Pickle.dump(len(self.comps), file) Pickle.dump(len(self.patches), file) for c in self.comps.values(): c.exportTo(file) for p in self.patches.values(): p.exportTo(file) Pickle.dump(self.rois, file)
[docs] @staticmethod def importFrom(file_name): """ Import data from a given file and create a ShadowMesh object according to the data. Parameters: * file File for the importing Return: ShadowMesh object """ with open(file_name, "rb") as file: mesh = ShadowMesh() ncomps = Pickle.load(file) npatches = Pickle.load(file) for c in range(ncomps): comp = ShadowComp.importFrom(mesh, file) for p in range(npatches): patch = ShadowPatch.importFrom(mesh, file) mesh.rois = Pickle.load(file) return mesh
[docs] def writeToTetmesh(self, tetmesh, node_proxy, tet_proxy, tri_proxy): """ Write data to STEPS Tetmesh object. Parameters: * tetmesh STEPS Tetmesh object * node_proxy ElementProxy object for nodes * tet_proxy ElementProxy object for tetrahedrons * tri_proxy ElementProxy object for triangles Return: ShadowMesh object """ if not HAS_STEPS: raise Exception("This function is not available without STEPS integration with CUBIT.") else: temp_comps = {} for c in self.comps.values(): print("Write compartment ", c.name, " to Tetmesh.") steps_indices = [tetproxy.getSTEPSID(i) for i in c.indices] comp = sgeom.TmComp(c.name, tetmesh, steps_indices) temp_comps[c.name] = comp for v in c.vsyss: comp.addVolsys(v) if len(self.patches) != 0: if tri_proxy.getSize() == 0: print("ImportAbaqus does not support triangle index mapping, use ImportAbaqus2 instead.") else: for p in self.patches.values(): print("Write patch ", p.name, " to Tetmesh.") steps_indices = [triproxy.getSTEPSID(i) for i in c.indices] icomp = temp_comps[p.icomp] ocomp = None if p.ocomp != None: ocomp = temp_comps[p.ocomp] patch = sgeom.TmPatch(p.name, tetmesh, steps_indices, icomp, ocomp) for s in c.ssyss: patch.addSurfsys(s) for roi in self.rois.items(): roi_name = roi[0] roi_type = roi[1]["Type"] roi_import_indices = roi[1]["Indices"] print("Write ROI data ", roi[0], " to Tetmesh.") if roi_type == ELEM_VERTEX: steps_indices = [nodeproxy.getSTEPSID(i) for i in roi_import_indices] elif roi_type == ELEM_TET: steps_indices = [tetproxy.getSTEPSID(i) for i in roi_import_indices] elif roi_type == ELEM_TRI: if tri_proxy.getSize() == 0: print("ImportAbaqus does not support triangle index mapping, use ImportAbaqus2 instead.") else: steps_indices = [triproxy.getSTEPSID(i) for i in roi_import_indices] else: steps_indices = roi_import_indices tetmesh.addROI(roi_name, roi_type, steps_indices)
################################################################################ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ################################################################################