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