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