1"""Python wrappers for MOAB Types.""" 2 3from pymoab cimport moab 4from pymoab cimport tag_conventions 5 6cimport numpy as np 7import numpy as np 8 9_eh_py_type = np.uint64 10 11cdef class MOABErrorCode: 12 13 cdef readonly moab.ErrorCode error_value 14 15 cdef readonly dict err_strings 16 def __cinit__(self, value = 0): 17 if isinstance(value, MOABErrorCode): 18 self.error_value = value.error_value 19 else: 20 self.error_value = <moab.ErrorCode> value 21 22 self.err_strings = { moab.MB_SUCCESS : "MB_SUCCESS", 23 moab.MB_INDEX_OUT_OF_RANGE : "MB_INDEX_OUT_OF_RANGE", 24 moab.MB_TYPE_OUT_OF_RANGE : "MB_TYPE_OUT_OF_RANGE", 25 moab.MB_MEMORY_ALLOCATION_FAILED : "MB_MEMORY_ALLOCATION_FAILED", 26 moab.MB_ENTITY_NOT_FOUND : "MB_ENTITY_NOT_FOUND", 27 moab.MB_MULTIPLE_ENTITIES_FOUND : "MB_MULTIPLE_ENTITIES_FOUND", 28 moab.MB_TAG_NOT_FOUND : "MB_TAG_NOT_FOUND", 29 moab.MB_FILE_DOES_NOT_EXIST : "MB_FILE_DOES_NOT_EXIST", 30 moab.MB_FILE_WRITE_ERROR : "MB_FILE_WRITE_ERROR", 31 moab.MB_NOT_IMPLEMENTED : "MB_NOT_IMPLEMENTED", 32 moab.MB_ALREADY_ALLOCATED : "MB_ALREADY_ALLOCATED", 33 moab.MB_VARIABLE_DATA_LENGTH : "MB_VARIABLE_DATA_LENGTH", 34 moab.MB_INVALID_SIZE : "MB_INVALID_SIZE", 35 moab.MB_UNSUPPORTED_OPERATION : "MB_UNSUPPORTED_OPERATION", 36 moab.MB_UNHANDLED_OPTION : "MB_UNHANDLED_OPTION", 37 moab.MB_STRUCTURED_MESH : "MB_STRUCTURED_MESH", 38 moab.MB_FAILURE : "MB_FAILURE" } 39 40 def __richcmp__(self, other, op): 41 if op == 2: 42 if isinstance(other, MOABErrorCode): 43 return self.error_value == other.error_value 44 elif type(other) == int: 45 return self.error_value == other 46 else: 47 return NotImplemented 48 49 def __hash__(self): 50 return self.error_value 51 52 def __repr__(self): 53 return self.__str__() 54 55 def __str__(self): 56 return "MOAB ErrorCode: "+self.err_strings[self.error_value] 57 58 59# Error codes 60MB_SUCCESS = MOABErrorCode(moab.MB_SUCCESS) 61MB_INDEX_OUT_OF_RANGE = MOABErrorCode(moab.MB_INDEX_OUT_OF_RANGE) 62MB_TYPE_OUT_OF_RANGE = MOABErrorCode(moab.MB_TYPE_OUT_OF_RANGE) 63MB_MEMORY_ALLOCATION_FAILED = MOABErrorCode(moab.MB_MEMORY_ALLOCATION_FAILED) 64MB_ENTITY_NOT_FOUND = MOABErrorCode(moab.MB_ENTITY_NOT_FOUND) 65MB_MULTIPLE_ENTITIES_FOUND = MOABErrorCode(moab.MB_MULTIPLE_ENTITIES_FOUND) 66MB_TAG_NOT_FOUND = MOABErrorCode(moab.MB_TAG_NOT_FOUND) 67MB_FILE_DOES_NOT_EXIST = MOABErrorCode(moab.MB_FILE_DOES_NOT_EXIST) 68MB_FILE_WRITE_ERROR = MOABErrorCode(moab.MB_FILE_WRITE_ERROR) 69MB_NOT_IMPLEMENTED = MOABErrorCode(moab.MB_NOT_IMPLEMENTED) 70MB_ALREADY_ALLOCATED = MOABErrorCode(moab.MB_ALREADY_ALLOCATED) 71MB_VARIABLE_DATA_LENGTH = MOABErrorCode(moab.MB_VARIABLE_DATA_LENGTH) 72MB_INVALID_SIZE = MOABErrorCode(moab.MB_INVALID_SIZE) 73MB_UNSUPPORTED_OPERATION = MOABErrorCode(moab.MB_UNSUPPORTED_OPERATION) 74MB_UNHANDLED_OPTION = MOABErrorCode(moab.MB_UNHANDLED_OPTION) 75MB_STRUCTURED_MESH = MOABErrorCode(moab.MB_STRUCTURED_MESH) 76MB_FAILURE = MOABErrorCode(moab.MB_FAILURE) 77 78 79cdef dict _ERROR_MSGS = { 80 MB_INDEX_OUT_OF_RANGE: (IndexError, 'MOAB index out of range'), 81 MB_TYPE_OUT_OF_RANGE: (TypeError, 'Incorrect MOAB type, out of range'), 82 MB_MEMORY_ALLOCATION_FAILED: (MemoryError, 'MOAB memory allocation'), 83 MB_ENTITY_NOT_FOUND: (RuntimeError, 'Entity not found'), 84 MB_MULTIPLE_ENTITIES_FOUND: (RuntimeError, 'Multiple entities found'), 85 MB_TAG_NOT_FOUND: (RuntimeError, 'Tag not found'), 86 MB_FILE_DOES_NOT_EXIST: (IOError, 'File not found'), 87 MB_FILE_WRITE_ERROR: (IOError, 'File write error'), 88 MB_NOT_IMPLEMENTED: (NotImplementedError, '[MOAB]'), 89 MB_ALREADY_ALLOCATED: (MemoryError, 'already allocated'), 90 MB_VARIABLE_DATA_LENGTH: (TypeError, 'variable length data'), 91 MB_INVALID_SIZE: (ValueError, 'invalid size'), 92 MB_UNSUPPORTED_OPERATION: (RuntimeError, 'unsupported operation'), 93 MB_UNHANDLED_OPTION: (RuntimeError, 'unhandled option'), 94 MB_STRUCTURED_MESH: (RuntimeError, 'structured mesh'), 95 MB_FAILURE: (RuntimeError, '[MOAB] failure'), 96 } 97 98def check_error(err, tuple exceptions = (), **kwargs): 99 """Checks error status code and raises error if needed.""" 100 for exception in exceptions: 101 if exception == err: 102 return 103 if err == MB_SUCCESS: 104 return 105 errtype, msg = _ERROR_MSGS[err] 106 if len(kwargs) > 0: 107 msg += ': ' 108 msg += ', '.join(sorted(['{0}={1!r}'.format(k, v) for k, v in kwargs.items()])) 109 raise errtype(MOABErrorCode(err)) 110 111# Data Types 112MB_TYPE_OPAQUE = moab.MB_TYPE_OPAQUE 113MB_TYPE_INTEGER = moab.MB_TYPE_INTEGER 114MB_TYPE_DOUBLE = moab.MB_TYPE_DOUBLE 115MB_TYPE_BIT = moab.MB_TYPE_BIT 116MB_TYPE_HANDLE = moab.MB_TYPE_HANDLE 117MB_MAX_DATA_TYPE = moab.MB_MAX_DATA_TYPE 118 119 120_TAG_TYPE_STRS = { 121 MB_TYPE_OPAQUE : "MB_TYPE_OPAQUE", 122 MB_TYPE_INTEGER : "MB_TYPE_INTEGER", 123 MB_TYPE_DOUBLE : "MB_TYPE_DOUBLE", 124 MB_TYPE_BIT : "MB_TYPE_BIT", 125 MB_TYPE_HANDLE : "MB_TYPE_HANDLE", 126 MB_MAX_DATA_TYPE : "MB_MAX_DATA_TYPE" 127} 128 129_DTYPE_CONV = { 130 MB_TYPE_OPAQUE: 'S', 131 MB_TYPE_INTEGER: 'int32', 132 MB_TYPE_DOUBLE: 'float64', 133 MB_TYPE_BIT: 'bool', 134 MB_TYPE_HANDLE: 'uint64', 135 MB_MAX_DATA_TYPE: 'uint64' 136} 137 138_VALID_DTYPES= { 139 MB_TYPE_OPAQUE: frozenset(['S','U','O','object']), 140 MB_TYPE_INTEGER: frozenset(['i','int8','int16','int32','int64','O','object']), 141 MB_TYPE_DOUBLE: frozenset(['float64','float','f8','f', 'O','object',]), 142 MB_TYPE_BIT: frozenset(['f','int8','int16','int32','int64','S1','bool','O','object']), 143 MB_TYPE_HANDLE: frozenset(['uint64','O','object']), 144 MB_MAX_DATA_TYPE: frozenset(['uint64','O','object']) 145} 146 147_VALID_NATIVE_TYPES = { 148 int: MB_TYPE_INTEGER, 149 float: MB_TYPE_DOUBLE, 150 str: MB_TYPE_OPAQUE, 151 object: MB_TYPE_OPAQUE, 152 np.uint64 : MB_TYPE_HANDLE 153} 154 155def pymoab_data_type(input_type): 156 """ 157 Attempts to find a PyMOAB datatype given a Python native type or 158 NumPy dtype 159 """ 160 161 # check native types 162 try: 163 t = _VALID_NATIVE_TYPES[input_type] 164 return t 165 except KeyError: 166 print("Checking all types...") 167 pass 168 169 # check valid dtypes 170 for k in _VALID_DTYPES.keys(): 171 if input_type in _VALID_DTYPES[k]: 172 return k 173 174 raise ValueError("Could not determine the PyMOAB data type.") 175 176def _convert_array(iterable, accepted_types, return_dtype): 177 err_msg = "Incorrect datatype found in array: {}" 178 #if this is already an array of the correct type, avoid the loop 179 if isinstance(iterable, np.ndarray) and iterable.dtype == return_dtype: 180 return iterable 181 #if not, each entry in the iterable should be verified 182 for entry in iterable: 183 assert (isinstance(entry, accepted_types)), err_msg.format(type(entry)) 184 #if this is true, then create an array from the iterable 185 return np.fromiter(iterable, return_dtype) 186 187def _eh_array(iterable): 188 err_msg = """ 189 Invalid EntityHandle type is being used. Please ensure all 190 EntityHandles are either Python type long or NumPy dtype uint64. 191 """ 192 # get dtype for EntityHandles 193 EH_DTYPE = _DTYPE_CONV[MB_TYPE_HANDLE] 194 # try to convert array 195 try: 196 arr = _convert_array(iterable, (_eh_py_type,), EH_DTYPE) 197 except: 198 raise ValueError(err_msg) 199 # return array if successful 200 return arr 201 202def np_tag_type(type): 203 return _DTYPE_CONV[type] 204 205def validate_type(tag_type,tag_length,tag_data): 206 207 #ensure this type is supported 208 assert tag_type in _DTYPE_CONV.keys(), "Invalid Tag Type" 209 #and that it is the correct shape 210 assert tag_data.ndim == 0 or tag_data.ndim == 1, "Not a flat array" 211 212 213 if MB_TYPE_OPAQUE == tag_type: 214 #so long as the array is some kind of string type, we're happy 215 is_valid = tag_data.dtype.char in _VALID_DTYPES[tag_type] 216 final_type = _DTYPE_CONV[tag_type]+str(tag_length) 217 else: 218 is_valid = str(tag_data.dtype) in _VALID_DTYPES[tag_type] 219 final_type = _DTYPE_CONV[tag_type] 220 221 assert is_valid, "Data is invalid for Tag. Please verify data length and type." 222 tag_data = np.asarray(tag_data, dtype=final_type) 223 return tag_data 224 225# Entity types 226MBVERTEX = moab.MBVERTEX 227MBEDGE = moab.MBEDGE 228MBTRI = moab.MBTRI 229MBQUAD = moab.MBQUAD 230MBPOLYGON = moab.MBPOLYGON 231MBTET = moab.MBTET 232MBPYRAMID = moab.MBPYRAMID 233MBPRISM = moab.MBPRISM 234MBKNIFE = moab.MBKNIFE 235MBHEX = moab.MBHEX 236MBPOLYHEDRON = moab.MBPOLYHEDRON 237MBENTITYSET = moab.MBENTITYSET 238MBMAXTYPE = moab.MBMAXTYPE 239 240# Tag Types 241MB_TAG_BIT = moab.MB_TAG_BIT 242MB_TAG_SPARSE = moab.MB_TAG_SPARSE 243MB_TAG_DENSE = moab.MB_TAG_DENSE 244MB_TAG_MESH = moab.MB_TAG_MESH 245MB_TAG_BYTES = moab.MB_TAG_BYTES 246MB_TAG_VARLEN = moab.MB_TAG_VARLEN 247MB_TAG_CREAT = moab.MB_TAG_CREAT 248MB_TAG_EXCL = moab.MB_TAG_EXCL 249MB_TAG_STORE = moab.MB_TAG_STORE 250MB_TAG_ANY = moab.MB_TAG_ANY 251MB_TAG_NOOPQ = moab.MB_TAG_NOOPQ 252MB_TAG_DFTOK = moab.MB_TAG_DFTOK 253 254# Query selection types 255INTERSECT = 0 256UNION = 1 257 258MESHSET_TRACK_OWNER = moab.MESHSET_TRACK_OWNER 259MESHSET_SET = moab.MESHSET_SET 260MESHSET_ORDERED = moab.MESHSET_ORDERED 261 262MATERIAL_SET_TAG_NAME = str(tag_conventions.MATERIAL_SET_TAG_NAME.decode()) 263DIRICHLET_SET_TAG_NAME = str(tag_conventions.DIRICHLET_SET_TAG_NAME.decode()) 264NEUMANN_SET_TAG_NAME = str(tag_conventions.NEUMANN_SET_TAG_NAME.decode()) 265HAS_MID_NODES_TAG_NAME = str(tag_conventions.HAS_MID_NODES_TAG_NAME.decode()) 266GEOM_DIMENSION_TAG_NAME = str(tag_conventions.GEOM_DIMENSION_TAG_NAME.decode()) 267MESH_TRANSFORM_TAG_NAME = str(tag_conventions.MESH_TRANSFORM_TAG_NAME.decode()) 268GLOBAL_ID_TAG_NAME = str(tag_conventions.GLOBAL_ID_TAG_NAME.decode()) 269CATEGORY_TAG_NAME = str(tag_conventions.CATEGORY_TAG_NAME.decode()) 270CATEGORY_TAG_SIZE = tag_conventions.CATEGORY_TAG_SIZE 271NAME_TAG_NAME = str(tag_conventions.NAME_TAG_NAME.decode()) 272NAME_TAG_SIZE = tag_conventions.NAME_TAG_SIZE 273