1"""Implements core functionality.""" 2from cython.operator cimport dereference as deref 3 4cimport numpy as np 5import numpy as np 6import ctypes 7 8from pymoab cimport moab 9from pymoab cimport eh 10 11from .tag cimport Tag, _tagArray 12from .rng cimport Range 13from .types import check_error, np_tag_type, validate_type, _convert_array, _eh_array, _eh_py_type 14from . import types 15from libcpp.vector cimport vector 16from libcpp.string cimport string as std_string 17from libc.stdlib cimport malloc 18 19from collections import Iterable 20 21cdef void* null = NULL 22 23cdef class Core(object): 24 25 def __cinit__(self): 26 """ Constructor """ 27 self.inst = new moab.Core() 28 29 def __del__(self): 30 """ Destructor """ 31 del self.inst 32 33 def impl_version(self): 34 """MOAB implementation number as a float.""" 35 return self.inst.impl_version() 36 37 def load_file(self, str fname, file_set = None, exceptions = ()): 38 """ 39 Load or import a file. 40 41 Load a MOAB-native file or import data from some other supported file format. 42 43 Example 44 ------- 45 mb = pymoab.core.Core() 46 mb.load_file("/location/of/my_file.h5m") 47 48 OR 49 50 fs = mb.create_meshset() 51 mb = pymoab.core.Core() 52 mb.load_file("/location/of/my_file.h5m", fs) 53 54 Parameters 55 ---------- 56 fname : string 57 The location of the file to read. 58 file_set : EntityHandle (default None) 59 If not None, this argument must be a valid 60 entity set handle. All entities read from the file will be added to 61 this set. File metadata will be added to tags on the set. 62 exceptions : tuple 63 A tuple containing any error types that should 64 be ignored. (see pymoab.types module for more info) 65 66 Returns 67 ------- 68 None. 69 70 Raises 71 ------ 72 MOAB ErrorCode 73 if a MOAB error occurs 74 ValueError 75 if a parameter is not of the correct type 76 """ 77 cdef bytes cfname = fname.encode('UTF-8') 78 cdef eh.EntityHandle fset 79 cdef eh.EntityHandle* ptr 80 if file_set != None: 81 fset = file_set 82 ptr = &fset 83 else: 84 ptr = NULL 85 cdef const char * file_name = cfname 86 cdef moab.ErrorCode err = self.inst.load_file(file_name,ptr) 87 check_error(err, exceptions) 88 89 def write_file(self, str fname, output_sets = None, output_tags = None, exceptions = ()): 90 """ 91 Write or export a file. 92 93 Write a MOAB-native file or export data to some other supported file format. 94 95 Example 96 ------- 97 mb.write_file("new_file.h5m") 98 99 Parameters 100 ---------- 101 fname : string 102 the location of the file to write 103 output_sets : EntityHandle or Range (default None) 104 If not None, this argument must be a valid EntitySet handle or 105 Range containing only EntitySets. 106 When specified, the method will write any entities from the given 107 meshsets. 108 output_tags : List of PyMOAB Tags (default None) 109 If not None, this argument must be a list of valid Tags. 110 When specified, the write_file will not write any of the tag's data 111 to the specified file. All tags handles will appear in the file, however. 112 113 exceptions : tuple (default is empty tuple) 114 tuple containing any error types that should 115 be ignored (see pymoab.types module for more info) 116 117 Returns 118 ------- 119 None 120 121 Raises 122 ------ 123 MOAB ErrorCode 124 if a MOAB error occurs 125 ValueError 126 if a parameter is not of the correct type 127 """ 128 cdef bytes cfname = fname.encode('UTF-8') 129 cdef const char * file_name = cfname 130 cdef moab.ErrorCode err 131 cdef int num_tags = 0 132 cdef _tagArray ta = _tagArray() 133 134 if output_tags: 135 assert isinstance(output_tags, Iterable), "Non-iterable output_tags argument." 136 for tag in output_tags: 137 assert isinstance(tag, Tag), "Non-tag type passed in output_tags." 138 num_tags = len(output_tags) 139 ta = _tagArray(output_tags) 140 else: 141 ta.ptr = NULL 142 143 cdef Range r = Range() 144 cdef np.ndarray[np.uint64_t, ndim=1] arr 145 if output_sets: 146 arr = _eh_array(output_sets) 147 r = Range(arr) 148 if not r.all_of_type(types.MBENTITYSET): 149 raise IOError("Only EntitySets should be passed to write file.") 150 if output_sets or output_tags: 151 err = self.inst.write_file( 152 file_name, <const char*> 0, <const char*> 0, deref(r.inst), ta.ptr, num_tags) 153 else: 154 err = self.inst.write_file(file_name) 155 156 check_error(err, exceptions) 157 158 def create_meshset(self, unsigned int options = 0x02, exceptions = ()): 159 """ 160 Create a new mesh set. 161 162 Create a new mesh set. Meshsets can store entities ordered or 163 unordered. A set can include entities at most once (MESHSET_SET) or more 164 than once (MESHSET_ORDERED). Meshsets can optionally track its members 165 using adjacencies (MESHSET_TRACK_OWNER); if set, entities are deleted 166 from tracking meshsets before being deleted. This adds data to mesh 167 entities, which can be more memory intensive. 168 169 Example 170 ------- 171 # Create a standard meshset 172 mb = pymoab.core.Core() 173 new_meshset = mb.create_meshset() 174 175 # Create a meshset which tracks entities 176 mb = pymoab.core.Core() 177 new_meshset = mb.create_meshset(pymoab.types.MESHSET_TRACK_OWNER) 178 179 Parameters 180 ---------- 181 options : MOAB EntitySet Property (default is MESHSET_SET) 182 settings for the Meshset being created 183 exceptions : tuple (default is empty tuple) 184 A tuple containing any error types that should 185 be ignored. (see pymoab.types module for more info) 186 187 Returns 188 ------- 189 MOAB Meshset (EntityHandle) 190 191 Raises 192 ------ 193 MOAB ErrorCode 194 if a MOAB error occurs 195 """ 196 cdef eh.EntityHandle ms_handle = 0 197 cdef moab.EntitySetProperty es_property = <moab.EntitySetProperty> options 198 cdef moab.ErrorCode err = self.inst.create_meshset(es_property, ms_handle) 199 check_error(err, exceptions) 200 return _eh_py_type(ms_handle) 201 202 def add_entity(self, eh.EntityHandle ms_handle, entity, exceptions = ()): 203 """ 204 Add an entity to the specified meshset. 205 206 If meshset has MESHSET_TRACK_OWNER option set, the entity adjacencies 207 are also added to the meshset. 208 209 Example 210 ------- 211 vertices # a iterable of MOAB vertex handles 212 new_meshset = mb.create_meshset() 213 mb.add_entity(new_meshset, entity) 214 215 Parameters 216 ---------- 217 ms_handle : EntityHandle 218 EntityHandle of the Meshset the entities will be added to 219 entity : EntityHandle 220 exceptions : tuple (default is empty tuple) 221 A tuple containing any error types that should 222 be ignored. (see pymoab.types module for more info) 223 224 Returns 225 ------- 226 None 227 228 Raises 229 ------ 230 MOAB ErrorCode 231 if a MOAB error occurs 232 """ 233 cdef moab.ErrorCode err 234 cdef Range r = Range(entity) 235 err = self.inst.add_entities(ms_handle, deref(r.inst)) 236 check_error(err, exceptions) 237 238 def add_entities(self, eh.EntityHandle ms_handle, entities, exceptions = ()): 239 """ 240 Add entities to the specified meshset. Entities can be provided either 241 as a pymoab.rng.Range o bject or as an iterable of EntityHandles. 242 243 If meshset has MESHSET_TRACK_OWNER option set, adjacencies are also 244 added to the meshset. 245 246 Example 247 ------- 248 vertices # a iterable of MOAB vertex handles 249 new_meshset = mb.create_meshset() 250 mb.add_entities(new_meshset, entities) 251 252 Parameters 253 ---------- 254 ms_handle : EntityHandle 255 EntityHandle of the Meshset the entities will be added to 256 entities : Range or iterable of EntityHandles 257 Entities that to add to the Meshset 258 exceptions : tuple (default is empty tuple) 259 A tuple containing any error types that should 260 be ignored. (see pymoab.types module for more info) 261 262 Returns 263 ------- 264 None 265 266 Raises 267 ------ 268 MOAB ErrorCode 269 if a MOAB error occurs 270 ValueError 271 if an EntityHandle is not of the correct type 272 """ 273 cdef moab.ErrorCode err 274 cdef Range r 275 cdef np.ndarray[np.uint64_t, ndim=1] arr 276 if isinstance(entities, Range): 277 r = entities 278 err = self.inst.add_entities(ms_handle, deref(r.inst)) 279 else: 280 arr = _eh_array(entities) 281 err = self.inst.add_entities(ms_handle, <eh.EntityHandle*> arr.data, len(entities)) 282 check_error(err, exceptions) 283 284 def remove_entity(self, eh.EntityHandle ms_handle, entity, exceptions = ()): 285 """ 286 Remove an entity from the specified meshset. 287 288 If meshset has MESHSET_TRACK_OWNER option set, entity adjacencies 289 are updated. 290 291 Example 292 ------- 293 new_meshset = mb.create_meshset() 294 mb.remove_entity(new_meshset, entity) 295 296 Parameters 297 ---------- 298 ms_handle : EntityHandle 299 EntityHandle of the Meshset the entities will be added to 300 entity : EntityHandle 301 exceptions : tuple (default is empty tuple) 302 A tuple containing any error types that should 303 be ignored. (see pymoab.types module for more info) 304 305 Returns 306 ------- 307 None 308 309 Raises 310 ------ 311 MOAB ErrorCode 312 if a MOAB error occurs 313 """ 314 cdef moab.ErrorCode err 315 cdef Range r = Range(entity) 316 err = self.inst.remove_entities(ms_handle, deref(r.inst)) 317 check_error(err, exceptions) 318 319 def remove_entities(self, eh.EntityHandle ms_handle, entities, exceptions = ()): 320 """ 321 Remove entities from the specified meshset. Entities can be provided either 322 as a pymoab.rng.Range object or as an iterable of EntityHandles. 323 324 If meshset has MESHSET_TRACK_OWNER option set, adjacencies in entities 325 in entities are updated. 326 327 Example 328 ------- 329 vertices # an iterable of MOAB vertex handles 330 new_meshset = mb.create_meshset() 331 mb.add_entities(new_meshset, entities) 332 # keep only the first entity in this meshset 333 mb.remove_entities(new_meshset, entities[1:]) 334 335 Parameters 336 ---------- 337 ms_handle : EntityHandle 338 EntityHandle of the Meshset the entities will be removed from 339 entities : Range or iterable of EntityHandles 340 Entities to remove from the Meshset 341 exceptions : tuple (default is empty tuple) 342 A tuple containing any error types that should 343 be ignored. (see pymoab.types module for more info) 344 345 Returns 346 ------- 347 None 348 349 Raises 350 ------ 351 MOAB ErrorCode 352 if a MOAB error occurs 353 ValueError 354 if an EntityHandle is not of the correct type 355 """ 356 cdef moab.ErrorCode err 357 cdef Range r 358 cdef np.ndarray[np.uint64_t, ndim=1] arr 359 if isinstance(entities, Range): 360 r = entities 361 err = self.inst.remove_entities(ms_handle, deref(r.inst)) 362 else: 363 arr = _eh_array(entities) 364 err = self.inst.remove_entities(ms_handle, <eh.EntityHandle*> arr.data, len(entities)) 365 check_error(err, exceptions) 366 367 def delete_entity(self, entity, exceptions = ()): 368 """ 369 Delete an entity from the database. 370 371 If the entity is contained in any meshsets, it are removed 372 from those meshsets which were created with MESHSET_TRACK_OWNER option. 373 374 Example 375 ------- 376 mb.delete_entity(entity) 377 378 Parameters 379 ---------- 380 entity : EntityHandle 381 exceptions : tuple (default is empty tuple) 382 A tuple containing any error types that should 383 be ignored. (see pymoab.types module for more info) 384 385 Returns 386 ------- 387 None 388 389 Raises 390 ------ 391 MOAB ErrorCode 392 if a MOAB error occurs 393 ValueError 394 if an EntityHandle is not of the correct type 395 """ 396 cdef moab.ErrorCode err 397 cdef Range r = Range(entity) 398 err = self.inst.delete_entities(deref(r.inst)) 399 check_error(err, exceptions) 400 401 def delete_entities(self, entities, exceptions = ()): 402 """ 403 Delete entities from the database. 404 405 If any of the entities are contained in any meshsets, they are removed 406 from those meshsets which were created with MESHSET_TRACK_OWNER option. 407 408 Example 409 ------- 410 mb = pymoab.core.Core() 411 # generate mesh using other Core functions # 412 mb.delete_entities(entities) 413 414 Parameters 415 ---------- 416 entities : Range or iterable of EntityHandles 417 Entities that to delete from the database 418 exceptions : tuple (default is empty tuple) 419 A tuple containing any error types that should 420 be ignored. (see pymoab.types module for more info) 421 422 Returns 423 ------- 424 None 425 426 Raises 427 ------ 428 MOAB ErrorCode 429 if a MOAB error occurs 430 ValueError 431 if an EntityHandle is not of the correct type 432 """ 433 cdef moab.ErrorCode err 434 cdef Range r 435 cdef np.ndarray[np.uint64_t, ndim=1] arr 436 if isinstance(entities, Range): 437 r = entities 438 err = self.inst.delete_entities(deref(r.inst)) 439 else: 440 arr = _eh_array(entities) 441 err = self.inst.delete_entities(<eh.EntityHandle*> arr.data, len(entities)) 442 check_error(err, exceptions) 443 444 def create_vertices(self, coordinates, exceptions = ()): 445 """ 446 Create vertices using the specified x,y,z coordinates. 447 448 Example 449 ------- 450 mb = pymoab.core.Core() 451 #create two vertices 452 coords = np.array((0, 0, 0, 1, 1, 1),dtype='float64') 453 verts = mb.create_vertices(coords) 454 455 OR 456 457 mb = pymoab.core.Core() 458 #create two vertices 459 coords = [[0.0, 0.0, 0.0],[1.0, 1.0, 1.0]] 460 verts = mb.create_vertices(coords) 461 462 Parameters 463 ---------- 464 coordinates : 1-D or 2-D iterable 465 Coordinates can be provided as either a 1-D iterable of 3*n floats 466 or as a 2-D array with dimensions (n,3) where n is the number of 467 vertices being created. 468 exceptions : tuple (default is empty tuple) 469 A tuple containing any error types that should 470 be ignored. (see pymoab.types module for more info) 471 472 Returns 473 ------- 474 MOAB Range of EntityHandles for the vertices 475 476 Raises 477 ------ 478 MOAB ErrorCode 479 if a MOAB error occurs 480 ValueError 481 if an EntityHandle is not of the correct type 482 """ 483 cdef Range rng = Range() 484 cdef np.ndarray coords_as_arr = np.asarray(coordinates) 485 if coords_as_arr.ndim > 1: 486 assert coords_as_arr.ndim == 2 487 coords_as_arr = coords_as_arr.flatten() 488 cdef np.ndarray[np.float64_t, ndim=1] coords_arr = _convert_array(coords_as_arr, (float, np.float64), np.float64) 489 assert len(coords_arr)%3 == 0, "Incorrect number of coordinates provided." 490 cdef moab.ErrorCode err = self.inst.create_vertices(<double *> coords_arr.data, 491 len(coords_arr)//3, 492 deref(rng.inst)) 493 check_error(err, exceptions) 494 return rng 495 496 def create_element(self, int entity_type, connectivity, exceptions = ()): 497 """ 498 Create an elment of type, entity_type, using vertex EntityHandles in connectivity. 499 500 Example 501 ------- 502 mb = core.Core() 503 # create some vertices 504 coords = np.array((0,0,0,1,0,0,1,1,1),dtype='float64') 505 verts = mb.create_vertices(coords) 506 507 # create the triangle in the database 508 tri_verts = np.array(((verts[0],verts[1],verts[2]),),dtype='uint64') 509 tris = mb.create_element(types.MBTRI,tri_verts) 510 511 OR 512 513 tri_verts = [verts[0],verts[1],verts[2]] 514 tris = mb.create_element(types.MBTRI,tri_verts) 515 516 517 Parameters 518 ---------- 519 entity_type : MOAB EntityType (see pymoab.types module) 520 type of entity to create (MBTRI, MBQUAD, etc.) 521 coordinates : iterable of EntityHandles 522 1-D array-like iterable of vertex EntityHandles the element is to be 523 created from 524 exceptions : tuple (default is empty tuple) 525 A tuple containing any error types that should 526 be ignored. (see pymoab.types module for more info) 527 528 Returns 529 ------- 530 EntityHandle of element created 531 532 Raises 533 ------ 534 MOAB ErrorCode 535 if a MOAB error occurs 536 ValueError 537 if an EntityHandle is not of the correct type 538 """ 539 cdef moab.EntityType typ = <moab.EntityType> entity_type 540 cdef eh.EntityHandle handle = 0 541 if isinstance(connectivity, Range): 542 connectivity = list(connectivity) 543 cdef np.ndarray[np.uint64_t, ndim=1] conn_arr = _eh_array(connectivity) 544 cdef int nnodes = len(connectivity) 545 cdef moab.ErrorCode err = self.inst.create_element(typ, 546 <eh.EntityHandle*> conn_arr.data, nnodes, handle) 547 check_error(err, exceptions) 548 return _eh_py_type(handle) 549 550 def create_elements(self, int entity_type, connectivity, exceptions = ()): 551 """ 552 Create an elments of type, entity_type, using vertex EntityHandles in connectivity. 553 554 Example 555 ------- 556 mb = core.Core() 557 # create some vertices for triangle 1 558 coords1 = np.array((0,0,0,1,0,0,1,1,1),dtype='float64') 559 verts1 = mb.create_vertices(coords) 560 # create some more vertices for triangle 2 561 coords2 = np.array((1,2,3,4,5,6,1,1,1),dtype='float64') 562 verts2 = mb.create_vertices(coords) 563 564 # create the triangles in the database 565 tri_verts = [[verts1[0],verts1[1],verts1[2]],[verts2[0],verts2[1],verts2[2]] 566 tris = mb.create_elements(types.MBTRI,tri_verts) 567 568 OR 569 570 tri_verts = [verts1,verts2] 571 tris = mb.create_elements(types.MBTRI,tri_verts) 572 573 Parameters 574 ---------- 575 entity_type : MOAB EntityType (see pymoab.types module) 576 type of entity to create (MBTRI, MBQUAD, MBHEX, etc.) 577 coordinates : iterable of EntityHandles 578 2-D array-like iterable of vertex EntityHandles the elements are to 579 be created from. Each entry in the array should have an appropriate 580 length for the element type being created (e.g. for MBTRI each entry 581 has length 3). 582 exceptions : tuple (default is empty tuple) 583 A tuple containing any error types that should 584 be ignored. (see pymoab.types module for more info) 585 586 Returns 587 ------- 588 EntityHandles of element created as a Range 589 590 Raises 591 ------ 592 MOAB ErrorCode 593 if a MOAB error occurs 594 ValueError 595 if an EntityHandle is not of the correct type 596 """ 597 cdef int i 598 cdef moab.ErrorCode err 599 cdef moab.EntityType typ = <moab.EntityType> entity_type 600 cdef np.ndarray connectivity_as_arr = np.asarray(connectivity) 601 assert connectivity_as_arr.ndim == 2 #required for now 602 cdef int nelems = connectivity_as_arr.shape[0] 603 cdef int nnodes = connectivity_as_arr.shape[1] 604 cdef np.ndarray[np.uint64_t, ndim=1] connectivity_i 605 cdef np.ndarray[np.uint64_t, ndim=1] handles = np.empty(nelems, 'uint64') 606 for i in range(nelems): 607 connectivity_i = _eh_array(connectivity[i]) 608 err = self.inst.create_element(typ, <eh.EntityHandle*> connectivity_i.data, 609 nnodes, deref((<eh.EntityHandle*> handles.data)+i)) 610 check_error(err, exceptions) 611 return Range(handles) 612 613 def tag_get_handle(self, 614 name, 615 size = None, 616 tag_type = None, 617 storage_type = None, 618 create_if_missing = False, 619 default_value = None, 620 exceptions = ()): 621 """ 622 Retrieve and/or create tag handles for storing data on mesh elements, vertices, 623 meshsets, etc. 624 625 626 Example - creating a new tag handle 627 ------- 628 # new MOAB core instance 629 mb = core.Core() 630 # 631 tag_type = pymoab.types.MB_TYPE_INTEGER # define the tag's data type 632 tag_size = 1 # the tag size (1 integer value) 633 storage_type = pymoab.types.MB_TAG_DENSE # define the storage type 634 tag_handle = mb.tag_get_handle("NewDataTag", 635 tag_size, 636 tag_type, 637 storage_type, 638 create_if_missing = True) 639 640 Example - retrieving an existing tag handle 641 ------- 642 # new MOAB core instance 643 mb = core.Core() 644 # 645 tag_type = pymoab.types.MB_TYPE_INTEGER # define the tag's data type 646 tag_size = 1 # the tag size (1 integer value) 647 tag_handle = mb.tag_get_handle("NewDataTag", 648 tag_size, 649 tag_type) 650 651 OR 652 653 # find the tag by name rather than using the full signature (less robust) 654 tag_handle = mb.tag_get_handle("NewDataTag") 655 656 Parameters 657 ---------- 658 name : string 659 name of the tag 660 size : int 661 number of values the tag contains (or the number of characters in 662 the case of an opaque tag) 663 tag_type : MOAB DataType 664 indicates the data type of the tag (MB_TYPE_DOUBLE, MB_TYPE_INTEGER, 665 MB_TYPE_OPAQUE, etc.) 666 storage_type : MOAB tag storage type (MB_TAG_DENSE, MB_TAG_SPARSE, etc.) 667 in advanced use of the database, this flag controls how this tag's 668 data is stored in memory. The two most common storage types are 669 670 MB_TYPE_SPARSE - sparse tags are stored as a list of (entity 671 handle, tag value) tuples, one list per sparse tag, sorted by 672 entity handle 673 674 MB_TYPE_DENSE - Dense tag values are stored in arrays which match 675 arrays of contiguous entity handles. Dense tags are more 676 efficient in both storage and memory if large numbers of 677 entities are assigned the same tag. Storage for a given dense 678 tag is not allocated until a tag value is set on an entity; 679 memory for a given dense tag is allocated for all entities in a 680 given sequence at the same time. Sparse: Sparse tags are stored 681 as a list of (entity handle, tag value) tuples, one list per 682 sparse tag, sorted by entity handle. 683 684 MB_TYPE_BIT - Bit tags are stored similarly to dense tags, but with 685 special handling to allow allocation in bit-size amounts per 686 entity. 687 create_if_missing : bool (default False) 688 indicates to the database instance that the tag should be created if 689 it cannot be found (requires that all arguments are provided to 690 fully define the tag) 691 default_value : default tag value (default None) 692 valid_default value fo the tag based on the tag type and length 693 specified in previous arguments. If no default value is specified, 694 then the returned tag will have no default value in the MOAB 695 instance. 696 exceptions : tuple (default is empty tuple) 697 A tuple containing any error types that should 698 be ignored. (see pymoab.types module for more info) 699 700 Returns 701 ------- 702 MOAB TagHandle 703 704 Raises 705 ------ 706 MOAB ErrorCode 707 if a MOAB error occurs 708 """ 709 cdef bytes cname = str(name).encode('UTF-8') 710 cdef const char* tag_name = cname 711 cdef Tag tag = Tag() 712 cdef moab.ErrorCode err 713 cdef moab.DataType tt 714 cdef int s 715 cdef np.ndarray default_val_arr 716 cdef const void* def_val_ptr = NULL 717 incomplete_tag_specification = False 718 719 # tag_type, size, and storage_type 720 # should either be all None 721 # or all non-None 722 all_none = all(v == None for v in [size, tag_type, storage_type]) 723 all_non_none = all( v != None for v in [size, tag_type, storage_type]) 724 if not (all_none or all_non_none): 725 raise ValueError(""" 726 Partial tag specification supplied. Please only provide tag name for 727 a name-based tag retrieval or provide a tag name, size, type, and 728 storage type for a more detailed specification of the tag to 729 retrieve. 730 """) 731 732 # if a default value is provided, set ptr 733 if default_value is not None: 734 if tag_type is types.MB_TYPE_OPAQUE: 735 default_val_arr = np.asarray((default_value,), dtype='S'+str(size)) 736 else: 737 default_val_arr = np.asarray(default_value, dtype=np.dtype(np_tag_type(tag_type))) 738 # validate default value data for tag type and length 739 default_val_arr = validate_type(tag_type,size,default_val_arr) 740 def_val_ptr = <const void*> default_val_arr.data 741 742 if tag_type is None and size is None and storage_type is None: 743 err = self.inst.tag_get_handle(tag_name, tag.inst) 744 else: 745 tt = tag_type 746 s = size 747 flags = storage_type|types.MB_TAG_CREAT if create_if_missing else storage_type 748 err = self.inst.tag_get_handle(tag_name, s, tt, tag.inst, flags, def_val_ptr, NULL) 749 750 check_error(err, exceptions) 751 return tag 752 753 def tag_set_data(self, Tag tag, entity_handles, data, exceptions = ()): 754 """ 755 Set tag data for a set of MOAB entities. The data provided must be 756 compatible with the tag's data type and be of an appropriate shape and 757 size depending on the number of entity handles are provided. 758 759 This function will ensure that the data is of the correct type and 760 length based on the tag it is to be applied to. Data can be passed as a 761 1-D iterable of appropriate length or as 2-D iterable with entries for 762 each entity handle equal to the length of the tag. 763 764 Example 765 ------- 766 # create moab core instance 767 mb = core.Core() 768 # create some vertices 769 coords = np.array((0,0,0,1,0,0,1,1,1),dtype='float64') 770 verts = mb.create_vertices(coords) 771 # create a new tag for data 772 tag_length = 2 773 tag_type = pymoab.types.MB_TYPE_DOUBLE 774 data_tag = mb.tag_get_handle("Data", 775 tag_length, 776 tag_type, 777 create_if_missing = True) 778 # some sample data 779 data = np.array([1.0,2.0,3.0,4.0,5.0,6.0], dtype = 'float') 780 #use this function to tag vertices with the data 781 mb.tag_set_data(data_tag, verts, data) 782 783 OR 784 785 # some sample data 786 data = np.array([[1.0,2.0],[3.0,4.0],[5.0,6.0]], dtype = 'float') 787 #use this function to tag vertices with the data 788 mb.tag_set_data(data_tag, verts, data) 789 790 OR 791 792 ### pass data as a an iterable object ### 793 # some sample data 794 data = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0] 795 #use this function to tag vertices with the data 796 mb.tag_set_data(data_tag, verts, data) 797 798 OR 799 800 ### pass data as a nested iterable object ### 801 ### (can be convenient for vector tags) ### 802 # some sample data 803 data = [[1.0, 2.0],[3.0, 4.0],[4.0, 5.0]] 804 #use this function to tag vertices with the data 805 mb.tag_set_data(data_tag, verts, data) 806 807 OR 808 809 ### tag a single vertex ### 810 # get a single vertex 811 vertex_to_tag = verts[0] 812 data = [1.0, 2.0] 813 #use this function to tag vertices with the data 814 mb.tag_set_data(data_tag, vertex, data) 815 816 Parameters 817 ---------- 818 tag : MOAB TagHandle 819 tag to which the data is applied 820 entity_handles : iterable of MOAB EntityHandle's or single EntityHandle 821 the EntityHandle(s) to tag the data on. This can be any iterable of 822 EntityHandles or a single EntityHandle. 823 exceptions : tuple (default is empty tuple) 824 A tuple containing any error types that should 825 be ignored. (see pymoab.types module for more info) 826 data : iterable of data to set for the tag 827 This is a 1-D or 2-D iterable of data values to set for the tag and 828 entities specified in the entity_handles parameter. If the data is 829 1-D then it must be of size len(entity_handles)*tag_length. If the 830 data is 2-D then it must be of size len(entity_handles) with each 831 second dimension entry having a length equal to the tag's 832 length. All entries in the data must be of the proper type for the 833 tag or be able to be converted to that type. 834 Returns 835 ------- 836 None 837 838 Raises 839 ------ 840 MOAB ErrorCode 841 if a MOAB error occurs 842 ValueError 843 if a data entry is not of the correct type or cannot be converted to 844 the correct type 845 """ 846 cdef moab.ErrorCode err 847 cdef np.ndarray ehs 848 cdef moab.DataType tag_type = moab.MB_MAX_DATA_TYPE 849 # create a numpy array for the entity handles to be tagged 850 if isinstance(entity_handles, _eh_py_type): 851 ehs = _eh_array([entity_handles,]) 852 else: 853 ehs = _eh_array(entity_handles) 854 err = self.inst.tag_get_data_type(tag.inst, tag_type); 855 check_error(err, ()) 856 cdef int length = 0 857 err = self.inst.tag_get_length(tag.inst,length); 858 check_error(err,()) 859 cdef np.ndarray data_arr = np.asarray(data) 860 # protect against shallow copy, delayed evaluation problem 861 data_arr = np.copy(data_arr) 862 #if the data array is not flat it must be dimension 2 and have 863 #as many entries as entity handles provided 864 if data_arr.ndim > 1: 865 assert data_arr.ndim == 2 866 assert data_arr.shape[0] == ehs.size 867 #each entry must be equal to the tag length as well 868 for entry in data_arr: 869 len(entry) == length 870 #if all of this is true, then flatten the array and continue 871 data_arr = data_arr.flatten() 872 error_str = "Incorrect data length" 873 if types.MB_TYPE_OPAQUE == tag_type: 874 assert data_arr.size == ehs.size, error_str 875 else: 876 assert data_arr.size == ehs.size*length, error_str 877 data_arr = validate_type(tag_type,length,data_arr) 878 err = self.inst.tag_set_data(tag.inst, <eh.EntityHandle*> ehs.data, ehs.size, <const void*> data_arr.data) 879 check_error(err, exceptions) 880 881 def tag_get_data(self, Tag tag, entity_handles, flat = False, exceptions = ()): 882 """ 883 Retrieve tag data for a set of entities. Data will be returned as a 2-D 884 array with number of entries equal to the number of EntityHandles passed 885 to the function by default. Each entry in the array will be equal to the 886 tag's length. A flat array of data can also be returned if specified by 887 setting the 'flat' parameter to True. 888 889 Example 890 ------- 891 mb = core.Core() 892 coords = np.array((0,0,0,1,0,0,1,1,1),dtype='float64') 893 verts = mb.create_vertices(coords) 894 # create a new tag for data 895 tag_length = 2 896 tag_type = pymoab.types.MB_TYPE_DOUBLE 897 data_tag = mb.tag_get_handle("Data", 898 tag_length, 899 tag_type, 900 create_if_missing = True) 901 # some sample data 902 data = np.array([1.0,2.0,3.0,4.0,5.0,6.0], dtype = 'float') 903 # use this function to tag vertices with the data 904 mb.tag_set_data(data_tag, verts, data) 905 906 # now retrieve this tag's data for the vertices from the instance 907 data = mb.tag_get_data(data_tag, verts) # returns 2-D array 908 909 OR 910 911 # now retrieve this tag's data for the vertices from the instance 912 # returns 1-D array of len(verts)*tag_length 913 data = mb.tag_get_data(data_tag, verts, flat=True) 914 915 Parameters 916 ---------- 917 tag : MOAB TagHandle 918 the tag for which data is to be retrieved 919 entity_handles : iterable of MOAB EntityHandles or a single EntityHandle 920 the EntityHandle(s) to retrieve data for. 921 flat : bool (default is False) 922 Indicates the structure in which the data is returned. If False, the 923 array is returned as a 2-D numpy array of len(entity_handles) with 924 each second dimension entry equal to the length of the tag data. If 925 True, the data is returned as a 1-D numpy array of length 926 len(entity_handles)*tag_length. 927 exceptions : tuple (default is empty tuple) 928 A tuple containing any error types that should 929 be ignored. (see pymoab.types module for more info) 930 931 Returns 932 ------- 933 Numpy array of data with dtype matching that of the tag's type 934 935 Raises 936 ------ 937 MOAB ErrorCode 938 if a MOAB error occurs 939 ValueError 940 if an EntityHandle is not of the correct type 941 """ 942 cdef moab.ErrorCode err 943 cdef np.ndarray ehs 944 cdef moab.DataType tag_type = moab.MB_MAX_DATA_TYPE 945 # create a numpy array for the entity handles to be tagged 946 if isinstance(entity_handles, _eh_py_type): 947 ehs = _eh_array([entity_handles,]) 948 else: 949 ehs = _eh_array(entity_handles) 950 # get the tag type and length for validation 951 err = self.inst.tag_get_data_type(tag.inst, tag_type); 952 check_error(err,()) 953 cdef int length = 0 954 err = self.inst.tag_get_length(tag.inst,length); 955 check_error(err,()) 956 #create array to hold data 957 cdef np.ndarray data 958 if tag_type is types.MB_TYPE_OPAQUE: 959 data = np.empty((ehs.size,),dtype='S'+str(length)) 960 else: 961 data = np.empty((length*ehs.size,), dtype=np.dtype(np_tag_type(tag_type))) 962 err = self.inst.tag_get_data(tag.inst, <eh.EntityHandle*> ehs.data, ehs.size, <void*> data.data) 963 check_error(err, exceptions) 964 # return data as user specifies 965 if tag_type is types.MB_TYPE_OPAQUE: 966 data = data.astype('str') 967 if flat: 968 return data 969 else: 970 entry_len = 1 if tag_type == types.MB_TYPE_OPAQUE else length 971 return data.reshape((ehs.size,entry_len)) 972 973 def tag_delete_data(self, Tag tag, entity_handles, exceptions = ()): 974 """ 975 Delete the data of a tag on a set of EntityHandle's. Only sparse tag 976 data are deleted with this method; dense tags are deleted by deleting 977 the tag itself using tag_delete. 978 979 Example 980 ------- 981 # delete data associated with the iterable entities from the tag data_tag 982 data = mb.tag_delete_data(data_tag, entities) 983 984 Parameters 985 ---------- 986 tag : MOAB TagHandle 987 the tag from which data is to be deleted 988 entity_handles : iterable of MOAB EntityHandles or a single EntityHandle 989 the EntityHandle(s) to delete data from. This can be any iterable of 990 EntityHandles or a single EntityHandle. 991 992 Returns 993 ------- 994 None 995 996 Raises 997 ------ 998 MOAB ErrorCode 999 if a MOAB error occurs 1000 ValueError 1001 if an EntityHandle is not of the correct type 1002 """ 1003 cdef moab.ErrorCode err 1004 cdef np.ndarray ehs 1005 # create a numpy array for the entity handles to be tagged 1006 if isinstance(entity_handles, _eh_py_type): 1007 ehs = _eh_array([entity_handles,]) 1008 else: 1009 ehs = _eh_array(entity_handles) 1010 # Delete the data 1011 err = self.inst.tag_delete_data(tag.inst, <eh.EntityHandle*> ehs.data, ehs.size) 1012 check_error(err, exceptions) 1013 1014 def tag_delete(self, Tag tag, exceptions = ()): 1015 """ 1016 Removes the tag from the database and deletes all of its associated data. 1017 1018 Example 1019 ------- 1020 # delete a tag that was previously created 1021 data = mb.tag_delete(data_tag) 1022 1023 Parameters 1024 ---------- 1025 tag : MOAB TagHandle 1026 the tag from which data is to be deleted 1027 1028 Returns 1029 ------- 1030 None 1031 1032 Raises 1033 ------ 1034 MOAB ErrorCode 1035 if a MOAB error occurs 1036 """ 1037 cdef moab.ErrorCode err 1038 # Delete the tag 1039 err = self.inst.tag_delete(tag.inst) 1040 check_error(err, exceptions) 1041 1042 def get_adjacencies(self, entity_handles, int to_dim, bint create_if_missing = False, int op_type = types.INTERSECT, exceptions = ()): 1043 """ 1044 Get the adjacencies associated with a range of entities to entities of a specified dimension. 1045 1046 Example 1047 ------- 1048 mb = core.Core() 1049 coords = np.array((0,0,0,1,0,0,1,1,1),dtype='float64') 1050 verts = mb.create_vertices(coords) 1051 #create elements 1052 verts = np.array(((verts[0],verts[1],verts[2]),),dtype='uint64') 1053 tris = mb.create_elements(types.MBTRI,verts) 1054 #get the adjacencies of the triangle of dim 1 (should return the vertices) 1055 adjacent_verts = mb.get_adjacencies(tris, 0, False) 1056 #now get the edges and ask MOAB to create them for us 1057 adjacent_edges = mb.get_adjacencies(tris, 1, True) 1058 1059 Parameters 1060 ---------- 1061 entity_handles : iterable of MOAB EntityHandles or a single EntityHandle 1062 the EntityHandle(s) to get the adjacencies of. This can be any 1063 iterable of EntityHandles or a single EntityHandle. 1064 to_dim : integer 1065 value indicating the dimension of the entities to return 1066 create_if_missing : bool (default is false) 1067 this parameter indicates that any adjacencies that do not exist 1068 should be created. For instance, in the example above, the second 1069 call to get_adjacencies will create the edges of the triangle which 1070 did not previously exist in the mesh database. 1071 op_type : int (default is 0 or INTERSECT) 1072 this value indicates how overlapping adjacencies should be handled 1073 INTERSECT - will return the intersection of the adjacencies between mesh elements 1074 UNION - will return the union of all adjacencies for the elements provided to the function 1075 exceptions : tuple (default is empty tuple) 1076 A tuple containing any error types that should 1077 be ignored. (see pymoab.types module for more info) 1078 1079 Returns 1080 ------- 1081 Range of MOAB EntityHAndles 1082 1083 Raises 1084 ------ 1085 MOAB ErrorCode 1086 if a MOAB error occurs 1087 ValueError 1088 if an EntityHandle is not of the correct type 1089 """ 1090 cdef moab.ErrorCode err 1091 cdef Range r 1092 cdef Range adj = Range() 1093 r = Range(entity_handles) 1094 err = self.inst.get_adjacencies(deref(r.inst), to_dim, create_if_missing, deref(adj.inst), op_type) 1095 check_error(err, exceptions) 1096 return adj 1097 1098 def type_from_handle(self, entity_handle): 1099 """ 1100 Returns the type (MBVERTEX, MBQUAD, etc.) of an EntityHandle 1101 1102 Example 1103 ------- 1104 mb = core.Core() 1105 coords = np.array((0,0,0,1,0,0,1,1,1),dtype='float64') 1106 verts = mb.create_vertices(coords) 1107 #create elements 1108 verts = np.array(((verts[0],verts[1],verts[2]),),dtype='uint64') 1109 tris = mb.create_elements(types.MBTRI,verts) 1110 entity_type = mb.type_from_handle(tris[0]) 1111 1112 Parameters 1113 ---------- 1114 entity_handle : a MOAB EntityHandle 1115 1116 Returns 1117 ------- 1118 An integer representing the EntityType 1119 1120 Raises 1121 ------ 1122 MOAB ErrorCode 1123 if a MOAB error occurs 1124 """ 1125 cdef moab.EntityType t 1126 t = self.inst.type_from_handle(<unsigned long> entity_handle) 1127 return t 1128 1129 def get_child_meshsets(self, meshset_handle, num_hops = 1, exceptions = ()): 1130 """ 1131 Retrieves the child meshsets from a parent meshset. 1132 1133 Example 1134 ------- 1135 mb = core.Core() 1136 parent_set = mb.create_meshset() 1137 child_set = mb.create_meshset() 1138 mb.add_parent_meshset(child_set, parent_set) 1139 child_sets = mb.get_child_meshsets(parent_set) 1140 1141 Parameters 1142 ---------- 1143 meshset_handle : MOAB EntityHandle 1144 handle of the parent meshset 1145 num_hops : integer (default is 1) 1146 the number of generations to traverse when collecting child 1147 meshsets. If this value is zero, then the maximum number of 1148 generations will be traversed. 1149 exceptions : tuple (default is empty tuple) 1150 A tuple containing any error types that should 1151 be ignored. (see pymoab.types module for more info) 1152 1153 Returns 1154 ------- 1155 Range of MOAB EntityHandles 1156 1157 Raises 1158 ------ 1159 MOAB ErrorCode 1160 if a MOAB error occurs 1161 ValueError 1162 if the Meshset EntityHandle is not of the correct type 1163 """ 1164 cdef moab.ErrorCode err 1165 cdef Range r = Range() 1166 err = self.inst.get_child_meshsets(<unsigned long> meshset_handle, deref(r.inst), num_hops) 1167 check_error(err, exceptions) 1168 return r 1169 1170 def get_parent_meshsets(self, meshset_handle, num_hops = 1, exceptions = ()): 1171 """ 1172 Retrieves the parent meshsets from a child meshset. 1173 1174 Example 1175 ------- 1176 mb = core.Core() 1177 parent_set = mb.create_meshset() 1178 child_set = mb.create_meshset() 1179 mb.add_parent_meshset(child_set, parent_set) 1180 parent_sets = mb.get_parent_meshsets(child_set) 1181 1182 Parameters 1183 ---------- 1184 meshset_handle : MOAB EntityHandle 1185 handle of the child meshset 1186 num_hops : integer (default is 1) 1187 the number of generations to traverse when collecting 1188 meshsets. If this value is zero, then the maximum number of 1189 generations will be traversed. 1190 exceptions : tuple (default is empty tuple) 1191 A tuple containing any error types that should 1192 be ignored. (see pymoab.types module for more info) 1193 1194 Returns 1195 ------- 1196 Range of MOAB EntityHandles 1197 1198 Raises 1199 ------ 1200 MOAB ErrorCode 1201 if a MOAB error occurs 1202 ValueError 1203 if the Meshset EntityHandle is not of the correct type 1204 """ 1205 cdef moab.ErrorCode err 1206 cdef Range r = Range() 1207 err = self.inst.get_parent_meshsets(<unsigned long> meshset_handle, deref(r.inst), 0) 1208 check_error(err, exceptions) 1209 return r 1210 1211 def add_parent_meshset(self, child_meshset, parent_meshset, exceptions = ()): 1212 """ 1213 Add a parent meshset to a meshset. 1214 1215 Example 1216 ------- 1217 mb = core.Core() 1218 parent_set = mb.create_meshset() 1219 child_set = mb.create_meshset() 1220 mb.add_parent_meshset(child_set, parent_set) 1221 1222 Parameters 1223 ---------- 1224 child_meshset : MOAB EntityHandle 1225 handle of the child meshset 1226 parent_meshset : MOAB EntityHandle 1227 handle of the parent meshset 1228 exceptions : tuple (default is empty tuple) 1229 A tuple containing any error types that should 1230 be ignored. (see pymoab.types module for more info) 1231 1232 Returns 1233 ------- 1234 None 1235 1236 Raises 1237 ------ 1238 MOAB ErrorCode 1239 if a MOAB error occurs 1240 ValueError 1241 if the Meshset EntityHandle is not of the correct type 1242 """ 1243 cdef moab.ErrorCode err 1244 err = self.inst.add_parent_meshset(<unsigned long> child_meshset, <unsigned long> parent_meshset) 1245 check_error(err, exceptions) 1246 1247 def add_child_meshset(self, parent_meshset, child_meshset, exceptions = ()): 1248 """ 1249 Add a child meshset to a meshset. 1250 1251 Example 1252 ------- 1253 mb = core.Core() 1254 parent_set = mb.create_meshset() 1255 child_set = mb.create_meshset() 1256 mb.add_child_meshset(parent_set, child_set) 1257 1258 Parameters 1259 ---------- 1260 parent_meshset : MOAB EntityHandle 1261 handle of the parent meshset 1262 child_meshset : MOAB EntityHandle 1263 handle of the child meshset 1264 exceptions : tuple (default is empty tuple) 1265 A tuple containing any error types that should 1266 be ignored. (see pymoab.types module for more info) 1267 1268 Returns 1269 ------- 1270 None 1271 1272 Raises 1273 ------ 1274 MOAB ErrorCode 1275 if a MOAB error occurs 1276 ValueError 1277 if the Meshset EntityHandle is not of the correct type 1278 """ 1279 cdef moab.ErrorCode err 1280 err = self.inst.add_child_meshset(<unsigned long> parent_meshset, <unsigned long> child_meshset) 1281 check_error(err, exceptions) 1282 1283 def add_parent_child(self, parent_meshset, child_meshset, exceptions = ()): 1284 """ 1285 Add a parent-child link between two meshsets. 1286 1287 Example 1288 ------- 1289 mb = core.Core() 1290 parent_set = mb.create_meshset() 1291 child_set = mb.create_meshset() 1292 mb.add_parent_child(parent_set, child_set) 1293 1294 Parameters 1295 ---------- 1296 parent_meshset : MOAB EntityHandle 1297 handle of the parent meshset 1298 child_meshset : MOAB EntityHandle 1299 handle of the child meshset 1300 exceptions : tuple (default is empty tuple) 1301 A tuple containing any error types that should 1302 be ignored. (see pymoab.types module for more info) 1303 1304 Returns 1305 ------- 1306 None 1307 1308 Raises 1309 ------ 1310 MOAB ErrorCode 1311 if a MOAB error occurs 1312 ValueError 1313 if the Meshset EntityHandle is not of the correct type 1314 """ 1315 cdef moab.ErrorCode err 1316 err = self.inst.add_parent_child(<unsigned long> parent_meshset, <unsigned long> child_meshset) 1317 check_error(err, exceptions) 1318 1319 def get_root_set(self): 1320 """ 1321 Return the entity meshset representing the whole mesh. 1322 1323 Returns 1324 ------- 1325 MOAB EntityHandle 1326 """ 1327 return _eh_py_type(0) 1328 1329 def get_connectivity(self, entity_handles, exceptions = ()): 1330 """ 1331 Returns the vertex handles which make up the mesh entities passed in via 1332 the entity_handles argument. 1333 1334 Example 1335 ------- 1336 # new PyMOAB instance 1337 mb = core.Core() 1338 #create some vertices 1339 coords = np.array((0,0,0,1,0,0,1,1,1),dtype='float64') 1340 verts = mb.create_vertices(coords) 1341 #create a triangle 1342 verts = np.array(((verts[0],verts[1],verts[2]),),dtype='uint64') 1343 tris = mb.create_elements(types.MBTRI,verts) 1344 # retrieve the vertex handles that make up the triangle 1345 conn = mb.get_connectivity(tris[0]) 1346 1347 1348 Parameters 1349 ---------- 1350 entity_handles : iterable of MOAB EntityHandles or a single EntityHandle 1351 to retrieve the vertex connectivity of. Note that these 1352 EntityHandles should represent mesh entities (MBEDGE, 1353 MBTRI, MBQUAD, etc.) rather than an EntitySet. 1354 exceptions : tuple (default is empty tuple) 1355 A tuple containing any error types that should 1356 be ignored. (see pymoab.types module for more info) 1357 1358 Returns 1359 ------- 1360 Numpy array of vertex EntityHandles 1361 1362 Raises 1363 ------ 1364 MOAB ErrorCode 1365 if a MOAB error occurs 1366 ValueError 1367 if an EntityHandle is not of the correct datatype 1368 """ 1369 cdef moab.ErrorCode err 1370 cdef np.ndarray[eh.EntityHandle] ehs 1371 if isinstance(entity_handles, _eh_py_type): 1372 ehs = _eh_array([entity_handles,]) 1373 else: 1374 ehs = _eh_array(entity_handles) 1375 cdef vector[eh.EntityHandle] ehs_out 1376 cdef eh.EntityHandle* eh_ptr 1377 cdef int num_ents = 0 1378 err = self.inst.get_connectivity(<eh.EntityHandle*> ehs.data, ehs.size, ehs_out) 1379 check_error(err, exceptions) 1380 1381 return np.asarray(ehs_out, dtype = np.uint64) 1382 1383 def get_coords(self, entities, exceptions = ()): 1384 """ 1385 Returns the xyz coordinate information for a set of vertices. 1386 1387 Example 1388 ------- 1389 mb = core.Core() 1390 verts # list of vertex EntityHandles 1391 ret_coords = mb.get_coords(verts) 1392 1393 Parameters 1394 ---------- 1395 entities : iterable of MOAB EntityHandles or a single EntityHandle 1396 the EntityHandle(s) to get the adjacencies of. This can be any 1397 iterable of EntityHandles or a single EntityHandle. 1398 exceptions : tuple (default is empty tuple) 1399 A tuple containing any error types that should 1400 be ignored. (see pymoab.types module for more info) 1401 1402 Returns 1403 ------- 1404 Returns coordinates as a 1-D Numpy array of xyz values 1405 1406 Raises 1407 ------ 1408 MOAB ErrorCode 1409 if a MOAB error occurs 1410 ValueError 1411 if the Meshset EntityHandle is not of the correct type 1412 """ 1413 cdef moab.ErrorCode err 1414 cdef Range r 1415 cdef np.ndarray[np.uint64_t, ndim=1] arr 1416 cdef np.ndarray coords 1417 if isinstance(entities, _eh_py_type): 1418 entities = Range(entities) 1419 if isinstance(entities, Range): 1420 r = entities 1421 coords = np.empty((3*r.size(),),dtype='float64') 1422 err = self.inst.get_coords(deref(r.inst), <double*> coords.data) 1423 else: 1424 arr = _eh_array(entities) 1425 coords = np.empty((3*len(arr),),dtype='float64') 1426 err = self.inst.get_coords(<eh.EntityHandle*> arr.data, len(entities), <double*> coords.data) 1427 check_error(err, exceptions) 1428 return coords 1429 1430 def set_coords(self, entities, np.ndarray coords, exceptions = ()): 1431 """ 1432 Sets the xyz coordinate information for a set of vertices. 1433 1434 Example 1435 ------- 1436 mb = core.Core() 1437 verts # list of vertex EntityHandles 1438 coords = np.array([[0,0,0],[1,0,0],[0,1,0],[1,1,0]]) 1439 ret_coords = mb.set_coords(verts, coords) 1440 1441 Parameters 1442 ---------- 1443 entities : iterable of MOAB EntityHandles or a single EntityHandle 1444 the EntityHandle(s) to get the adjacencies of. This can be any 1445 iterable of EntityHandles or a single EntityHandle. 1446 coords : coordinate positions (float) 1447 vertex coordinates to be set in Core object 1448 exceptions : tuple (default is empty tuple) 1449 A tuple containing any error types that should 1450 be ignored. (see pymoab.types module for more info) 1451 1452 Raises 1453 ------ 1454 MOAB ErrorCode 1455 if a MOAB error occurs 1456 ValueError 1457 if the Meshset EntityHandle is not of the correct type 1458 """ 1459 cdef moab.ErrorCode err 1460 cdef Range r 1461 cdef np.ndarray[np.uint64_t, ndim=1] arr 1462 if isinstance(entities, _eh_py_type): 1463 entities = Range(entities) 1464 if isinstance(entities, Range): 1465 r = entities 1466 if 3*r.size() != len(coords): 1467 check_error(moab.MB_INVALID_SIZE, exceptions) 1468 err = self.inst.set_coords(deref(r.inst), <const double*> coords.data) 1469 else: 1470 arr = _eh_array(entities) 1471 if 3*len(arr) != len(coords): 1472 check_error(moab.MB_INVALID_SIZE, exceptions) 1473 err = self.inst.set_coords(<eh.EntityHandle*> arr.data, len(entities), <const double*> coords.data) 1474 check_error(err, exceptions) 1475 1476 def get_entities_by_type(self, meshset, entity_type, bint recur = False, bint as_list = False, exceptions = ()): 1477 """ 1478 Retrieves all entities of a given entity type in the database or meshset 1479 1480 Parameters 1481 ---------- 1482 meshset : MOAB EntityHandle 1483 meshset whose entities are being queried 1484 entity_type : MOAB EntityType 1485 type of the entities desired (MBVERTEX, MBTRI, etc.) 1486 recur : bool (default is False) 1487 if True, meshsets containing meshsets are queried recusively. The 1488 contenst of these meshsets are returned, but not the meshsets 1489 themselves. 1490 as_list : return entities in a list (preserves ordering if necessary, but 1491 consumes more memory) 1492 Returns 1493 ------- 1494 MOAB Range of EntityHandles 1495 1496 Raises 1497 ------ 1498 MOAB ErrorCode 1499 if a MOAB error occurs 1500 ValueError 1501 if the Meshset EntityHandle is not of the correct type or 1502 if the EntityType provided is not valid 1503 """ 1504 cdef moab.ErrorCode err 1505 cdef Range entities = Range() 1506 cdef moab.EntityType typ = entity_type 1507 cdef vector[eh.EntityHandle] hvec 1508 if as_list: 1509 err = self.inst.get_entities_by_type(<unsigned long> meshset, 1510 typ, 1511 hvec, 1512 recur) 1513 check_error(err, exceptions) 1514 return hvec 1515 1516 else: 1517 err = self.inst.get_entities_by_type(<unsigned long> meshset, 1518 typ, 1519 deref(entities.inst), 1520 recur) 1521 check_error(err, exceptions) 1522 return entities 1523 1524 def get_entities_by_type_and_tag(self, 1525 meshset, 1526 entity_type, 1527 tags, 1528 values, 1529 int condition = types.INTERSECT, 1530 bint recur = False, 1531 exceptions = ()): 1532 """ 1533 Retrieve entities of a given EntityType in the database which also have 1534 the provided tag and (optionally) the value specified. 1535 1536 Values are expected to be provided in one or two-dimensional arrays in 1537 which each entry in the highest array dimension represents the value (or 1538 set of values for a vector tag) to be matched for corresponding tag in 1539 the "tags" parameter. If an entry is filled with None values, then any 1540 entity with that tag will be returned. 1541 1542 NOTE: This function currently only works for a single tag and set of values. 1543 1544 Example 1545 ------- 1546 mb = core.Core() 1547 rs = mb.get_root_set() 1548 entities = mb.get_entities_by_type(rs, types.MBVERTEX) 1549 1550 Parameters 1551 ---------- 1552 meshset : MOAB EntityHandle (defualt is the database root set) 1553 meshset whose entities are being queried. 1554 entity_type : MOAB EntityType 1555 type of the entities desired (MBVERTEX, MBTRI, etc.) 1556 tags : iterable of MOAB TagHandles or single TagHandle 1557 an iterable of MOAB TagHandles. Only entities with these tags will 1558 be returned. 1559 values : iterable of tag values 1560 an iterable data structure of the tag values to be matched for 1561 entities returned by the call (see general description for details 1562 on the composition of this data structure) 1563 recur : bool (default is False) 1564 if True, meshsets containing meshsets are queried recusively. The 1565 contenst of these meshsets are returned, but not the meshsets 1566 themselves. 1567 1568 Returns 1569 ------- 1570 MOAB Range of EntityHandles 1571 1572 Raises 1573 ------ 1574 MOAB ErrorCode 1575 if a MOAB error occurs 1576 ValueError 1577 if the Meshset EntityHandle is not of the correct type or if the 1578 EntityType provided is not valid or if the tag data to be matched is 1579 not constructed properly 1580 """ 1581 cdef np.ndarray vals = np.asarray(values, dtype='O') 1582 assert isinstance(tags, Tag) or len(tags) == 1 , "Only single-tag queries are currently supported." 1583 # overall dimension of the numpy array should be 2 1584 # one array for each tag passed to the function 1585 # assert vals.ndim == 2 (was for support of multiple tags) 1586 #ensure that the correct number of arrays exist 1587 cdef int num_tags 1588 cdef Tag single_tag 1589 if isinstance(tags, Tag): 1590 num_tags = 1 1591 single_tag = tags 1592 elif len(tags) == 1: 1593 num_tags = 1 1594 single_tag = tags[0] 1595 else: 1596 num_tags = len(tags) 1597 if 1 != num_tags: 1598 assert vals.ndim == 2 1599 assert num_tags == vals.shape[0] 1600 assert vals.ndim <= 2 1601 #allocate memory for an appropriately sized void** array 1602 cdef void** arr = <void**> malloc(num_tags*sizeof(void*)) 1603 #some variables to help in setting up the void array 1604 cdef moab.ErrorCode err 1605 cdef moab.DataType this_tag_type = moab.MB_MAX_DATA_TYPE 1606 cdef int this_tag_length = 0 1607 cdef bytes val_str 1608 cdef np.ndarray this_data 1609 1610 # if this is a single tag and the values array is 1-D 1611 # then validate and call function 1612 if (num_tags == 1) and (vals.ndim == 1): 1613 this_data = self._validate_data_for_tag(single_tag,vals) 1614 arr[0] = <void*> this_data.data if this_data is not None else NULL 1615 elif vals.ndim == 2: 1616 # assign values to void** array 1617 for i in range(num_tags): 1618 this_data = self._validate_data_for_tag(tags[i],vals[i]) 1619 #set the array value 1620 arr[i] = <void*> this_data.data if this_data is not None else NULL 1621 1622 #create tag array to pass to function 1623 cdef _tagArray ta = _tagArray(tags) 1624 #convert type to tag type 1625 cdef moab.EntityType typ = entity_type 1626 #a range to hold returned entities 1627 cdef Range ents = Range() 1628 #here goes nothing 1629 err = self.inst.get_entities_by_type_and_tag(<unsigned long> meshset, 1630 typ, 1631 ta.ptr, 1632 <const void**> arr, 1633 num_tags, 1634 deref(ents.inst), 1635 condition, 1636 recur) 1637 check_error(err, exceptions) 1638 # return entities found in the MOAB function call 1639 return ents 1640 1641 1642 def get_entities_by_handle(self, meshset, bint recur = False, bint as_list = False, exceptions = ()): 1643 """ 1644 Retrieves all entities in the given meshset. 1645 1646 Parameters 1647 ---------- 1648 meshset : MOAB EntityHandle 1649 meshset whose entities are being queried 1650 recur : bool (default is False) 1651 if True, meshsets containing meshsets are queried recusively. The 1652 contenst of these meshsets are returned, but not the meshsets 1653 themselves. 1654 as_list : return entities in a list (preserves ordering if necessary, but 1655 consumes more memory) 1656 Returns 1657 ------- 1658 MOAB Range of EntityHandles 1659 1660 Raises 1661 ------ 1662 MOAB ErrorCode 1663 if a MOAB error occurs 1664 ValueError 1665 if the Meshset EntityHandle is not of the correct type or 1666 if the EntityType provided is not valid 1667 """ 1668 cdef moab.ErrorCode err 1669 cdef Range ents = Range() 1670 cdef vector[eh.EntityHandle] hvec 1671 if as_list: 1672 err = self.inst.get_entities_by_handle(<unsigned long> meshset, hvec, recur) 1673 check_error(err, exceptions) 1674 return hvec 1675 else: 1676 err = self.inst.get_entities_by_handle(<unsigned long> meshset, deref(ents.inst), recur) 1677 check_error(err, exceptions) 1678 return ents 1679 1680 def get_entities_by_dimension(self, meshset, int dimension, bint recur = False, bint as_list = False, exceptions = ()): 1681 """ 1682 Retrieves all entities of a given topological dimension in the database or meshset 1683 1684 Parameters 1685 ---------- 1686 meshset : MOAB EntityHandle 1687 meshset whose entities are being queried 1688 dimension : integer 1689 topological dimension of the entities desired 1690 recur : bool (default is False) 1691 if True, meshsets containing meshsets are queried recusively. The 1692 contenst of these meshsets are returned, but not the meshsets 1693 themselves. 1694 as_list : return entities in a list (preserves ordering if necessary, but 1695 consumes more memory) 1696 Returns 1697 ------- 1698 MOAB Range of EntityHandles 1699 1700 Raises 1701 ------ 1702 MOAB ErrorCode 1703 if a MOAB error occurs 1704 ValueError 1705 if the Meshset EntityHandle is not of the correct type or 1706 if the EntityType provided is not valid 1707 """ 1708 cdef moab.ErrorCode err 1709 cdef Range ents = Range() 1710 cdef vector[eh.EntityHandle] hvec 1711 if as_list: 1712 err = self.inst.get_entities_by_dimension(<unsigned long> meshset, dimension, hvec, recur) 1713 check_error(err, exceptions) 1714 return hvec 1715 else: 1716 err = self.inst.get_entities_by_dimension(<unsigned long> meshset, dimension, deref(ents.inst), recur) 1717 check_error(err, exceptions) 1718 return ents 1719 1720 def delete_mesh(self): 1721 """Deletes all mesh entities from the database""" 1722 self.inst.delete_mesh() 1723 1724 def _validate_data_for_tag(self, Tag tag, data_arr): 1725 """Internal method for validating tag data.""" 1726 1727 cdef moab.ErrorCode err 1728 cdef moab.DataType tag_type = moab.MB_MAX_DATA_TYPE 1729 cdef int tag_length = 0 1730 # make sure we're dealing with a 1-D array at this point 1731 assert data_arr.ndim == 1 1732 # if None is passed, set pointer to NULL and continue 1733 if data_arr[0] == None: 1734 return None 1735 else: 1736 # otherwise get the tag type 1737 err = self.inst.tag_get_data_type(tag.inst, tag_type) 1738 check_error(err) 1739 #and length 1740 err = self.inst.tag_get_length(tag.inst,tag_length); 1741 check_error(err) 1742 #check that the data_arr for this tag is the correct length 1743 if tag_type == moab.MB_TYPE_OPAQUE: 1744 #if this is an opaque tag, there should only be one 1745 #string entry in the array 1746 assert data_arr.size == 1 1747 else: 1748 assert data_arr.size == tag_length 1749 #validate the array type and convert the dtype if necessary 1750 data_arr = validate_type(tag_type, tag_length, data_arr) 1751 return data_arr 1752 1753 def tag_get_default_value(self, Tag tag, exceptions = () ): 1754 """ 1755 Returns the default value for a tag as a 1-D numpy array 1756 1757 Parameters 1758 ---------- 1759 tag : MOAB tag 1760 1761 Returns 1762 ------- 1763 NumPy 1-D array 1764 1765 Raises 1766 ------ 1767 MOAB ErrorCode 1768 if an internal MOAB error occurs 1769 """ 1770 # get the tag type and length for validation 1771 cdef moab.DataType tag_type = moab.MB_MAX_DATA_TYPE 1772 err = self.inst.tag_get_data_type(tag.inst, tag_type); 1773 check_error(err,()) 1774 cdef int length = 0 1775 err = self.inst.tag_get_length(tag.inst,length); 1776 check_error(err,()) 1777 #create array to hold data 1778 cdef np.ndarray data 1779 if tag_type is types.MB_TYPE_OPAQUE: 1780 data = np.empty((1,),dtype='S'+str(length)) 1781 else: 1782 data = np.empty((length,),dtype=np.dtype(np_tag_type(tag_type))) 1783 err = self.inst.tag_get_default_value(tag.inst, <void*> data.data) 1784 check_error(err, exceptions) 1785 return data 1786 1787 def tag_get_length(self, Tag tag, exceptions = () ): 1788 """ 1789 Returns an integer representing the tag's length 1790 1791 Parameters 1792 ---------- 1793 tag : MOAB tag 1794 1795 Returns 1796 ------- 1797 int : the tag length 1798 1799 Raises 1800 ------ 1801 MOAB ErrorCode 1802 if an internal MOAB error occurs 1803 """ 1804 cdef int length = 0 1805 err = self.inst.tag_get_length(tag.inst, length) 1806 check_error(err, exceptions) 1807 return length 1808 1809 def tag_get_tags_on_entity(self, entity): 1810 """ 1811 Retrieves all tags for a given EntityHandle 1812 1813 Parameters 1814 ---------- 1815 entity : MOAB EntityHandle 1816 1817 Returns 1818 ------- 1819 A list of tags on that entity 1820 1821 Raises 1822 ------ 1823 MOAB ErrorCode 1824 if an internal MOAB error occurs 1825 """ 1826 cdef vector[moab.TagInfo*] tags 1827 err = self.inst.tag_get_tags_on_entity(entity, tags) 1828 tag_list = [] 1829 for tag in tags: 1830 t = Tag() 1831 t.inst = tag 1832 tag_list.append(t) 1833 return tag_list 1834