1 #define PETSCVEC_DLL 2 /* 3 The PF mathematical functions interface routines, callable by users. 4 */ 5 #include "../src/vec/pf/pfimpl.h" /*I "petscpf.h" I*/ 6 7 /* Logging support */ 8 PetscCookie PF_COOKIE = 0; 9 10 PetscFList PFList = PETSC_NULL; /* list of all registered PD functions */ 11 PetscTruth PFRegisterAllCalled = PETSC_FALSE; 12 13 #undef __FUNCT__ 14 #define __FUNCT__ "PFSet" 15 /*@C 16 PFSet - Sets the C/C++/Fortran functions to be used by the PF function 17 18 Collective on PF 19 20 Input Parameter: 21 + pf - the function context 22 . apply - function to apply to an array 23 . applyvec - function to apply to a Vec 24 . view - function that prints information about the PF 25 . destroy - function to free the private function context 26 - ctx - private function context 27 28 Level: beginner 29 30 .keywords: PF, setting 31 32 .seealso: PFCreate(), PFDestroy(), PFSetType(), PFApply(), PFApplyVec() 33 @*/ 34 PetscErrorCode PETSCVEC_DLLEXPORT PFSet(PF pf,PetscErrorCode (*apply)(void*,PetscInt,PetscScalar*,PetscScalar*),PetscErrorCode (*applyvec)(void*,Vec,Vec),PetscErrorCode (*view)(void*,PetscViewer),PetscErrorCode (*destroy)(void*),void*ctx) 35 { 36 PetscFunctionBegin; 37 PetscValidHeaderSpecific(pf,PF_COOKIE,1); 38 pf->data = ctx; 39 40 pf->ops->destroy = destroy; 41 pf->ops->apply = apply; 42 pf->ops->applyvec = applyvec; 43 pf->ops->view = view; 44 45 PetscFunctionReturn(0); 46 } 47 48 #undef __FUNCT__ 49 #define __FUNCT__ "PFDestroy" 50 /*@C 51 PFDestroy - Destroys PF context that was created with PFCreate(). 52 53 Collective on PF 54 55 Input Parameter: 56 . pf - the function context 57 58 Level: beginner 59 60 .keywords: PF, destroy 61 62 .seealso: PFCreate(), PFSet(), PFSetType() 63 @*/ 64 PetscErrorCode PETSCVEC_DLLEXPORT PFDestroy(PF pf) 65 { 66 PetscErrorCode ierr; 67 PetscTruth flg = PETSC_FALSE; 68 69 PetscFunctionBegin; 70 PetscValidHeaderSpecific(pf,PF_COOKIE,1); 71 if (--((PetscObject)pf)->refct > 0) PetscFunctionReturn(0); 72 73 ierr = PetscOptionsGetTruth(((PetscObject)pf)->prefix,"-pf_view",&flg,PETSC_NULL);CHKERRQ(ierr); 74 if (flg) { 75 PetscViewer viewer; 76 ierr = PetscViewerASCIIGetStdout(((PetscObject)pf)->comm,&viewer);CHKERRQ(ierr); 77 ierr = PFView(pf,viewer);CHKERRQ(ierr); 78 } 79 80 /* if memory was published with AMS then destroy it */ 81 ierr = PetscObjectDepublish(pf);CHKERRQ(ierr); 82 83 if (pf->ops->destroy) {ierr = (*pf->ops->destroy)(pf->data);CHKERRQ(ierr);} 84 ierr = PetscHeaderDestroy(pf);CHKERRQ(ierr); 85 PetscFunctionReturn(0); 86 } 87 88 #undef __FUNCT__ 89 #define __FUNCT__ "PFCreate" 90 /*@C 91 PFCreate - Creates a mathematical function context. 92 93 Collective on MPI_Comm 94 95 Input Parameter: 96 + comm - MPI communicator 97 . dimin - dimension of the space you are mapping from 98 - dimout - dimension of the space you are mapping to 99 100 Output Parameter: 101 . pf - the function context 102 103 Level: developer 104 105 .keywords: PF, create, context 106 107 .seealso: PFSetUp(), PFApply(), PFDestroy(), PFApplyVec() 108 @*/ 109 PetscErrorCode PETSCVEC_DLLEXPORT PFCreate(MPI_Comm comm,PetscInt dimin,PetscInt dimout,PF *pf) 110 { 111 PF newpf; 112 PetscErrorCode ierr; 113 114 PetscFunctionBegin; 115 PetscValidPointer(pf,1); 116 *pf = PETSC_NULL; 117 #ifndef PETSC_USE_DYNAMIC_LIBRARIES 118 ierr = PFInitializePackage(PETSC_NULL);CHKERRQ(ierr); 119 #endif 120 121 ierr = PetscHeaderCreate(newpf,_p_PF,struct _PFOps,PF_COOKIE,-1,"PF",comm,PFDestroy,PFView);CHKERRQ(ierr); 122 newpf->data = 0; 123 124 newpf->ops->destroy = 0; 125 newpf->ops->apply = 0; 126 newpf->ops->applyvec = 0; 127 newpf->ops->view = 0; 128 newpf->dimin = dimin; 129 newpf->dimout = dimout; 130 131 *pf = newpf; 132 ierr = PetscPublishAll(pf);CHKERRQ(ierr); 133 PetscFunctionReturn(0); 134 135 } 136 137 /* -------------------------------------------------------------------------------*/ 138 139 #undef __FUNCT__ 140 #define __FUNCT__ "PFApplyVec" 141 /*@ 142 PFApplyVec - Applies the mathematical function to a vector 143 144 Collective on PF 145 146 Input Parameters: 147 + pf - the function context 148 - x - input vector (or PETSC_NULL for the vector (0,1, .... N-1) 149 150 Output Parameter: 151 . y - output vector 152 153 Level: beginner 154 155 .keywords: PF, apply 156 157 .seealso: PFApply(), PFCreate(), PFDestroy(), PFSetType(), PFSet() 158 @*/ 159 PetscErrorCode PETSCVEC_DLLEXPORT PFApplyVec(PF pf,Vec x,Vec y) 160 { 161 PetscErrorCode ierr; 162 PetscInt i,rstart,rend,n,p; 163 PetscTruth nox = PETSC_FALSE; 164 165 PetscFunctionBegin; 166 PetscValidHeaderSpecific(pf,PF_COOKIE,1); 167 PetscValidHeaderSpecific(y,VEC_COOKIE,3); 168 if (x) { 169 PetscValidHeaderSpecific(x,VEC_COOKIE,2); 170 if (x == y) SETERRQ(PETSC_ERR_ARG_IDN,"x and y must be different vectors"); 171 } else { 172 PetscScalar *xx; 173 174 ierr = VecDuplicate(y,&x);CHKERRQ(ierr); 175 nox = PETSC_TRUE; 176 ierr = VecGetOwnershipRange(x,&rstart,&rend);CHKERRQ(ierr); 177 ierr = VecGetArray(x,&xx);CHKERRQ(ierr); 178 for (i=rstart; i<rend; i++) { 179 xx[i-rstart] = (PetscScalar)i; 180 } 181 ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr); 182 } 183 184 ierr = VecGetLocalSize(x,&n);CHKERRQ(ierr); 185 ierr = VecGetLocalSize(y,&p);CHKERRQ(ierr); 186 if ((pf->dimin*(n/pf->dimin)) != n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Local input vector length %D not divisible by dimin %D of function",n,pf->dimin); 187 if ((pf->dimout*(p/pf->dimout)) != p) SETERRQ2(PETSC_ERR_ARG_SIZ,"Local output vector length %D not divisible by dimout %D of function",p,pf->dimout); 188 if ((n/pf->dimin) != (p/pf->dimout)) SETERRQ4(PETSC_ERR_ARG_SIZ,"Local vector lengths %D %D are wrong for dimin and dimout %D %D of function",n,p,pf->dimin,pf->dimout); 189 190 if (pf->ops->applyvec) { 191 ierr = (*pf->ops->applyvec)(pf->data,x,y);CHKERRQ(ierr); 192 } else { 193 PetscScalar *xx,*yy; 194 195 ierr = VecGetLocalSize(x,&n);CHKERRQ(ierr); 196 n = n/pf->dimin; 197 ierr = VecGetArray(x,&xx);CHKERRQ(ierr); 198 ierr = VecGetArray(y,&yy);CHKERRQ(ierr); 199 if (!pf->ops->apply) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No function has been provided for this PF"); 200 ierr = (*pf->ops->apply)(pf->data,n,xx,yy);CHKERRQ(ierr); 201 ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr); 202 ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr); 203 } 204 if (nox) { 205 ierr = VecDestroy(x);CHKERRQ(ierr); 206 } 207 PetscFunctionReturn(0); 208 } 209 210 #undef __FUNCT__ 211 #define __FUNCT__ "PFApply" 212 /*@ 213 PFApply - Applies the mathematical function to an array of values. 214 215 Collective on PF 216 217 Input Parameters: 218 + pf - the function context 219 . n - number of pointwise function evaluations to perform, each pointwise function evaluation 220 is a function of dimin variables and computes dimout variables where dimin and dimout are defined 221 in the call to PFCreate() 222 - x - input array 223 224 Output Parameter: 225 . y - output array 226 227 Level: beginner 228 229 Notes: 230 231 .keywords: PF, apply 232 233 .seealso: PFApplyVec(), PFCreate(), PFDestroy(), PFSetType(), PFSet() 234 @*/ 235 PetscErrorCode PETSCVEC_DLLEXPORT PFApply(PF pf,PetscInt n,PetscScalar* x,PetscScalar* y) 236 { 237 PetscErrorCode ierr; 238 239 PetscFunctionBegin; 240 PetscValidHeaderSpecific(pf,PF_COOKIE,1); 241 PetscValidScalarPointer(x,2); 242 PetscValidScalarPointer(y,3); 243 if (x == y) SETERRQ(PETSC_ERR_ARG_IDN,"x and y must be different arrays"); 244 if (!pf->ops->apply) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No function has been provided for this PF"); 245 246 ierr = (*pf->ops->apply)(pf->data,n,x,y);CHKERRQ(ierr); 247 PetscFunctionReturn(0); 248 } 249 250 #undef __FUNCT__ 251 #define __FUNCT__ "PFView" 252 /*@ 253 PFView - Prints information about a mathematical function 254 255 Collective on PF unless PetscViewer is PETSC_VIEWER_STDOUT_SELF 256 257 Input Parameters: 258 + PF - the PF context 259 - viewer - optional visualization context 260 261 Note: 262 The available visualization contexts include 263 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 264 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 265 output where only the first processor opens 266 the file. All other processors send their 267 data to the first processor to print. 268 269 The user can open an alternative visualization contexts with 270 PetscViewerASCIIOpen() (output to a specified file). 271 272 Level: developer 273 274 .keywords: PF, view 275 276 .seealso: PetscViewerCreate(), PetscViewerASCIIOpen() 277 @*/ 278 PetscErrorCode PETSCVEC_DLLEXPORT PFView(PF pf,PetscViewer viewer) 279 { 280 const PFType cstr; 281 PetscErrorCode ierr; 282 PetscTruth iascii; 283 PetscViewerFormat format; 284 285 PetscFunctionBegin; 286 PetscValidHeaderSpecific(pf,PF_COOKIE,1); 287 if (!viewer) { 288 ierr = PetscViewerASCIIGetStdout(((PetscObject)pf)->comm,&viewer);CHKERRQ(ierr); 289 } 290 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,2); 291 PetscCheckSameComm(pf,1,viewer,2); 292 293 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 294 if (iascii) { 295 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 296 ierr = PetscViewerASCIIPrintf(viewer,"PF Object:\n");CHKERRQ(ierr); 297 ierr = PFGetType(pf,&cstr);CHKERRQ(ierr); 298 if (cstr) { 299 ierr = PetscViewerASCIIPrintf(viewer," type: %s\n",cstr);CHKERRQ(ierr); 300 } else { 301 ierr = PetscViewerASCIIPrintf(viewer," type: not yet set\n");CHKERRQ(ierr); 302 } 303 if (pf->ops->view) { 304 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 305 ierr = (*pf->ops->view)(pf->data,viewer);CHKERRQ(ierr); 306 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 307 } 308 } else { 309 SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by PF",((PetscObject)viewer)->type_name); 310 } 311 PetscFunctionReturn(0); 312 } 313 314 /*MC 315 PFRegisterDynamic - Adds a method to the mathematical function package. 316 317 Synopsis: 318 PetscErrorCode PFRegisterDynamic(char *name_solver,char *path,char *name_create,PetscErrorCode (*routine_create)(PF)) 319 320 Not collective 321 322 Input Parameters: 323 + name_solver - name of a new user-defined solver 324 . path - path (either absolute or relative) the library containing this solver 325 . name_create - name of routine to create method context 326 - routine_create - routine to create method context 327 328 Notes: 329 PFRegisterDynamic() may be called multiple times to add several user-defined functions 330 331 If dynamic libraries are used, then the fourth input argument (routine_create) 332 is ignored. 333 334 Sample usage: 335 .vb 336 PFRegisterDynamic("my_function","/home/username/my_lib/lib/libO/solaris/mylib", 337 "MyFunctionCreate",MyFunctionSetCreate); 338 .ve 339 340 Then, your solver can be chosen with the procedural interface via 341 $ PFSetType(pf,"my_function") 342 or at runtime via the option 343 $ -pf_type my_function 344 345 Level: advanced 346 347 ${PETSC_ARCH}, ${PETSC_DIR}, ${PETSC_LIB_DIR}, or ${any environmental variable} 348 occuring in pathname will be replaced with appropriate values. 349 350 .keywords: PF, register 351 352 .seealso: PFRegisterAll(), PFRegisterDestroy(), PFRegister() 353 M*/ 354 355 #undef __FUNCT__ 356 #define __FUNCT__ "PFRegister" 357 PetscErrorCode PETSCVEC_DLLEXPORT PFRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(PF,void*)) 358 { 359 PetscErrorCode ierr; 360 char fullname[PETSC_MAX_PATH_LEN]; 361 362 PetscFunctionBegin; 363 ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 364 ierr = PetscFListAdd(&PFList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 365 PetscFunctionReturn(0); 366 } 367 368 #undef __FUNCT__ 369 #define __FUNCT__ "PFGetType" 370 /*@C 371 PFGetType - Gets the PF method type and name (as a string) from the PF 372 context. 373 374 Not Collective 375 376 Input Parameter: 377 . pf - the function context 378 379 Output Parameter: 380 . type - name of function 381 382 Level: intermediate 383 384 .keywords: PF, get, method, name, type 385 386 .seealso: PFSetType() 387 388 @*/ 389 PetscErrorCode PETSCVEC_DLLEXPORT PFGetType(PF pf,const PFType *type) 390 { 391 PetscFunctionBegin; 392 PetscValidHeaderSpecific(pf,PF_COOKIE,1); 393 PetscValidPointer(type,2); 394 *type = ((PetscObject)pf)->type_name; 395 PetscFunctionReturn(0); 396 } 397 398 399 #undef __FUNCT__ 400 #define __FUNCT__ "PFSetType" 401 /*@C 402 PFSetType - Builds PF for a particular function 403 404 Collective on PF 405 406 Input Parameter: 407 + pf - the function context. 408 . type - a known method 409 - ctx - optional type dependent context 410 411 Options Database Key: 412 . -pf_type <type> - Sets PF type 413 414 415 Notes: 416 See "petsc/include/petscpf.h" for available methods (for instance, 417 PFCONSTANT) 418 419 Level: intermediate 420 421 .keywords: PF, set, method, type 422 423 .seealso: PFSet(), PFRegisterDynamic(), PFCreate(), DACreatePF() 424 425 @*/ 426 PetscErrorCode PETSCVEC_DLLEXPORT PFSetType(PF pf,const PFType type,void *ctx) 427 { 428 PetscErrorCode ierr,(*r)(PF,void*); 429 PetscTruth match; 430 431 PetscFunctionBegin; 432 PetscValidHeaderSpecific(pf,PF_COOKIE,1); 433 PetscValidCharPointer(type,2); 434 435 ierr = PetscTypeCompare((PetscObject)pf,type,&match);CHKERRQ(ierr); 436 if (match) PetscFunctionReturn(0); 437 438 if (pf->ops->destroy) {ierr = (*pf->ops->destroy)(pf);CHKERRQ(ierr);} 439 pf->data = 0; 440 441 /* Determine the PFCreateXXX routine for a particular function */ 442 ierr = PetscFListFind(PFList,((PetscObject)pf)->comm,type,(void (**)(void)) &r);CHKERRQ(ierr); 443 if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested PF type %s",type); 444 pf->ops->destroy = 0; 445 pf->ops->view = 0; 446 pf->ops->apply = 0; 447 pf->ops->applyvec = 0; 448 449 /* Call the PFCreateXXX routine for this particular function */ 450 ierr = (*r)(pf,ctx);CHKERRQ(ierr); 451 452 ierr = PetscObjectChangeTypeName((PetscObject)pf,type);CHKERRQ(ierr); 453 PetscFunctionReturn(0); 454 } 455 456 #undef __FUNCT__ 457 #define __FUNCT__ "PFSetFromOptions" 458 /*@ 459 PFSetFromOptions - Sets PF options from the options database. 460 461 Collective on PF 462 463 Input Parameters: 464 . pf - the mathematical function context 465 466 Options Database Keys: 467 468 Notes: 469 To see all options, run your program with the -help option 470 or consult the users manual. 471 472 Level: intermediate 473 474 .keywords: PF, set, from, options, database 475 476 .seealso: 477 @*/ 478 PetscErrorCode PETSCVEC_DLLEXPORT PFSetFromOptions(PF pf) 479 { 480 PetscErrorCode ierr; 481 char type[256]; 482 PetscTruth flg; 483 484 PetscFunctionBegin; 485 PetscValidHeaderSpecific(pf,PF_COOKIE,1); 486 487 ierr = PetscOptionsBegin(((PetscObject)pf)->comm,((PetscObject)pf)->prefix,"Mathematical functions options","Vec");CHKERRQ(ierr); 488 ierr = PetscOptionsList("-pf_type","Type of function","PFSetType",PFList,0,type,256,&flg);CHKERRQ(ierr); 489 if (flg) { 490 ierr = PFSetType(pf,type,PETSC_NULL);CHKERRQ(ierr); 491 } 492 if (pf->ops->setfromoptions) { 493 ierr = (*pf->ops->setfromoptions)(pf);CHKERRQ(ierr); 494 } 495 ierr = PetscOptionsEnd();CHKERRQ(ierr); 496 497 PetscFunctionReturn(0); 498 } 499 500 static PetscTruth PFPackageInitialized = PETSC_FALSE; 501 #undef __FUNCT__ 502 #define __FUNCT__ "PFFinalizePackage" 503 /*@C 504 PFFinalizePackage - This function destroys everything in the Petsc interface to Mathematica. It is 505 called from PetscFinalize(). 506 507 Level: developer 508 509 .keywords: Petsc, destroy, package, mathematica 510 .seealso: PetscFinalize() 511 @*/ 512 PetscErrorCode PETSC_DLLEXPORT PFFinalizePackage(void) 513 { 514 PetscFunctionBegin; 515 PFPackageInitialized = PETSC_FALSE; 516 PFList = PETSC_NULL; 517 PFRegisterAllCalled = PETSC_FALSE; 518 PetscFunctionReturn(0); 519 } 520 521 #undef __FUNCT__ 522 #define __FUNCT__ "PFInitializePackage" 523 /*@C 524 PFInitializePackage - This function initializes everything in the PF package. It is called 525 from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to PFCreate() 526 when using static libraries. 527 528 Input Parameter: 529 . path - The dynamic library path, or PETSC_NULL 530 531 Level: developer 532 533 .keywords: Vec, initialize, package 534 .seealso: PetscInitialize() 535 @*/ 536 PetscErrorCode PETSCVEC_DLLEXPORT PFInitializePackage(const char path[]) 537 { 538 char logList[256]; 539 char *className; 540 PetscTruth opt; 541 PetscErrorCode ierr; 542 543 PetscFunctionBegin; 544 if (PFPackageInitialized) PetscFunctionReturn(0); 545 PFPackageInitialized = PETSC_TRUE; 546 /* Register Classes */ 547 ierr = PetscCookieRegister("PointFunction",&PF_COOKIE);CHKERRQ(ierr); 548 /* Register Constructors */ 549 ierr = PFRegisterAll(path);CHKERRQ(ierr); 550 /* Process info exclusions */ 551 ierr = PetscOptionsGetString(PETSC_NULL, "-info_exclude", logList, 256, &opt);CHKERRQ(ierr); 552 if (opt) { 553 ierr = PetscStrstr(logList, "pf", &className);CHKERRQ(ierr); 554 if (className) { 555 ierr = PetscInfoDeactivateClass(PF_COOKIE);CHKERRQ(ierr); 556 } 557 } 558 /* Process summary exclusions */ 559 ierr = PetscOptionsGetString(PETSC_NULL, "-log_summary_exclude", logList, 256, &opt);CHKERRQ(ierr); 560 if (opt) { 561 ierr = PetscStrstr(logList, "pf", &className);CHKERRQ(ierr); 562 if (className) { 563 ierr = PetscLogEventDeactivateClass(PF_COOKIE);CHKERRQ(ierr); 564 } 565 } 566 ierr = PetscRegisterFinalize(PFFinalizePackage);CHKERRQ(ierr); 567 PetscFunctionReturn(0); 568 } 569 570 571 572 573 574 575 576 577 578