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