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