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