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