xref: /petsc/src/sys/objects/inherit.c (revision da93591f59bc1e95f467c6fc21a755040df0b8f3)
1 #define PETSC_DLL
2 /*
3      Provides utility routines for manipulating any type of PETSc object.
4 */
5 #include "petsc.h"  /*I   "petsc.h"    I*/
6 #include "petscsys.h"
7 
8 EXTERN PetscErrorCode PetscObjectGetComm_Petsc(PetscObject,MPI_Comm *);
9 EXTERN PetscErrorCode PetscObjectCompose_Petsc(PetscObject,const char[],PetscObject);
10 EXTERN PetscErrorCode PetscObjectQuery_Petsc(PetscObject,const char[],PetscObject *);
11 EXTERN PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject,const char[],const char[],void (*)(void));
12 EXTERN PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject,const char[],void (**)(void));
13 
14 #undef __FUNCT__
15 #define __FUNCT__ "PetscHeaderCreate_Private"
16 /*
17    PetscHeaderCreate_Private - Creates a base PETSc object header and fills
18    in the default values.  Called by the macro PetscHeaderCreate().
19 */
20 PetscErrorCode PETSC_DLLEXPORT PetscHeaderCreate_Private(PetscObject h,PetscCookie cookie,PetscInt type,const char class_name[],MPI_Comm comm,
21                                          PetscErrorCode (*des)(PetscObject),PetscErrorCode (*vie)(PetscObject,PetscViewer))
22 {
23   static PetscInt idcnt = 1;
24   PetscErrorCode  ierr;
25 
26   PetscFunctionBegin;
27   h->cookie                 = cookie;
28   h->type                   = type;
29   h->class_name             = (char*)class_name;
30   h->prefix                 = 0;
31   h->refct                  = 1;
32   h->amem                   = -1;
33   h->id                     = idcnt++;
34   h->parentid               = 0;
35   h->qlist                  = 0;
36   h->olist                  = 0;
37   h->bops->destroy          = des;
38   h->bops->view             = vie;
39   h->bops->getcomm          = PetscObjectGetComm_Petsc;
40   h->bops->compose          = PetscObjectCompose_Petsc;
41   h->bops->query            = PetscObjectQuery_Petsc;
42   h->bops->composefunction  = PetscObjectComposeFunction_Petsc;
43   h->bops->queryfunction    = PetscObjectQueryFunction_Petsc;
44   ierr = PetscCommDuplicate(comm,&h->comm,&h->tag);CHKERRQ(ierr);
45   PetscFunctionReturn(0);
46 }
47 
48 extern PetscTruth     PetscMemoryCollectMaximumUsage;
49 extern PetscLogDouble PetscMemoryMaximumUsage;
50 
51 #undef __FUNCT__
52 #define __FUNCT__ "PetscHeaderDestroy_Private"
53 /*
54     PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by
55     the macro PetscHeaderDestroy().
56 */
57 PetscErrorCode PETSC_DLLEXPORT PetscHeaderDestroy_Private(PetscObject h)
58 {
59   PetscErrorCode ierr;
60 
61   PetscFunctionBegin;
62   if (PetscMemoryCollectMaximumUsage) {
63     PetscLogDouble usage;
64     ierr = PetscMemoryGetCurrentUsage(&usage);CHKERRQ(ierr);
65     if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage;
66   }
67   /* first destroy things that could execute arbitrary code */
68   if (h->python_destroy) {
69     void           *python_context          = h->python_context;
70     PetscErrorCode (*python_destroy)(void*) = h->python_destroy;
71     h->python_context = 0;
72     h->python_destroy = 0;
73     ierr = (*python_destroy)(python_context);CHKERRQ(ierr);
74   }
75   ierr = PetscOListDestroy(h->olist);CHKERRQ(ierr);
76   ierr = PetscCommDestroy(&h->comm);CHKERRQ(ierr);
77   /* next destroy other things */
78   h->cookie = PETSCFREEDHEADER;
79   ierr = PetscFree(h->bops);CHKERRQ(ierr);
80   ierr = PetscFListDestroy(&h->qlist);CHKERRQ(ierr);
81   ierr = PetscStrfree(h->type_name);CHKERRQ(ierr);
82   ierr = PetscStrfree(h->name);CHKERRQ(ierr);
83   ierr = PetscStrfree(h->prefix);CHKERRQ(ierr);
84   ierr = PetscFree(h->fortran_func_pointers);CHKERRQ(ierr);
85   ierr = PetscFree(h->intcomposeddata);CHKERRQ(ierr);
86   ierr = PetscFree(h->intcomposedstate);CHKERRQ(ierr);
87   ierr = PetscFree(h->realcomposeddata);CHKERRQ(ierr);
88   ierr = PetscFree(h->realcomposedstate);CHKERRQ(ierr);
89   ierr = PetscFree(h->scalarcomposeddata);CHKERRQ(ierr);
90   ierr = PetscFree(h->scalarcomposedstate);CHKERRQ(ierr);
91   PetscFunctionReturn(0);
92 }
93 
94 #undef __FUNCT__
95 #define __FUNCT__ "PetscObjectReference"
96 /*@C
97    PetscObjectReference - Indicates to any PetscObject that it is being
98    referenced by another PetscObject. This increases the reference
99    count for that object by one.
100 
101    Collective on PetscObject
102 
103    Input Parameter:
104 .  obj - the PETSc object. This must be cast with (PetscObject), for example,
105          PetscObjectReference((PetscObject)mat);
106 
107    Level: advanced
108 
109 .seealso: PetscObjectCompose(), PetscObjectDereference()
110 @*/
111 PetscErrorCode PETSC_DLLEXPORT PetscObjectReference(PetscObject obj)
112 {
113   PetscFunctionBegin;
114   PetscValidHeader(obj,1);
115   obj->refct++;
116   PetscFunctionReturn(0);
117 }
118 
119 #undef __FUNCT__
120 #define __FUNCT__ "PetscObjectGetReference"
121 /*@C
122    PetscObjectGetReference - Gets the current reference count for
123    any PETSc object.
124 
125    Not Collective
126 
127    Input Parameter:
128 .  obj - the PETSc object; this must be cast with (PetscObject), for example,
129          PetscObjectGetReference((PetscObject)mat,&cnt);
130 
131    Output Parameter:
132 .  cnt - the reference count
133 
134    Level: advanced
135 
136 .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
137 @*/
138 PetscErrorCode PETSC_DLLEXPORT PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
139 {
140   PetscFunctionBegin;
141   PetscValidHeader(obj,1);
142   PetscValidIntPointer(cnt,2);
143   *cnt = obj->refct;
144   PetscFunctionReturn(0);
145 }
146 
147 #undef __FUNCT__
148 #define __FUNCT__ "PetscObjectDereference"
149 /*@
150    PetscObjectDereference - Indicates to any PetscObject that it is being
151    referenced by one less PetscObject. This decreases the reference
152    count for that object by one.
153 
154    Collective on PetscObject
155 
156    Input Parameter:
157 .  obj - the PETSc object; this must be cast with (PetscObject), for example,
158          PetscObjectDereference((PetscObject)mat);
159 
160    Level: advanced
161 
162 .seealso: PetscObjectCompose(), PetscObjectReference()
163 @*/
164 PetscErrorCode PETSC_DLLEXPORT PetscObjectDereference(PetscObject obj)
165 {
166   PetscErrorCode ierr;
167 
168   PetscFunctionBegin;
169   PetscValidHeader(obj,1);
170   if (obj->bops->destroy) {
171     ierr = (*obj->bops->destroy)(obj);CHKERRQ(ierr);
172   } else if (!--obj->refct) {
173     SETERRQ(PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
174   }
175   PetscFunctionReturn(0);
176 }
177 
178 /* ----------------------------------------------------------------------- */
179 /*
180      The following routines are the versions private to the PETSc object
181      data structures.
182 */
183 #undef __FUNCT__
184 #define __FUNCT__ "PetscObjectGetComm_Petsc"
185 PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
186 {
187   PetscFunctionBegin;
188   *comm = obj->comm;
189   PetscFunctionReturn(0);
190 }
191 
192 #undef __FUNCT__
193 #define __FUNCT__ "PetscObjectCompose_Petsc"
194 PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
195 {
196   PetscErrorCode ierr;
197   char           *tname;
198 
199   PetscFunctionBegin;
200   if (ptr) {
201     ierr = PetscOListReverseFind(ptr->olist,obj,&tname);CHKERRQ(ierr);
202     if (tname){
203       SETERRQ(PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was compose with it");
204     }
205   }
206   ierr = PetscOListAdd(&obj->olist,name,ptr);CHKERRQ(ierr);
207   PetscFunctionReturn(0);
208 }
209 
210 #undef __FUNCT__
211 #define __FUNCT__ "PetscObjectQuery_Petsc"
212 PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
213 {
214   PetscErrorCode ierr;
215 
216   PetscFunctionBegin;
217   ierr = PetscOListFind(obj->olist,name,ptr);CHKERRQ(ierr);
218   PetscFunctionReturn(0);
219 }
220 
221 #undef __FUNCT__
222 #define __FUNCT__ "PetscObjectComposeFunction_Petsc"
223 PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
224 {
225   PetscErrorCode ierr;
226 
227   PetscFunctionBegin;
228   ierr = PetscFListAdd(&obj->qlist,name,fname,ptr);CHKERRQ(ierr);
229   PetscFunctionReturn(0);
230 }
231 
232 #undef __FUNCT__
233 #define __FUNCT__ "PetscObjectQueryFunction_Petsc"
234 PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
235 {
236   PetscErrorCode ierr;
237 
238   PetscFunctionBegin;
239   ierr = PetscFListFind(obj->qlist,obj->comm,name,ptr);CHKERRQ(ierr);
240   PetscFunctionReturn(0);
241 }
242 
243 /*
244         These are the versions that are usable to any CCA compliant objects
245 */
246 #undef __FUNCT__
247 #define __FUNCT__ "PetscObjectCompose"
248 /*@C
249    PetscObjectCompose - Associates another PETSc object with a given PETSc object.
250 
251    Not Collective
252 
253    Input Parameters:
254 +  obj - the PETSc object; this must be cast with (PetscObject), for example,
255          PetscObjectCompose((PetscObject)mat,...);
256 .  name - name associated with the child object
257 -  ptr - the other PETSc object to associate with the PETSc object; this must also be
258          cast with (PetscObject)
259 
260    Level: advanced
261 
262    Notes:
263    The second objects reference count is automatically increased by one when it is
264    composed.
265 
266    Replaces any previous object that had the same name.
267 
268    If ptr is null and name has previously been composed using an object, then that
269    entry is removed from the obj.
270 
271    PetscObjectCompose() can be used with any PETSc object (such as
272    Mat, Vec, KSP, SNES, etc.) or any user-provided object.  See
273    PetscContainerCreate() for info on how to create an object from a
274    user-provided pointer that may then be composed with PETSc objects.
275 
276    Concepts: objects^composing
277    Concepts: composing objects
278 
279 .seealso: PetscObjectQuery(), PetscContainerCreate()
280 @*/
281 PetscErrorCode PETSC_DLLEXPORT PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
282 {
283   PetscErrorCode ierr;
284 
285   PetscFunctionBegin;
286   PetscValidHeader(obj,1);
287   PetscValidCharPointer(name,2);
288   if (ptr) PetscValidHeader(ptr,3);
289   ierr = (*obj->bops->compose)(obj,name,ptr);CHKERRQ(ierr);
290   PetscFunctionReturn(0);
291 }
292 
293 #undef __FUNCT__
294 #define __FUNCT__ "PetscObjectQuery"
295 /*@C
296    PetscObjectQuery  - Gets a PETSc object associated with a given object.
297 
298    Not Collective
299 
300    Input Parameters:
301 +  obj - the PETSc object
302          Thus must be cast with a (PetscObject), for example,
303          PetscObjectCompose((PetscObject)mat,...);
304 .  name - name associated with child object
305 -  ptr - the other PETSc object associated with the PETSc object, this must also be
306          cast with (PetscObject)
307 
308    Level: advanced
309 
310    Concepts: objects^composing
311    Concepts: composing objects
312    Concepts: objects^querying
313    Concepts: querying objects
314 
315 .seealso: PetscObjectQuery()
316 @*/
317 PetscErrorCode PETSC_DLLEXPORT PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
318 {
319   PetscErrorCode ierr;
320 
321   PetscFunctionBegin;
322   PetscValidHeader(obj,1);
323   PetscValidCharPointer(name,2);
324   PetscValidPointer(ptr,3);
325   ierr = (*obj->bops->query)(obj,name,ptr);CHKERRQ(ierr);
326   PetscFunctionReturn(0);
327 }
328 
329 #undef __FUNCT__
330 #define __FUNCT__ "PetscObjectComposeFunction"
331 PetscErrorCode PETSC_DLLEXPORT PetscObjectComposeFunction(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
332 {
333   PetscErrorCode ierr;
334 
335   PetscFunctionBegin;
336   PetscValidHeader(obj,1);
337   PetscValidCharPointer(name,2);
338   PetscValidCharPointer(fname,2);
339   ierr = (*obj->bops->composefunction)(obj,name,fname,ptr);CHKERRQ(ierr);
340   PetscFunctionReturn(0);
341 }
342 
343 #undef __FUNCT__
344 #define __FUNCT__ "PetscObjectQueryFunction"
345 /*@C
346    PetscObjectQueryFunction - Gets a function associated with a given object.
347 
348    Collective on PetscObject
349 
350    Input Parameters:
351 +  obj - the PETSc object; this must be cast with (PetscObject), for example,
352          PetscObjectQueryFunction((PetscObject)ksp,...);
353 -  name - name associated with the child function
354 
355    Output Parameter:
356 .  ptr - function pointer
357 
358    Level: advanced
359 
360    Concepts: objects^composing functions
361    Concepts: composing functions
362    Concepts: functions^querying
363    Concepts: objects^querying
364    Concepts: querying objects
365 
366 .seealso: PetscObjectComposeFunctionDynamic()
367 @*/
368 PetscErrorCode PETSC_DLLEXPORT PetscObjectQueryFunction(PetscObject obj,const char name[],void (**ptr)(void))
369 {
370   PetscErrorCode ierr;
371 
372   PetscFunctionBegin;
373   PetscValidHeader(obj,1);
374   PetscValidCharPointer(name,2);
375   ierr = (*obj->bops->queryfunction)(obj,name,ptr);CHKERRQ(ierr);
376   PetscFunctionReturn(0);
377 }
378 
379 struct _p_PetscContainer {
380   PETSCHEADER(int);
381   void   *ptr;
382   PetscErrorCode (*userdestroy)(void*);
383 };
384 
385 #undef __FUNCT__
386 #define __FUNCT__ "PetscContainerGetPointer"
387 /*@C
388    PetscContainerGetPointer - Gets the pointer value contained in the container.
389 
390    Collective on PetscContainer
391 
392    Input Parameter:
393 .  obj - the object created with PetscContainerCreate()
394 
395    Output Parameter:
396 .  ptr - the pointer value
397 
398    Level: advanced
399 
400 .seealso: PetscContainerCreate(), PetscContainerDestroy(),
401           PetscContainerSetPointer()
402 @*/
403 PetscErrorCode PETSC_DLLEXPORT PetscContainerGetPointer(PetscContainer obj,void **ptr)
404 {
405   PetscFunctionBegin;
406   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_COOKIE,1);
407   PetscValidPointer(ptr,2);
408   *ptr = obj->ptr;
409   PetscFunctionReturn(0);
410 }
411 
412 
413 #undef __FUNCT__
414 #define __FUNCT__ "PetscContainerSetPointer"
415 /*@C
416    PetscContainerSetPointer - Sets the pointer value contained in the container.
417 
418    Collective on PetscContainer
419 
420    Input Parameters:
421 +  obj - the object created with PetscContainerCreate()
422 -  ptr - the pointer value
423 
424    Level: advanced
425 
426 .seealso: PetscContainerCreate(), PetscContainerDestroy(),
427           PetscContainerGetPointer()
428 @*/
429 PetscErrorCode PETSC_DLLEXPORT PetscContainerSetPointer(PetscContainer obj,void *ptr)
430 {
431   PetscFunctionBegin;
432   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_COOKIE,1);
433   if (ptr) PetscValidPointer(ptr,2);
434   obj->ptr = ptr;
435   PetscFunctionReturn(0);
436 }
437 
438 #undef __FUNCT__
439 #define __FUNCT__ "PetscContainerDestroy"
440 /*@C
441    PetscContainerDestroy - Destroys a PETSc container object.
442 
443    Collective on PetscContainer
444 
445    Input Parameter:
446 .  obj - an object that was created with PetscContainerCreate()
447 
448    Level: advanced
449 
450 .seealso: PetscContainerCreate()
451 @*/
452 PetscErrorCode PETSC_DLLEXPORT PetscContainerDestroy(PetscContainer obj)
453 {
454   PetscErrorCode ierr;
455   PetscFunctionBegin;
456   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_COOKIE,1);
457   if (--((PetscObject)obj)->refct > 0) PetscFunctionReturn(0);
458   if (obj->userdestroy) (*obj->userdestroy)(obj->ptr);
459   ierr = PetscHeaderDestroy(obj);CHKERRQ(ierr);
460   PetscFunctionReturn(0);
461 }
462 
463 #undef __FUNCT__
464 #define __FUNCT__ "PetscContainerSetUserDestroy"
465 /*@C
466    PetscContainerSetUserDestroy - Sets name of the user destroy function.
467 
468    Collective on PetscContainer
469 
470    Input Parameter:
471 +  obj - an object that was created with PetscContainerCreate()
472 -  des - name of the user destroy function
473 
474    Level: advanced
475 
476 .seealso: PetscContainerDestroy()
477 @*/
478 PetscErrorCode PETSC_DLLEXPORT PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
479 {
480   PetscFunctionBegin;
481   PetscValidHeaderSpecific(obj,PETSC_CONTAINER_COOKIE,1);
482   obj->userdestroy = des;
483   PetscFunctionReturn(0);
484 }
485 
486 PetscCookie PETSC_DLLEXPORT PETSC_CONTAINER_COOKIE;
487 
488 #undef __FUNCT__
489 #define __FUNCT__ "PetscContainerCreate"
490 /*@C
491    PetscContainerCreate - Creates a PETSc object that has room to hold
492    a single pointer. This allows one to attach any type of data (accessible
493    through a pointer) with the PetscObjectCompose() function to a PetscObject.
494    The data item itself is attached by a call to PetscContainerSetPointer.
495 
496    Collective on MPI_Comm
497 
498    Input Parameters:
499 .  comm - MPI communicator that shares the object
500 
501    Output Parameters:
502 .  container - the container created
503 
504    Level: advanced
505 
506 .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
507 @*/
508 PetscErrorCode PETSC_DLLEXPORT PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
509 {
510   PetscErrorCode ierr;
511   PetscContainer contain;
512 
513   PetscFunctionBegin;
514   PetscValidPointer(container,2);
515   ierr = PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_COOKIE,0,"PetscContainer",comm,PetscContainerDestroy,0);CHKERRQ(ierr);
516   *container = contain;
517   PetscFunctionReturn(0);
518 }
519 
520 #undef __FUNCT__
521 #define __FUNCT__ "PetscObjectSetFromOptions"
522 /*@
523    PetscObjectSetFromOptions - Sets generic parameters from user options.
524 
525    Collective on obj
526 
527    Input Parameter:
528 .  obj - the PetscObjcet
529 
530    Options Database Keys:
531 
532    Notes:
533    We have no generic options at present, so this does nothing
534 
535    Level: beginner
536 
537 .keywords: set, options, database
538 .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
539 @*/
540 PetscErrorCode PETSC_DLLEXPORT PetscObjectSetFromOptions(PetscObject obj)
541 {
542   PetscFunctionBegin;
543   PetscValidHeader(obj,1);
544   PetscFunctionReturn(0);
545 }
546 
547 #undef __FUNCT__
548 #define __FUNCT__ "PetscObjectSetUp"
549 /*@
550    PetscObjectSetUp - Sets up the internal data structures for the later use.
551 
552    Collective on PetscObject
553 
554    Input Parameters:
555 .  obj - the PetscObject
556 
557    Notes:
558    This does nothing at present.
559 
560    Level: advanced
561 
562 .keywords: setup
563 .seealso: PetscObjectDestroy()
564 @*/
565 PetscErrorCode PETSC_DLLEXPORT PetscObjectSetUp(PetscObject obj)
566 {
567   PetscFunctionBegin;
568   PetscValidHeader(obj,1);
569   PetscFunctionReturn(0);
570 }
571