xref: /petsc/src/binding/petsc4py/src/petsc4py/PETSc/petscobj.pxi (revision f73bfc444f01cd53364f186d523b473a6ee5b07a)
1# --------------------------------------------------------------------
2
3cdef extern from * nogil:
4
5    ctypedef int PetscClassId
6    ctypedef long PetscObjectState
7    ctypedef long PetscObjectId
8    PetscErrorCode PetscObjectView(PetscObject, PetscViewer)
9    PetscErrorCode PetscObjectDestroy(PetscObject*)
10    PetscErrorCode PetscObjectGetReference(PetscObject, PetscInt*)
11    PetscErrorCode PetscObjectReference(PetscObject)
12    PetscErrorCode PetscObjectDereference(PetscObject)
13
14    PetscErrorCode PetscObjectSetOptionsPrefix(PetscObject, char[])
15    PetscErrorCode PetscObjectAppendOptionsPrefix(PetscObject, char[])
16    PetscErrorCode PetscObjectGetOptionsPrefix(PetscObject, char*[])
17    PetscErrorCode PetscObjectSetFromOptions(PetscObject)
18    PetscErrorCode PetscObjectViewFromOptions(PetscObject, PetscObject, char[])
19
20    PetscErrorCode PetscObjectGetComm(PetscObject, MPI_Comm*)
21    PetscErrorCode PetscObjectGetClassId(PetscObject, PetscClassId*)
22    PetscErrorCode PetscObjectGetType(PetscObject, char*[])
23    PetscErrorCode PetscObjectGetClassName(PetscObject, char*[])
24    PetscErrorCode PetscObjectSetName(PetscObject, char[])
25    PetscErrorCode PetscObjectGetName(PetscObject, char*[])
26    PetscErrorCode PetscObjectGetId(PetscObject, PetscObjectId*)
27
28    PetscErrorCode PetscObjectStateIncrease(PetscObject)
29    PetscErrorCode PetscObjectStateSet(PetscObject, PetscObjectState)
30    PetscErrorCode PetscObjectStateGet(PetscObject, PetscObjectState*)
31    PetscErrorCode PetscObjectTypeCompare(PetscObject, char[], PetscBool*)
32    PetscErrorCode PetscObjectChangeTypeName(PetscObject, char[])
33    PetscErrorCode PetscObjectCompose(PetscObject, char[], PetscObject)
34    PetscErrorCode PetscObjectQuery(PetscObject, char[], PetscObject*)
35
36    ctypedef void (*PetscVoidFunction)()
37    PetscErrorCode PetscObjectComposeFunction(PetscObject, char[], PetscVoidFunction)
38    PetscErrorCode PetscObjectQueryFunction(PetscObject, char[], PetscVoidFunction*)
39
40    PetscErrorCode PetscObjectIncrementTabLevel(PetscObject, PetscObject, PetscInt)
41    PetscErrorCode PetscObjectGetTabLevel(PetscObject, PetscInt*)
42    PetscErrorCode PetscObjectSetTabLevel(PetscObject, PetscInt)
43
44    ctypedef struct _n_PetscOptionItems
45    ctypedef _n_PetscOptionItems* PetscOptionItems
46
47    ctypedef PetscErrorCode (*PetscObjectOptionsHandler)(PetscObject,
48                                                         PetscOptionItems,
49                                                         void*) except PETSC_ERR_PYTHON
50    ctypedef PetscErrorCode (*PetscObjectOptionsCtxDel)(PetscObject, void*)
51    PetscErrorCode PetscObjectAddOptionsHandler(PetscObject,
52                                                PetscObjectOptionsHandler,
53                                                PetscObjectOptionsCtxDel,
54                                                void*)
55    PetscErrorCode PetscObjectDestroyOptionsHandlers(PetscObject)
56
57cdef extern from * nogil: # custom.h
58    PetscErrorCode PetscObjectGetDeviceId(PetscObject, PetscInt*)
59
60cdef extern from "<petsc/private/garbagecollector.h>" nogil:
61    PetscErrorCode PetscObjectDelayedDestroy(PetscObject*)
62
63# --------------------------------------------------------------------
64
65cdef inline PetscErrorCode PetscINCREF(PetscObject *obj) noexcept nogil:
66    if obj    == NULL: return PETSC_SUCCESS
67    if obj[0] == NULL: return PETSC_SUCCESS
68    return PetscObjectReference(obj[0])
69
70cdef inline PetscErrorCode PetscDECREF(PetscObject *obj) noexcept nogil:
71    if obj    == NULL: return PETSC_SUCCESS
72    if obj[0] == NULL: return PETSC_SUCCESS
73    return PetscObjectDereference(obj[0])
74
75cdef inline PetscErrorCode PetscCLEAR(PetscObject* obj) noexcept nogil:
76    if obj    == NULL: return PETSC_SUCCESS
77    if obj[0] == NULL: return PETSC_SUCCESS
78    cdef PetscObject tmp
79    tmp = obj[0]; obj[0] = NULL
80    return PetscObjectDestroy(&tmp)
81
82cdef inline PetscErrorCode PetscDEALLOC(PetscObject* obj) noexcept nogil:
83    if obj    == NULL: return PETSC_SUCCESS
84    if obj[0] == NULL: return PETSC_SUCCESS
85    cdef PetscObject tmp
86    tmp = obj[0]; obj[0] = NULL
87    if not (<int>PetscInitializeCalled): return PETSC_SUCCESS
88    if     (<int>PetscFinalizeCalled):   return PETSC_SUCCESS
89    return PetscObjectDelayedDestroy(&tmp)
90
91cdef inline PetscErrorCode PetscINCSTATE(PetscObject *obj) noexcept nogil:
92    if obj    == NULL: return PETSC_SUCCESS
93    if obj[0] == NULL: return PETSC_SUCCESS
94    return PetscObjectStateIncrease(obj[0])
95
96# --------------------------------------------------------------------
97
98cdef extern from *:
99    ctypedef struct PyObject
100    void _Py_DecRef"Py_DECREF"(PyObject*)
101    PyObject* PyDict_New() except NULL
102    PyObject* PyDict_GetItem(PyObject*, PyObject*) except *
103    int       PyDict_SetItem(PyObject*, PyObject*, PyObject*) except -1
104    int       PyDict_DelItem(PyObject*, PyObject*) except -1
105
106cdef extern from * nogil:
107    ctypedef struct _p_PetscObject:
108        MPI_Comm comm
109        const char *prefix
110        PetscInt refct
111        void *python_context
112        PetscErrorCode (*python_destroy)(void*) noexcept nogil
113
114cdef inline void Py_DecRef(PyObject *ob) noexcept with gil:
115    _Py_DecRef(ob)
116
117cdef PetscErrorCode PetscDelPyDict(void* ptr) noexcept nogil:
118    if ptr != NULL and Py_IsInitialized():
119        Py_DecRef(<PyObject*>ptr)
120    return PETSC_SUCCESS
121
122cdef object PetscGetPyDict(PetscObject obj, bint create):
123    if obj.python_context != NULL:
124        return <object>obj.python_context
125    if create:
126        obj.python_destroy = PetscDelPyDict
127        obj.python_context = <void*>PyDict_New()
128        return <object>obj.python_context
129    return None
130
131cdef inline object PetscGetPyObj(PetscObject o, char name[]):
132    cdef object dct = PetscGetPyDict(o, False)
133    if dct is None: return None
134    cdef object key = bytes2str(name)
135    cdef PyObject *d = <PyObject*>dct
136    cdef PyObject *k = <PyObject*>key
137    cdef PyObject *v = NULL
138    v = PyDict_GetItem(d, k)
139    if v != NULL: return <object>v
140    return None
141
142cdef inline object PetscSetPyObj(PetscObject o, char name[], object p):
143    cdef object dct
144    if p is not None:
145        dct = PetscGetPyDict(o, True)
146    else:
147        dct = PetscGetPyDict(o, False)
148        if dct is None: return None
149    cdef str key = bytes2str(name)
150    cdef PyObject *d = <PyObject*>dct
151    cdef PyObject *k = <PyObject*>key
152    cdef PyObject *v = <PyObject*>p
153    PyDict_SetItem(d, k, v)
154    if v == <PyObject*>None:
155        PyDict_DelItem(d, k)
156    return None
157
158# --------------------------------------------------------------------
159
160cdef extern from *:
161    object PyLong_FromVoidPtr(void*)
162
163cdef inline Py_intptr_t Object_toFortran(PetscObject o) nogil:
164    return <Py_intptr_t> o
165
166# --------------------------------------------------------------------
167
168cdef inline type subtype_DM(PetscDM dm):
169    cdef PetscObject obj = <PetscObject> dm
170    if obj == NULL: return DM
171    # ---
172    cdef PetscBool match = PETSC_FALSE
173    CHKERR(PetscObjectTypeCompare(obj, b"da", &match))
174    if match == PETSC_TRUE: return DMDA
175    CHKERR(PetscObjectTypeCompare(obj, b"plex", &match))
176    if match == PETSC_TRUE: return DMPlex
177    CHKERR(PetscObjectTypeCompare(obj, b"composite", &match))
178    if match == PETSC_TRUE: return DMComposite
179    CHKERR(PetscObjectTypeCompare(obj, b"shell", &match))
180    if match == PETSC_TRUE: return DMShell
181    CHKERR(PetscObjectTypeCompare(obj, b"stag", &match))
182    if match == PETSC_TRUE: return DMStag
183    CHKERR(PetscObjectTypeCompare(obj, b"swarm", &match))
184    if match == PETSC_TRUE: return DMSwarm
185    # ---
186    return DM
187
188cdef inline type subtype_Object(PetscObject obj):
189    cdef type klass = Object
190    if obj == NULL: return klass
191    cdef PetscClassId classid = 0
192    CHKERR(PetscObjectGetClassId(obj, &classid))
193    if classid == PETSC_DM_CLASSID:
194        klass = subtype_DM(<PetscDM>obj)
195    else:
196        klass = PyPetscType_Lookup(classid)
197    return klass
198
199# --------------------------------------------------------------------
200
201cdef PetscErrorCode PetscObjectOptionsHandler_PYTHON(
202    PetscObject obj,
203    PetscOptionItems unused_PetscOptionsObject,
204    void *unused_ctx,
205   ) except PETSC_ERR_PYTHON with gil:
206    cdef Object pobj = PyPetscObject_New(obj)
207    cdef object handler = pobj.get_attr('__optshandler__')
208    if handler is None: return PETSC_SUCCESS
209    handler(pobj)
210    return PETSC_SUCCESS
211