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