1# -------------------------------------------------------------------- 2 3cdef class Object: 4 """Base class wrapping a PETSc object. 5 6 See Also 7 -------- 8 petsc.PetscObject 9 10 """ 11 # --- special methods --- 12 13 def __cinit__(self): 14 self.oval = NULL 15 self.obj = &self.oval 16 17 def __dealloc__(self): 18 CHKERR(PetscDEALLOC(&self.obj[0])) 19 self.obj = NULL 20 21 def __richcmp__(self, other, int op): 22 if not isinstance(self, Object): return NotImplemented 23 if not isinstance(other, Object): return NotImplemented 24 cdef Object s = self, o = other 25 if op == 2: return (s.obj[0] == o.obj[0]) 26 elif op == 3: return (s.obj[0] != o.obj[0]) 27 else: raise TypeError("only '==' and '!='") 28 29 def __bool__(self): 30 return self.obj[0] != NULL 31 32 def __copy__(self): 33 cdef Object obj = type(self)() 34 cdef PetscObject o = self.obj[0] 35 if o != NULL: 36 CHKERR(PetscObjectReference(o)) 37 obj.obj[0] = o 38 return obj 39 40 def __deepcopy__(self, dict memo): 41 cdef object obj_copy = None 42 try: 43 obj_copy = self.copy 44 except AttributeError: 45 raise NotImplementedError 46 <void>memo # unused 47 return obj_copy() 48 49 # --- attribute management --- 50 51 cdef object get_attr(self, char name[]): 52 return PetscGetPyObj(self.obj[0], name) 53 54 cdef object set_attr(self, char name[], object attr): 55 return PetscSetPyObj(self.obj[0], name, attr) 56 57 cdef object get_dict(self): 58 return PetscGetPyDict(self.obj[0], True) 59 60 # 61 62 def view(self, Viewer viewer=None) -> None: 63 """Display the object. 64 65 Collective. 66 67 Parameters 68 ---------- 69 viewer 70 A `Viewer` instance or `None` for the default viewer. 71 72 See Also 73 -------- 74 petsc.PetscObjectView 75 76 """ 77 cdef PetscViewer vwr = NULL 78 if viewer is not None: vwr = viewer.vwr 79 CHKERR(PetscObjectView(self.obj[0], vwr)) 80 81 def destroy(self) -> Self: 82 """Destroy the object. 83 84 Collective. 85 86 See Also 87 -------- 88 petsc.PetscObjectDestroy 89 90 """ 91 CHKERR(PetscObjectDestroy(&self.obj[0])) 92 return self 93 94 def getType(self) -> str: 95 """Return the object type name. 96 97 Not collective. 98 99 See Also 100 -------- 101 petsc.PetscObjectGetType 102 103 """ 104 cdef const char *cval = NULL 105 CHKERR(PetscObjectGetType(self.obj[0], &cval)) 106 return bytes2str(cval) 107 108 # 109 110 def setOptionsPrefix(self, prefix : str | None) -> None: 111 """Set the prefix used for searching for options in the database. 112 113 Logically collective. 114 115 See Also 116 -------- 117 petsc_options, getOptionsPrefix, petsc.PetscObjectSetOptionsPrefix 118 119 """ 120 cdef const char *cval = NULL 121 prefix = str2bytes(prefix, &cval) 122 CHKERR(PetscObjectSetOptionsPrefix(self.obj[0], cval)) 123 124 def getOptionsPrefix(self) -> str: 125 """Return the prefix used for searching for options in the database. 126 127 Not collective. 128 129 See Also 130 -------- 131 petsc_options, setOptionsPrefix, petsc.PetscObjectGetOptionsPrefix 132 133 """ 134 cdef const char *cval = NULL 135 CHKERR(PetscObjectGetOptionsPrefix(self.obj[0], &cval)) 136 return bytes2str(cval) 137 138 def appendOptionsPrefix(self, prefix: str | None) -> None: 139 """Append to the prefix used for searching for options in the database. 140 141 Logically collective. 142 143 See Also 144 -------- 145 petsc_options, setOptionsPrefix, petsc.PetscObjectAppendOptionsPrefix 146 147 """ 148 cdef const char *cval = NULL 149 prefix = str2bytes(prefix, &cval) 150 CHKERR(PetscObjectAppendOptionsPrefix(self.obj[0], cval)) 151 152 def setFromOptions(self) -> None: 153 """Configure the object from the options database. 154 155 Collective. 156 157 Classes that do not implement ``setFromOptions`` use this method 158 that, in turn, calls `petsc.PetscObjectSetFromOptions`. 159 160 See Also 161 -------- 162 petsc_options, petsc.PetscObjectSetFromOptions 163 164 """ 165 CHKERR(PetscObjectSetFromOptions(self.obj[0])) 166 167 def viewFromOptions(self, name : str, Object objpre=None) -> None: 168 """View the object via command line options. 169 170 Collective. 171 172 Parameters 173 ---------- 174 name 175 The command line option. 176 objpre 177 Optional object that provides prefix. 178 179 See Also 180 -------- 181 petsc_options, petsc.PetscObjectViewFromOptions 182 183 """ 184 cdef PetscObject pobj = NULL 185 cdef const char *cval = NULL 186 pobj = objpre.obj[0] if objpre is not None else NULL 187 name = str2bytes(name, &cval) 188 CHKERR(PetscObjectViewFromOptions(self.obj[0], pobj, cval)) 189 190 def setOptionsHandler(self, handler: PetscOptionsHandlerFunction | None) -> None: 191 """Set the callback for processing extra options. 192 193 Logically collective. 194 195 Parameters 196 ---------- 197 handler 198 The callback function, called at the end of a ``setFromOptions`` invocation 199 for the given class. 200 201 See Also 202 -------- 203 petsc_options, Mat.setFromOptions, KSP.setFromOptions 204 petsc.PetscObjectAddOptionsHandler 205 206 """ 207 if handler is not None: 208 CHKERR(PetscObjectAddOptionsHandler(self.obj[0], PetscObjectOptionsHandler_PYTHON, NULL, NULL)) 209 self.set_attr('__optshandler__', handler) 210 else: 211 self.set_attr('__optshandler__', None) 212 213 def destroyOptionsHandlers(self) -> None: 214 """Clear all the option handlers. 215 216 Collective. 217 218 See Also 219 -------- 220 petsc_options, setOptionsHandler, petsc.PetscObjectDestroyOptionsHandlers 221 222 """ 223 self.set_attr('__optshandler__', None) 224 CHKERR(PetscObjectDestroyOptionsHandlers(self.obj[0])) 225 226 # 227 228 def getComm(self) -> Comm: 229 """Return the communicator of the object. 230 231 Not collective. 232 233 See Also 234 -------- 235 petsc.PetscObjectGetComm 236 237 """ 238 cdef Comm comm = Comm() 239 CHKERR(PetscObjectGetComm(self.obj[0], &comm.comm)) 240 return comm 241 242 def getName(self) -> str: 243 """Return the name of the object. 244 245 Not collective. 246 247 See Also 248 -------- 249 petsc.PetscObjectGetName 250 251 """ 252 cdef const char *cval = NULL 253 CHKERR(PetscObjectGetName(self.obj[0], &cval)) 254 return bytes2str(cval) 255 256 def setName(self, name : str | None) -> None: 257 """Associate a name to the object. 258 259 Not collective. 260 261 See Also 262 -------- 263 petsc.PetscObjectSetName 264 265 """ 266 cdef const char *cval = NULL 267 name = str2bytes(name, &cval) 268 CHKERR(PetscObjectSetName(self.obj[0], cval)) 269 270 def getClassId(self) -> int: 271 """Return the class identifier of the object. 272 273 Not collective. 274 275 See Also 276 -------- 277 petsc.PetscObjectGetClassId 278 279 """ 280 cdef PetscClassId classid = 0 281 CHKERR(PetscObjectGetClassId(self.obj[0], &classid)) 282 return <long>classid 283 284 def getClassName(self) -> str: 285 """Return the class name of the object. 286 287 Not collective. 288 289 See Also 290 -------- 291 petsc.PetscObjectGetClassName 292 293 """ 294 cdef const char *cval = NULL 295 CHKERR(PetscObjectGetClassName(self.obj[0], &cval)) 296 return bytes2str(cval) 297 298 def getRefCount(self) -> int: 299 """Return the reference count of the object. 300 301 Not collective. 302 303 See Also 304 -------- 305 petsc.PetscObjectGetReference 306 307 """ 308 if self.obj[0] == NULL: return 0 309 cdef PetscInt refcnt = 0 310 CHKERR(PetscObjectGetReference(self.obj[0], &refcnt)) 311 return toInt(refcnt) 312 313 def getId(self) -> int: 314 """Return the unique identifier of the object. 315 316 Not collective. 317 318 See Also 319 -------- 320 petsc.PetscObjectGetId 321 322 """ 323 cdef PetscObjectId cid = 0 324 CHKERR(PetscObjectGetId(self.obj[0], &cid)) 325 return <long>cid 326 327 # --- general support --- 328 329 def compose(self, name : str | None, Object obj or None) -> None: 330 """Associate a PETSc object using a key string. 331 332 Logically collective. 333 334 Parameters 335 ---------- 336 name 337 The string identifying the object to be composed. 338 obj 339 The object to be composed. 340 341 See Also 342 -------- 343 query, petsc.PetscObjectCompose 344 345 """ 346 cdef const char *cval = NULL 347 cdef PetscObject cobj = NULL 348 name = str2bytes(name, &cval) 349 if obj is not None: cobj = obj.obj[0] 350 CHKERR(PetscObjectCompose(self.obj[0], cval, cobj)) 351 352 def query(self, name: str) -> Object: 353 """Query for the PETSc object associated with a key string. 354 355 Not collective. 356 357 See Also 358 -------- 359 compose, petsc.PetscObjectQuery 360 361 """ 362 cdef const char *cval = NULL 363 cdef PetscObject cobj = NULL 364 name = str2bytes(name, &cval) 365 CHKERR(PetscObjectQuery(self.obj[0], cval, &cobj)) 366 if cobj == NULL: return None 367 cdef Object obj = subtype_Object(cobj)() 368 obj.obj[0] = cobj 369 CHKERR(PetscINCREF(obj.obj)) 370 return obj 371 372 def incRef(self) -> int: 373 """Increment the object reference count. 374 375 Logically collective. 376 377 See Also 378 -------- 379 getRefCount, petsc.PetscObjectReference 380 381 """ 382 cdef PetscObject obj = self.obj[0] 383 cdef PetscInt refct = 0 384 if obj != NULL: 385 CHKERR(PetscObjectReference(obj)) 386 CHKERR(PetscObjectGetReference(obj, &refct)) 387 return toInt(refct) 388 389 def decRef(self) -> int: 390 """Decrement the object reference count. 391 392 Logically collective. 393 394 See Also 395 -------- 396 getRefCount, petsc.PetscObjectDereference 397 398 """ 399 cdef PetscObject obj = self.obj[0] 400 cdef PetscInt refct = 0 401 if obj != NULL: 402 CHKERR(PetscObjectGetReference(obj, &refct)) 403 CHKERR(PetscObjectDereference(obj)) 404 if refct == 1: self.obj[0] = NULL 405 refct -= 1 406 return toInt(refct) 407 408 def getAttr(self, name : str) -> object: 409 """Return the attribute associated with a given name. 410 411 Not collective. 412 413 See Also 414 -------- 415 setAttr, getDict 416 417 """ 418 cdef const char *cval = NULL 419 name = str2bytes(name, &cval) 420 return self.get_attr(<char*>cval) 421 422 def setAttr(self, name : str, attr : object) -> None: 423 """Set an the attribute associated with a given name. 424 425 Not collective. 426 427 See Also 428 -------- 429 getAttr, getDict 430 431 """ 432 cdef const char *cval = NULL 433 name = str2bytes(name, &cval) 434 self.set_attr(<char*>cval, attr) 435 436 def getDict(self) -> dict: 437 """Return the dictionary of attributes. 438 439 Not collective. 440 441 See Also 442 -------- 443 setAttr, getAttr 444 445 """ 446 return self.get_dict() 447 448 # --- state manipulation --- 449 450 def stateIncrease(self) -> None: 451 """Increment the PETSc object state. 452 453 Logically collective. 454 455 See Also 456 -------- 457 stateGet, stateSet, petsc.PetscObjectStateIncrease 458 459 """ 460 PetscINCSTATE(self.obj) 461 462 def stateGet(self) -> int: 463 """Return the PETSc object state. 464 465 Not collective. 466 467 See Also 468 -------- 469 stateSet, stateIncrease, petsc.PetscObjectStateGet 470 471 """ 472 cdef PetscObjectState state = 0 473 CHKERR(PetscObjectStateGet(self.obj[0], &state)) 474 return <long>state 475 476 def stateSet(self, state : int) -> None: 477 """Set the PETSc object state. 478 479 Logically collective. 480 481 See Also 482 -------- 483 stateIncrease, stateGet, petsc.PetscObjectStateSet 484 485 """ 486 cdef PetscObjectState cstate = asInt(state) 487 CHKERR(PetscObjectStateSet(self.obj[0], cstate)) 488 489 # --- tab level --- 490 491 def incrementTabLevel(self, tab : int, Object parent=None) -> None: 492 """Increment the PETSc object tab level. 493 494 Logically collective. 495 496 See Also 497 -------- 498 setTabLevel, getTabLevel, petsc.PetscObjectIncrementTabLevel 499 500 """ 501 cdef PetscInt ctab = asInt(tab) 502 cdef PetscObject cobj = <PetscObject> NULL if parent is None else parent.obj[0] 503 CHKERR(PetscObjectIncrementTabLevel(self.obj[0], cobj, ctab)) 504 505 def setTabLevel(self, level : int) -> None: 506 """Set the PETSc object tab level. 507 508 Logically collective. 509 510 See Also 511 -------- 512 incrementTabLevel, getTabLevel, petsc.PetscObjectSetTabLevel 513 514 """ 515 cdef PetscInt clevel = asInt(level) 516 CHKERR(PetscObjectSetTabLevel(self.obj[0], clevel)) 517 518 def getTabLevel(self) -> None: 519 """Return the PETSc object tab level. 520 521 Not collective. 522 523 See Also 524 -------- 525 setTabLevel, incrementTabLevel, petsc.PetscObjectGetTabLevel 526 527 """ 528 cdef PetscInt clevel = 0 529 CHKERR(PetscObjectGetTabLevel(self.obj[0], &clevel)) 530 return toInt(clevel) 531 532 # --- properties --- 533 534 property type: 535 """Object type.""" 536 def __get__(self) -> str: 537 return self.getType() 538 539 def __set__(self, value): 540 self.setType(value) 541 542 property prefix: 543 """Options prefix.""" 544 def __get__(self) -> str: 545 return self.getOptionsPrefix() 546 547 def __set__(self, value): 548 self.setOptionsPrefix(value) 549 550 property comm: 551 """The object communicator.""" 552 def __get__(self) -> Comm: 553 return self.getComm() 554 555 property name: 556 """The object name.""" 557 def __get__(self) -> str: 558 return self.getName() 559 560 def __set__(self, value): 561 self.setName(value) 562 563 property classid: 564 """The class identifier.""" 565 def __get__(self) -> int: 566 return self.getClassId() 567 568 property id: 569 """The object identifier.""" 570 def __get__(self) -> int: 571 return self.getId() 572 573 property klass: 574 """The class name.""" 575 def __get__(self) -> str: 576 return self.getClassName() 577 578 property refcount: 579 """Reference count.""" 580 def __get__(self) -> int: 581 return self.getRefCount() 582 583 # --- ctypes support --- 584 585 property handle: 586 """Handle for ctypes support.""" 587 def __get__(self) -> int: 588 cdef PetscObject obj = self.obj[0] 589 return PyLong_FromVoidPtr(<void*>obj) 590 591 # --- Fortran support --- 592 593 property fortran: 594 """Fortran handle.""" 595 def __get__(self) -> int: 596 cdef PetscObject obj = self.obj[0] 597 return Object_toFortran(obj) 598 599# -------------------------------------------------------------------- 600 601include "cyclicgc.pxi" 602 603cdef dict type_registry = {0 : None} 604__type_registry__ = type_registry 605 606cdef int PyPetscType_Register(int classid, type cls) except -1: 607 global type_registry 608 cdef object key = <long>classid 609 cdef object value = cls 610 cdef const char *dummy = NULL 611 if key not in type_registry: 612 type_registry[key] = cls 613 reg_LogClass(str2bytes(cls.__name__, &dummy), 614 <PetscLogClass>classid) 615 TypeEnableGC(<PyTypeObject*>cls) 616 else: 617 value = type_registry[key] 618 if cls is not value: 619 raise ValueError( 620 "key: %d, cannot register: %s, " 621 "already registered: %s" % (key, cls, value)) 622 return 0 623 624cdef type PyPetscType_Lookup(int classid): 625 global type_registry 626 cdef object key = <long>classid 627 cdef type cls = Object 628 try: 629 cls = type_registry[key] 630 except KeyError: 631 cls = Object 632 return cls 633 634# -------------------------------------------------------------------- 635