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