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,PetscCookie cookie,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->cookie = cookie; 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->cookie = 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 #undef __FUNCT__ 293 #define __FUNCT__ "PetscObjectQuery" 294 /*@C 295 PetscObjectQuery - Gets a PETSc object associated with a given object. 296 297 Not Collective 298 299 Input Parameters: 300 + obj - the PETSc object 301 Thus must be cast with a (PetscObject), for example, 302 PetscObjectCompose((PetscObject)mat,...); 303 . name - name associated with child object 304 - ptr - the other PETSc object associated with the PETSc object, this must also be 305 cast with (PetscObject) 306 307 Level: advanced 308 309 Concepts: objects^composing 310 Concepts: composing objects 311 Concepts: objects^querying 312 Concepts: querying objects 313 314 .seealso: PetscObjectQuery() 315 @*/ 316 PetscErrorCode PETSC_DLLEXPORT PetscObjectQuery(PetscObject obj,const char name[],PetscObject *ptr) 317 { 318 PetscErrorCode ierr; 319 320 PetscFunctionBegin; 321 PetscValidHeader(obj,1); 322 PetscValidCharPointer(name,2); 323 PetscValidPointer(ptr,3); 324 ierr = (*obj->bops->query)(obj,name,ptr);CHKERRQ(ierr); 325 PetscFunctionReturn(0); 326 } 327 328 #undef __FUNCT__ 329 #define __FUNCT__ "PetscObjectComposeFunction" 330 PetscErrorCode PETSC_DLLEXPORT PetscObjectComposeFunction(PetscObject obj,const char name[],const char fname[],void (*ptr)(void)) 331 { 332 PetscErrorCode ierr; 333 334 PetscFunctionBegin; 335 PetscValidHeader(obj,1); 336 PetscValidCharPointer(name,2); 337 PetscValidCharPointer(fname,2); 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 PetscValidHeader(obj,1); 373 PetscValidCharPointer(name,2); 374 ierr = (*obj->bops->queryfunction)(obj,name,ptr);CHKERRQ(ierr); 375 PetscFunctionReturn(0); 376 } 377 378 struct _p_PetscContainer { 379 PETSCHEADER(int); 380 void *ptr; 381 PetscErrorCode (*userdestroy)(void*); 382 }; 383 384 #undef __FUNCT__ 385 #define __FUNCT__ "PetscContainerGetPointer" 386 /*@C 387 PetscContainerGetPointer - Gets the pointer value contained in the container. 388 389 Collective on PetscContainer 390 391 Input Parameter: 392 . obj - the object created with PetscContainerCreate() 393 394 Output Parameter: 395 . ptr - the pointer value 396 397 Level: advanced 398 399 .seealso: PetscContainerCreate(), PetscContainerDestroy(), 400 PetscContainerSetPointer() 401 @*/ 402 PetscErrorCode PETSC_DLLEXPORT PetscContainerGetPointer(PetscContainer obj,void **ptr) 403 { 404 PetscFunctionBegin; 405 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_COOKIE,1); 406 PetscValidPointer(ptr,2); 407 *ptr = obj->ptr; 408 PetscFunctionReturn(0); 409 } 410 411 412 #undef __FUNCT__ 413 #define __FUNCT__ "PetscContainerSetPointer" 414 /*@C 415 PetscContainerSetPointer - Sets the pointer value contained in the container. 416 417 Collective on PetscContainer 418 419 Input Parameters: 420 + obj - the object created with PetscContainerCreate() 421 - ptr - the pointer value 422 423 Level: advanced 424 425 .seealso: PetscContainerCreate(), PetscContainerDestroy(), 426 PetscContainerGetPointer() 427 @*/ 428 PetscErrorCode PETSC_DLLEXPORT PetscContainerSetPointer(PetscContainer obj,void *ptr) 429 { 430 PetscFunctionBegin; 431 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_COOKIE,1); 432 if (ptr) PetscValidPointer(ptr,2); 433 obj->ptr = ptr; 434 PetscFunctionReturn(0); 435 } 436 437 #undef __FUNCT__ 438 #define __FUNCT__ "PetscContainerDestroy" 439 /*@C 440 PetscContainerDestroy - Destroys a PETSc container object. 441 442 Collective on PetscContainer 443 444 Input Parameter: 445 . obj - an object that was created with PetscContainerCreate() 446 447 Level: advanced 448 449 .seealso: PetscContainerCreate() 450 @*/ 451 PetscErrorCode PETSC_DLLEXPORT PetscContainerDestroy(PetscContainer obj) 452 { 453 PetscErrorCode ierr; 454 PetscFunctionBegin; 455 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_COOKIE,1); 456 if (--((PetscObject)obj)->refct > 0) PetscFunctionReturn(0); 457 if (obj->userdestroy) (*obj->userdestroy)(obj->ptr); 458 ierr = PetscHeaderDestroy(obj);CHKERRQ(ierr); 459 PetscFunctionReturn(0); 460 } 461 462 #undef __FUNCT__ 463 #define __FUNCT__ "PetscContainerSetUserDestroy" 464 /*@C 465 PetscContainerSetUserDestroy - Sets name of the user destroy function. 466 467 Collective on PetscContainer 468 469 Input Parameter: 470 + obj - an object that was created with PetscContainerCreate() 471 - des - name of the user destroy function 472 473 Level: advanced 474 475 .seealso: PetscContainerDestroy() 476 @*/ 477 PetscErrorCode PETSC_DLLEXPORT PetscContainerSetUserDestroy(PetscContainer obj, PetscErrorCode (*des)(void*)) 478 { 479 PetscFunctionBegin; 480 PetscValidHeaderSpecific(obj,PETSC_CONTAINER_COOKIE,1); 481 obj->userdestroy = des; 482 PetscFunctionReturn(0); 483 } 484 485 PetscCookie PETSC_DLLEXPORT PETSC_CONTAINER_COOKIE; 486 487 #undef __FUNCT__ 488 #define __FUNCT__ "PetscContainerCreate" 489 /*@C 490 PetscContainerCreate - Creates a PETSc object that has room to hold 491 a single pointer. This allows one to attach any type of data (accessible 492 through a pointer) with the PetscObjectCompose() function to a PetscObject. 493 The data item itself is attached by a call to PetscContainerSetPointer. 494 495 Collective on MPI_Comm 496 497 Input Parameters: 498 . comm - MPI communicator that shares the object 499 500 Output Parameters: 501 . container - the container created 502 503 Level: advanced 504 505 .seealso: PetscContainerDestroy(), PetscContainerSetPointer(), PetscContainerGetPointer() 506 @*/ 507 PetscErrorCode PETSC_DLLEXPORT PetscContainerCreate(MPI_Comm comm,PetscContainer *container) 508 { 509 PetscErrorCode ierr; 510 PetscContainer contain; 511 512 PetscFunctionBegin; 513 PetscValidPointer(container,2); 514 ierr = PetscHeaderCreate(contain,_p_PetscContainer,PetscInt,PETSC_CONTAINER_COOKIE,0,"PetscContainer",comm,PetscContainerDestroy,0);CHKERRQ(ierr); 515 *container = contain; 516 PetscFunctionReturn(0); 517 } 518 519 #undef __FUNCT__ 520 #define __FUNCT__ "PetscObjectSetFromOptions" 521 /*@ 522 PetscObjectSetFromOptions - Sets generic parameters from user options. 523 524 Collective on obj 525 526 Input Parameter: 527 . obj - the PetscObjcet 528 529 Options Database Keys: 530 531 Notes: 532 We have no generic options at present, so this does nothing 533 534 Level: beginner 535 536 .keywords: set, options, database 537 .seealso: PetscObjectSetOptionsPrefix(), PetscObjectGetOptionsPrefix() 538 @*/ 539 PetscErrorCode PETSC_DLLEXPORT PetscObjectSetFromOptions(PetscObject obj) 540 { 541 PetscFunctionBegin; 542 PetscValidHeader(obj,1); 543 PetscFunctionReturn(0); 544 } 545 546 #undef __FUNCT__ 547 #define __FUNCT__ "PetscObjectSetUp" 548 /*@ 549 PetscObjectSetUp - Sets up the internal data structures for the later use. 550 551 Collective on PetscObject 552 553 Input Parameters: 554 . obj - the PetscObject 555 556 Notes: 557 This does nothing at present. 558 559 Level: advanced 560 561 .keywords: setup 562 .seealso: PetscObjectDestroy() 563 @*/ 564 PetscErrorCode PETSC_DLLEXPORT PetscObjectSetUp(PetscObject obj) 565 { 566 PetscFunctionBegin; 567 PetscValidHeader(obj,1); 568 PetscFunctionReturn(0); 569 } 570