Actual source code: inherit.c

  2: /*
  3:      Provides utility routines for manipulating any type of PETSc object.
  4: */
  5: #include <petscsys.h>  /*I   "petscsys.h"    I*/

  7: PetscObject *PetscObjects = 0;
  8: PetscInt    PetscObjectsCounts = 0, PetscObjectsMaxCounts = 0;


 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  PetscHeaderCreate_Private(PetscObject h,PetscClassId classid,PetscInt type,const char class_name[],const char descr[],const char mansec[],
 23:                                           MPI_Comm comm,PetscErrorCode (*des)(PetscObject*),PetscErrorCode (*vie)(PetscObject,PetscViewer))
 24: {
 25:   static PetscInt idcnt = 1;
 26:   PetscErrorCode  ierr;
 27:   PetscObject     *newPetscObjects;
 28:   PetscInt         newPetscObjectsMaxCounts,i;

 31:   h->classid                = classid;
 32:   h->type                   = type;
 33:   h->class_name             = (char*)class_name;
 34:   h->description            = (char*)descr;
 35:   h->mansec                 = (char*)mansec;
 36:   h->prefix                 = 0;
 37:   h->refct                  = 1;
 38:   h->amem                   = -1;
 39:   h->id                     = idcnt++;
 40:   h->parentid               = 0;
 41:   h->qlist                  = 0;
 42:   h->olist                  = 0;
 43:   h->precision              = (PetscPrecision) sizeof(PetscScalar);
 44:   h->bops->destroy          = des;
 45:   h->bops->view             = vie;
 46:   h->bops->getcomm          = PetscObjectGetComm_Petsc;
 47:   h->bops->compose          = PetscObjectCompose_Petsc;
 48:   h->bops->query            = PetscObjectQuery_Petsc;
 49:   h->bops->composefunction  = PetscObjectComposeFunction_Petsc;
 50:   h->bops->queryfunction    = PetscObjectQueryFunction_Petsc;
 51:   PetscCommDuplicate(comm,&h->comm,&h->tag);

 53:   /* Keep a record of object created */
 54:   PetscObjectsCounts++;
 55:   for (i=0; i<PetscObjectsMaxCounts; i++) {
 56:     if (!PetscObjects[i]) {
 57:       PetscObjects[i] = h;
 58:       return(0);
 59:     }
 60:   }
 61:   /* Need to increase the space for storing PETSc objects */
 62:   if (!PetscObjectsMaxCounts) newPetscObjectsMaxCounts = 100;
 63:   else                        newPetscObjectsMaxCounts = 2*PetscObjectsMaxCounts;
 64:   PetscMalloc(newPetscObjectsMaxCounts*sizeof(PetscObject),&newPetscObjects);
 65:   PetscMemcpy(newPetscObjects,PetscObjects,PetscObjectsMaxCounts*sizeof(PetscObject));
 66:   PetscMemzero(newPetscObjects+PetscObjectsMaxCounts,(newPetscObjectsMaxCounts - PetscObjectsMaxCounts)*sizeof(PetscObject));
 67:   PetscFree(PetscObjects);
 68:   PetscObjects                        = newPetscObjects;
 69:   PetscObjects[PetscObjectsMaxCounts] = h;
 70:   PetscObjectsMaxCounts               = newPetscObjectsMaxCounts;

 72:   return(0);
 73: }


 80: /*
 81:     PetscHeaderDestroy_Private - Destroys a base PETSc object header. Called by 
 82:     the macro PetscHeaderDestroy().
 83: */
 84: PetscErrorCode  PetscHeaderDestroy_Private(PetscObject h)
 85: {
 87:   PetscInt       i;

 90: #if defined(PETSC_HAVE_AMS)
 91:   if (PetscAMSPublishAll) {
 92:     PetscObjectUnPublish((PetscObject)h);
 93:   }
 94: #endif
 95:   if (PetscMemoryCollectMaximumUsage) {
 96:     PetscLogDouble usage;
 97:     PetscMemoryGetCurrentUsage(&usage);
 98:     if (usage > PetscMemoryMaximumUsage) PetscMemoryMaximumUsage = usage;
 99:   }
100:   /* first destroy things that could execute arbitrary code */
101:   if (h->python_destroy) {
102:     void           *python_context          = h->python_context;
103:     PetscErrorCode (*python_destroy)(void*) = h->python_destroy;
104:     h->python_context = 0;
105:     h->python_destroy = 0;
106:     (*python_destroy)(python_context);
107:   }
108:   PetscOListDestroy(&h->olist);
109:   PetscCommDestroy(&h->comm);
110:   /* next destroy other things */
111:   h->classid = PETSCFREEDHEADER;
112:   PetscFree(h->bops);
113:   PetscFListDestroy(&h->qlist);
114:   PetscFree(h->type_name);
115:   PetscFree(h->name);
116:   PetscFree(h->prefix);
117:   PetscFree(h->fortran_func_pointers);

119:   /* Record object removal from list of all objects */
120:   for (i=0; i<PetscObjectsMaxCounts; i++) {
121:     if (PetscObjects[i] == h) {
122:       PetscObjects[i] = 0;
123:       PetscObjectsCounts--;
124:       break;
125:     }
126:   }
127:   if (!PetscObjectsCounts) {
128:     PetscFree(PetscObjects);
129:     PetscObjectsMaxCounts = 0;
130:   }
131:   return(0);
132: }

136: /*@C
137:    PetscObjectCopyFortranFunctionPointers - Copy function pointers to another object

139:    Logically Collective on PetscObject

141:    Input Parameter:
142: +  src - source object
143: -  dest - destination object

145:    Level: developer

147:    Note:
148:    Both objects must have the same class.
149: @*/
150: PetscErrorCode PetscObjectCopyFortranFunctionPointers(PetscObject src,PetscObject dest)
151: {

157:   if (src->classid != dest->classid) SETERRQ(src->comm,PETSC_ERR_ARG_INCOMP,"Objects must be of the same class");

159:   PetscFree(dest->fortran_func_pointers);
160:   PetscMalloc(src->num_fortran_func_pointers*sizeof(void(*)(void)),&dest->fortran_func_pointers);
161:   PetscMemcpy(dest->fortran_func_pointers,src->fortran_func_pointers,src->num_fortran_func_pointers*sizeof(void(*)(void)));
162:   dest->num_fortran_func_pointers = src->num_fortran_func_pointers;
163:   return(0);
164: }

168: /*@C
169:    PetscObjectsView - Prints the currently existing objects.

171:    Logically Collective on PetscViewer

173:    Input Parameter:
174: .  viewer - must be an PETSCVIEWERASCII viewer

176:    Level: advanced

178:    Concepts: options database^printing

180: @*/
181: PetscErrorCode  PetscObjectsView(PetscViewer viewer)
182: {
184:   PetscInt       i;
185:   PetscBool      isascii;
186:   PetscObject    h;

189:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD;
190:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
191:   if (!isascii) SETERRQ(((PetscObject)viewer)->comm,PETSC_ERR_SUP,"Only supports ASCII viewer");

193:   for (i=0; i<PetscObjectsMaxCounts; i++) {
194:     if ((h = PetscObjects[i])) {
195:       PetscObjectName(h);
196:       PetscViewerASCIIPrintf(viewer,"%s %s %s\n",h->class_name,h->type_name,h->name);
197:     }
198:   }
199:   return(0);
200: }

204: /*@C
205:    PetscObjectsGetObject - Get a pointer to a named object

207:    Not collective

209:    Input Parameter:
210: .  name - the name of an object

212:    Output Parameter:
213: .   obj - the object or null if there is no object

215:    Level: advanced

217:    Concepts: options database^printing

219: @*/
220: PetscErrorCode  PetscObjectsGetObject(const char* name,PetscObject *obj,char **classname)
221: {
223:   PetscInt       i;
224:   PetscObject    h;
225:   PetscBool      flg;

228:   *obj = PETSC_NULL;
229:   for (i=0; i<PetscObjectsMaxCounts; i++) {
230:     if ((h = PetscObjects[i])) {
231:       PetscObjectName(h);
232:       PetscStrcmp(h->name,name,&flg);
233:       if (flg) {
234:         *obj = h;
235:         if (classname) *classname = h->class_name;
236:         return(0);
237:       }
238:     }
239:   }
240:   return(0);
241: }

245: char* PetscObjectsGetObjectMatlab(const char* name,PetscObject *obj)
246: {
248:   PetscInt       i;
249:   PetscObject    h;
250:   PetscBool      flg;

253:   *obj = PETSC_NULL;
254:   for (i=0; i<PetscObjectsMaxCounts; i++) {
255:     if ((h = PetscObjects[i])) {
256:       PetscObjectName(h);if (ierr) return(0);
257:       PetscStrcmp(h->name,name,&flg);if (ierr) return(0);
258:       if (flg) {
259:         *obj = h;
260:         PetscFunctionReturn(h->class_name);
261:       }
262:     }
263:   }
264:   return(0);
265: }

269: /*@C
270:     PetscObjectAddOptionsHandler - Adds an additional function to check for options when XXXSetFromOptions() is called.

272:     Not Collective

274:     Input Parameter:
275: +   obj - the PETSc object
276: .   handle - function that checks for options
277: .   destroy - function to destroy context if provided
278: -   ctx - optional context for check function

280:     Level: developer


283: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectProcessOptionsHandlers(), PetscObjectDestroyOptionsHandlers()

285: @*/
286: PetscErrorCode  PetscObjectAddOptionsHandler(PetscObject obj,PetscErrorCode (*handle)(PetscObject,void*),PetscErrorCode (*destroy)(PetscObject,void*),void *ctx)
287: {
289:   if (obj->noptionhandler >= PETSC_MAX_OPTIONS_HANDLER) SETERRQ(obj->comm,PETSC_ERR_ARG_OUTOFRANGE,"To many options handlers added");
290:   obj->optionhandler[obj->noptionhandler]   = handle;
291:   obj->optiondestroy[obj->noptionhandler]   = destroy;
292:   obj->optionctx[obj->noptionhandler++]     = ctx;
293:   return(0);
294: }

298: /*@C
299:     PetscObjectProcessOptionsHandlers - Calls all the options handler attached to an object

301:     Not Collective

303:     Input Parameter:
304: .   obj - the PETSc object

306:     Level: developer


309: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectDestroyOptionsHandlers()

311: @*/
312: PetscErrorCode  PetscObjectProcessOptionsHandlers(PetscObject obj)
313: {
314:   PetscInt       i;

318:   for (i=0; i<obj->noptionhandler; i++) {
319:     (*obj->optionhandler[i])(obj,obj->optionctx[i]);
320:   }
321:   return(0);
322: }

326: /*@C
327:     PetscObjectDestroyOptionsHandlers - Destroys all the option handlers attached to an objeft

329:     Not Collective

331:     Input Parameter:
332: .   obj - the PETSc object

334:     Level: developer


337: .seealso: KSPSetFromOptions(), PCSetFromOptions(), SNESSetFromOptions(), PetscObjectAddOptionsHandler(), PetscObjectProcessOptionsHandlers()

339: @*/
340: PetscErrorCode  PetscObjectDestroyOptionsHandlers(PetscObject obj)
341: {
342:   PetscInt       i;

346:   for (i=0; i<obj->noptionhandler; i++) {
347:     (*obj->optiondestroy[i])(obj,obj->optionctx[i]);
348:   }
349:   obj->noptionhandler = 0;
350:   return(0);
351: }


356: /*@
357:    PetscObjectReference - Indicates to any PetscObject that it is being
358:    referenced by another PetscObject. This increases the reference
359:    count for that object by one.

361:    Logically Collective on PetscObject

363:    Input Parameter:
364: .  obj - the PETSc object. This must be cast with (PetscObject), for example, 
365:          PetscObjectReference((PetscObject)mat);

367:    Level: advanced

369: .seealso: PetscObjectCompose(), PetscObjectDereference()
370: @*/
371: PetscErrorCode  PetscObjectReference(PetscObject obj)
372: {
375:   obj->refct++;
376:   return(0);
377: }

381: /*@
382:    PetscObjectGetReference - Gets the current reference count for 
383:    any PETSc object.

385:    Not Collective

387:    Input Parameter:
388: .  obj - the PETSc object; this must be cast with (PetscObject), for example, 
389:          PetscObjectGetReference((PetscObject)mat,&cnt);

391:    Output Parameter:
392: .  cnt - the reference count

394:    Level: advanced

396: .seealso: PetscObjectCompose(), PetscObjectDereference(), PetscObjectReference()
397: @*/
398: PetscErrorCode  PetscObjectGetReference(PetscObject obj,PetscInt *cnt)
399: {
403:   *cnt = obj->refct;
404:   return(0);
405: }

409: /*@
410:    PetscObjectDereference - Indicates to any PetscObject that it is being
411:    referenced by one less PetscObject. This decreases the reference
412:    count for that object by one.

414:    Collective on PetscObject if reference reaches 0 otherwise Logically Collective

416:    Input Parameter:
417: .  obj - the PETSc object; this must be cast with (PetscObject), for example, 
418:          PetscObjectDereference((PetscObject)mat);

420:    Notes: PetscObjectDestroy(PetscObject *obj)  sets the obj pointer to null after the call, this routine does not.

422:    Level: advanced

424: .seealso: PetscObjectCompose(), PetscObjectReference()
425: @*/
426: PetscErrorCode  PetscObjectDereference(PetscObject obj)
427: {

432:   if (obj->bops->destroy) {
433:     (*obj->bops->destroy)(&obj);
434:   } else if (!--obj->refct) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"This PETSc object does not have a generic destroy routine");
435:   return(0);
436: }

438: /* ----------------------------------------------------------------------- */
439: /*
440:      The following routines are the versions private to the PETSc object
441:      data structures.
442: */
445: PetscErrorCode PetscObjectGetComm_Petsc(PetscObject obj,MPI_Comm *comm)
446: {
448:   *comm = obj->comm;
449:   return(0);
450: }

454: PetscErrorCode PetscObjectRemoveReference(PetscObject obj,const char name[])
455: {

459:   PetscOListRemoveReference(&obj->olist,name);
460:   return(0);
461: }

465: PetscErrorCode PetscObjectCompose_Petsc(PetscObject obj,const char name[],PetscObject ptr)
466: {
468:   char           *tname;
469:   PetscBool      skipreference;

472:   if (ptr) {
473:     PetscOListReverseFind(ptr->olist,obj,&tname,&skipreference);
474:     if (tname && !skipreference) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"An object cannot be composed with an object that was compose with it");
475:   }
476:   PetscOListAdd(&obj->olist,name,ptr);
477:   return(0);
478: }

482: PetscErrorCode PetscObjectQuery_Petsc(PetscObject obj,const char name[],PetscObject *ptr)
483: {

487:   PetscOListFind(obj->olist,name,ptr);
488:   return(0);
489: }

493: PetscErrorCode PetscObjectComposeFunction_Petsc(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
494: {

498:   PetscFListAdd(&obj->qlist,name,fname,ptr);
499:   return(0);
500: }

504: PetscErrorCode PetscObjectQueryFunction_Petsc(PetscObject obj,const char name[],void (**ptr)(void))
505: {

509:   PetscFListFind(obj->qlist,obj->comm,name,PETSC_FALSE,ptr);
510:   return(0);
511: }

515: /*@C
516:    PetscObjectCompose - Associates another PETSc object with a given PETSc object. 
517:                        
518:    Not Collective

520:    Input Parameters:
521: +  obj - the PETSc object; this must be cast with (PetscObject), for example, 
522:          PetscObjectCompose((PetscObject)mat,...);
523: .  name - name associated with the child object 
524: -  ptr - the other PETSc object to associate with the PETSc object; this must also be 
525:          cast with (PetscObject)

527:    Level: advanced

529:    Notes:
530:    The second objects reference count is automatically increased by one when it is
531:    composed.

533:    Replaces any previous object that had the same name.

535:    If ptr is null and name has previously been composed using an object, then that
536:    entry is removed from the obj.

538:    PetscObjectCompose() can be used with any PETSc object (such as
539:    Mat, Vec, KSP, SNES, etc.) or any user-provided object.  See 
540:    PetscContainerCreate() for info on how to create an object from a 
541:    user-provided pointer that may then be composed with PETSc objects.
542:    
543:    Concepts: objects^composing
544:    Concepts: composing objects

546: .seealso: PetscObjectQuery(), PetscContainerCreate()
547: @*/
548: PetscErrorCode  PetscObjectCompose(PetscObject obj,const char name[],PetscObject ptr)
549: {

556:   (*obj->bops->compose)(obj,name,ptr);
557:   return(0);
558: }

562: /*@C
563:    PetscObjectSetPrecision - sets the precision used within a given object.
564:                        
565:    Collective on the PetscObject

567:    Input Parameters:
568: +  obj - the PETSc object; this must be cast with (PetscObject), for example, 
569:          PetscObjectCompose((PetscObject)mat,...);
570: -  precision - the precision

572:    Level: advanced

574: .seealso: PetscObjectQuery(), PetscContainerCreate()
575: @*/
576: PetscErrorCode  PetscObjectSetPrecision(PetscObject obj,PetscPrecision precision)
577: {
580:   obj->precision = precision;
581:   return(0);
582: }

586: /*@C
587:    PetscObjectQuery  - Gets a PETSc object associated with a given object.
588:                        
589:    Not Collective

591:    Input Parameters:
592: +  obj - the PETSc object
593:          Thus must be cast with a (PetscObject), for example, 
594:          PetscObjectCompose((PetscObject)mat,...);
595: .  name - name associated with child object 
596: -  ptr - the other PETSc object associated with the PETSc object, this must be 
597:          cast with (PetscObject *)

599:    Level: advanced

601:    The reference count of neither object is increased in this call

603:    Concepts: objects^composing
604:    Concepts: composing objects
605:    Concepts: objects^querying
606:    Concepts: querying objects

608: .seealso: PetscObjectCompose()
609: @*/
610: PetscErrorCode  PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr)
611: {

618:   (*obj->bops->query)(obj,name,ptr);
619:   return(0);
620: }

624: PetscErrorCode  PetscObjectComposeFunction(PetscObject obj,const char name[],const char fname[],void (*ptr)(void))
625: {

632:   (*obj->bops->composefunction)(obj,name,fname,ptr);
633:   return(0);
634: }

638: /*@C
639:    PetscObjectQueryFunction - Gets a function associated with a given object.
640:                        
641:    Logically Collective on PetscObject

643:    Input Parameters:
644: +  obj - the PETSc object; this must be cast with (PetscObject), for example, 
645:          PetscObjectQueryFunction((PetscObject)ksp,...);
646: -  name - name associated with the child function

648:    Output Parameter:
649: .  ptr - function pointer

651:    Level: advanced

653:    Concepts: objects^composing functions
654:    Concepts: composing functions
655:    Concepts: functions^querying
656:    Concepts: objects^querying
657:    Concepts: querying objects

659: .seealso: PetscObjectComposeFunctionDynamic()
660: @*/
661: PetscErrorCode  PetscObjectQueryFunction(PetscObject obj,const char name[],void (**ptr)(void))
662: {

668:   (*obj->bops->queryfunction)(obj,name,ptr);
669:   return(0);
670: }

672: struct _p_PetscContainer {
673:   PETSCHEADER(int);
674:   void   *ptr;
675:   PetscErrorCode (*userdestroy)(void*);
676: };

680: /*@C
681:    PetscContainerGetPointer - Gets the pointer value contained in the container.

683:    Not Collective

685:    Input Parameter:
686: .  obj - the object created with PetscContainerCreate()

688:    Output Parameter:
689: .  ptr - the pointer value

691:    Level: advanced

693: .seealso: PetscContainerCreate(), PetscContainerDestroy(), 
694:           PetscContainerSetPointer()
695: @*/
696: PetscErrorCode  PetscContainerGetPointer(PetscContainer obj,void **ptr)
697: {
701:   *ptr = obj->ptr;
702:   return(0);
703: }


708: /*@C
709:    PetscContainerSetPointer - Sets the pointer value contained in the container.

711:    Logically Collective on PetscContainer

713:    Input Parameters:
714: +  obj - the object created with PetscContainerCreate()
715: -  ptr - the pointer value

717:    Level: advanced

719: .seealso: PetscContainerCreate(), PetscContainerDestroy(), 
720:           PetscContainerGetPointer()
721: @*/
722: PetscErrorCode  PetscContainerSetPointer(PetscContainer obj,void *ptr)
723: {
727:   obj->ptr = ptr;
728:   return(0);
729: }

733: /*@C
734:    PetscContainerDestroy - Destroys a PETSc container object.

736:    Collective on PetscContainer

738:    Input Parameter:
739: .  obj - an object that was created with PetscContainerCreate()

741:    Level: advanced

743: .seealso: PetscContainerCreate(), PetscContainerSetUserDestroy()
744: @*/
745: PetscErrorCode  PetscContainerDestroy(PetscContainer *obj)
746: {
749:   if (!*obj) return(0);
751:   if (--((PetscObject)(*obj))->refct > 0) return(0);
752:   if ((*obj)->userdestroy) (*(*obj)->userdestroy)((*obj)->ptr);
753:   PetscHeaderDestroy(obj);
754:   return(0);
755: }

759: /*@C
760:    PetscContainerSetUserDestroy - Sets name of the user destroy function.

762:    Logically Collective on PetscContainer

764:    Input Parameter:
765: +  obj - an object that was created with PetscContainerCreate()
766: -  des - name of the user destroy function

768:    Level: advanced

770: .seealso: PetscContainerDestroy()
771: @*/
772: PetscErrorCode  PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*))
773: {
776:   obj->userdestroy = des;
777:   return(0);
778: }

780: PetscClassId  PETSC_CONTAINER_CLASSID;

784: /*@C
785:    PetscContainerCreate - Creates a PETSc object that has room to hold
786:    a single pointer. This allows one to attach any type of data (accessible
787:    through a pointer) with the PetscObjectCompose() function to a PetscObject.
788:    The data item itself is attached by a call to PetscContainerSetPointer().

790:    Collective on MPI_Comm

792:    Input Parameters:
793: .  comm - MPI communicator that shares the object

795:    Output Parameters:
796: .  container - the container created

798:    Level: advanced

800: .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer()
801: @*/
802: PetscErrorCode  PetscContainerCreate(MPI_Comm comm,PetscContainer *container)
803: {
805:   PetscContainer contain;

809:   PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_CLASSID,0,"PetscContainer","Container","Sys",comm,PetscContainerDestroy,0);
810:   *container = contain;
811:   return(0);
812: }

816: /*@
817:    PetscObjectSetFromOptions - Sets generic parameters from user options.

819:    Collective on obj

821:    Input Parameter:
822: .  obj - the PetscObjcet

824:    Options Database Keys:

826:    Notes:
827:    We have no generic options at present, so this does nothing

829:    Level: beginner

831: .keywords: set, options, database
832: .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix()
833: @*/
834: PetscErrorCode  PetscObjectSetFromOptions(PetscObject obj)
835: {
838:   return(0);
839: }

843: /*@
844:    PetscObjectSetUp - Sets up the internal data structures for the later use.

846:    Collective on PetscObject

848:    Input Parameters:
849: .  obj - the PetscObject

851:    Notes:
852:    This does nothing at present.

854:    Level: advanced

856: .keywords: setup
857: .seealso: PetscObjectDestroy()
858: @*/
859: PetscErrorCode  PetscObjectSetUp(PetscObject obj)
860: {
863:   return(0);
864: }