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