xref: /petsc/src/sys/objects/inherit.c (revision 1f428162ad0d3f3f8d1cec0ccb02b2fdaac4d2ec)
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    PetscObjectContainerCreate() 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(), PetscObjectContainerCreate()
272 @*/
273 PetscErrorCode PETSC_DLLEXPORT PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
274 {
275   PetscErrorCode ierr;
276 
277   PetscFunctionBegin;
278   ierr = (*obj->bops->compose)(obj,name,ptr);CHKERRQ(ierr);
279   PetscFunctionReturn(0);
280 }
281 
282 #undef __FUNCT__
283 #define __FUNCT__ "PetscObjectQuery"
284 /*@C
285    PetscObjectQuery  - Gets a PETSc object associated with a given object.
286 
287    Not Collective
288 
289    Input Parameters:
290 +  obj - the PETSc object
291          Thus must be cast with a (PetscObject), for example,
292          PetscObjectCompose((PetscObject)mat,...);
293 .  name - name associated with child object
294 -  ptr - the other PETSc object associated with the PETSc object, this must also be
295          cast with (PetscObject)
296 
297    Level: advanced
298 
299    Concepts: objects^composing
300    Concepts: composing objects
301    Concepts: objects^querying
302    Concepts: querying objects
303 
304 .seealso: PetscObjectQuery()
305 @*/
306 PetscErrorCode PETSC_DLLEXPORT PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
307 {
308   PetscErrorCode ierr;
309 
310   PetscFunctionBegin;
311   ierr = (*obj->bops->query)(obj,name,ptr);CHKERRQ(ierr);
312   PetscFunctionReturn(0);
313 }
314 
315 #undef __FUNCT__
316 #define __FUNCT__ "PetscObjectComposeFunction"
317 PetscErrorCode PETSC_DLLEXPORT PetscObjectComposeFunction(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
318 {
319   PetscErrorCode ierr;
320 
321   PetscFunctionBegin;
322   ierr = (*obj->bops->composefunction)(obj,name,fname,ptr);CHKERRQ(ierr);
323   PetscFunctionReturn(0);
324 }
325 
326 #undef __FUNCT__
327 #define __FUNCT__ "PetscObjectQueryFunction"
328 /*@C
329    PetscObjectQueryFunction - Gets a function associated with a given object.
330 
331    Collective on PetscObject
332 
333    Input Parameters:
334 +  obj - the PETSc object; this must be cast with (PetscObject), for example,
335          PetscObjectQueryFunction((PetscObject)ksp,...);
336 -  name - name associated with the child function
337 
338    Output Parameter:
339 .  ptr - function pointer
340 
341    Level: advanced
342 
343    Concepts: objects^composing functions
344    Concepts: composing functions
345    Concepts: functions^querying
346    Concepts: objects^querying
347    Concepts: querying objects
348 
349 .seealso: PetscObjectComposeFunctionDynamic()
350 @*/
351 PetscErrorCode PETSC_DLLEXPORT PetscObjectQueryFunction(PetscObject obj,const char name[],void (**ptr)(void))
352 {
353   PetscErrorCode ierr;
354 
355   PetscFunctionBegin;
356   ierr = (*obj->bops->queryfunction)(obj,name,ptr);CHKERRQ(ierr);
357   PetscFunctionReturn(0);
358 }
359 
360 struct _p_PetscObjectContainer {
361   PETSCHEADER(int);
362   void   *ptr;
363   PetscErrorCode (*userdestroy)(void*);
364 };
365 
366 #undef __FUNCT__
367 #define __FUNCT__ "PetscObjectContainerGetPointer"
368 /*@C
369    PetscObjectContainerGetPointer - Gets the pointer value contained in the container.
370 
371    Collective on PetscObjectContainer
372 
373    Input Parameter:
374 .  obj - the object created with PetscObjectContainerCreate()
375 
376    Output Parameter:
377 .  ptr - the pointer value
378 
379    Level: advanced
380 
381 .seealso: PetscObjectContainerCreate(), PetscObjectContainerDestroy(),
382           PetscObjectContainerSetPointer()
383 @*/
384 PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerGetPointer(PetscObjectContainer obj,void **ptr)
385 {
386   PetscFunctionBegin;
387   *ptr = obj->ptr;
388   PetscFunctionReturn(0);
389 }
390 
391 
392 #undef __FUNCT__
393 #define __FUNCT__ "PetscObjectContainerSetPointer"
394 /*@C
395    PetscObjectContainerSetPointer - Sets the pointer value contained in the container.
396 
397    Collective on PetscObjectContainer
398 
399    Input Parameters:
400 +  obj - the object created with PetscObjectContainerCreate()
401 -  ptr - the pointer value
402 
403    Level: advanced
404 
405 .seealso: PetscObjectContainerCreate(), PetscObjectContainerDestroy(),
406           PetscObjectContainerGetPointer()
407 @*/
408 PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerSetPointer(PetscObjectContainer obj,void *ptr)
409 {
410   PetscFunctionBegin;
411   obj->ptr = ptr;
412   PetscFunctionReturn(0);
413 }
414 
415 #undef __FUNCT__
416 #define __FUNCT__ "PetscObjectContainerDestroy"
417 /*@C
418    PetscObjectContainerDestroy - Destroys a PETSc container object.
419 
420    Collective on PetscObjectContainer
421 
422    Input Parameter:
423 .  obj - an object that was created with PetscObjectContainerCreate()
424 
425    Level: advanced
426 
427 .seealso: PetscObjectContainerCreate()
428 @*/
429 PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerDestroy(PetscObjectContainer obj)
430 {
431   PetscErrorCode ierr;
432   PetscFunctionBegin;
433   if (--obj->refct > 0) PetscFunctionReturn(0);
434   if (obj->userdestroy) (*obj->userdestroy)(obj->ptr);
435   ierr = PetscHeaderDestroy(obj);CHKERRQ(ierr);
436   PetscFunctionReturn(0);
437 }
438 
439 #undef __FUNCT__
440 #define __FUNCT__ "PetscObjectContainerSetUserDestroy"
441 /*@C
442    PetscObjectContainerSetUserDestroy - Sets name of the user destroy function.
443 
444    Collective on PetscObjectContainer
445 
446    Input Parameter:
447 +  obj - an object that was created with PetscObjectContainerCreate()
448 -  des - name of the user destroy function
449 
450    Level: advanced
451 
452 .seealso: PetscObjectContainerDestroy()
453 @*/
454 PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerSetUserDestroy(PetscObjectContainer obj, PetscErrorCode (*des)(void*))
455 {
456   PetscFunctionBegin;
457   obj->userdestroy = des;
458   PetscFunctionReturn(0);
459 }
460 
461 PetscCookie PETSC_DLLEXPORT CONTAINER_COOKIE = 0;
462 
463 #undef __FUNCT__
464 #define __FUNCT__ "PetscObjectContainerCreate"
465 /*@C
466    PetscObjectContainerCreate - Creates a PETSc object that has room to hold
467    a single pointer. This allows one to attach any type of data (accessible
468    through a pointer) with the PetscObjectCompose() function to a PetscObject.
469    The data item itself is attached by a call to PetscObjectContainerSetPointer.
470 
471    Collective on MPI_Comm
472 
473    Input Parameters:
474 .  comm - MPI communicator that shares the object
475 
476    Output Parameters:
477 .  container - the container created
478 
479    Level: advanced
480 
481 .seealso: PetscObjectContainerDestroy(), PetscObjectContainerSetPointer(), PetscObjectContainerGetPointer()
482 @*/
483 PetscErrorCode PETSC_DLLEXPORT PetscObjectContainerCreate(MPI_Comm comm,PetscObjectContainer *container)
484 {
485   PetscErrorCode       ierr;
486   PetscObjectContainer contain;
487 
488   PetscFunctionBegin;
489   if (!CONTAINER_COOKIE) {
490     ierr = PetscLogClassRegister(&CONTAINER_COOKIE,          "Container");CHKERRQ(ierr);
491   }
492   ierr = PetscHeaderCreate(contain,_p_PetscObjectContainer,PetscInt,CONTAINER_COOKIE,0,"container",comm,PetscObjectContainerDestroy,0);CHKERRQ(ierr);
493   *container = contain;
494   PetscFunctionReturn(0);
495 }
496 
497 #undef __FUNCT__
498 #define __FUNCT__ "PetscObjectSetFromOptions"
499 /*@
500    PetscObjectSetFromOptions - Sets generic parameters from user options.
501 
502    Collective on obj
503 
504    Input Parameter:
505 .  obj - the PetscObjcet
506 
507    Options Database Keys:
508 
509    Notes:
510    We have no generic options at present, so this does nothing
511 
512    Level: beginner
513 
514 .keywords: set, options, database
515 .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
516 @*/
517 PetscErrorCode PETSC_DLLEXPORT PetscObjectSetFromOptions(PetscObject obj)
518 {
519   PetscFunctionBegin;
520   if (!obj) SETERRQ(PETSC_ERR_ARG_CORRUPT, "Null object");
521   PetscFunctionReturn(0);
522 }
523 
524 #undef __FUNCT__
525 #define __FUNCT__ "PetscObjectSetUp"
526 /*@
527    PetscObjectSetUp - Sets up the internal data structures for the later use.
528 
529    Collective on PetscObject
530 
531    Input Parameters:
532 .  obj - the PetscObject
533 
534    Notes:
535    This does nothing at present.
536 
537    Level: advanced
538 
539 .keywords: setup
540 .seealso: PetscObjectDestroy()
541 @*/
542 PetscErrorCode PETSC_DLLEXPORT PetscObjectSetUp(PetscObject obj)
543 {
544   PetscFunctionBegin;
545   if (!obj) SETERRQ(PETSC_ERR_ARG_CORRUPT, "Null object");
546   PetscFunctionReturn(0);
547 }
548