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