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