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 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_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 PetscTruth flg = PETSC_FALSE; 68 69 PetscFunctionBegin; 70 PetscValidHeaderSpecific(pf,PF_CLASSID,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_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 PetscTruth 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,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 const PFType cstr; 280 PetscErrorCode ierr; 281 PetscTruth iascii; 282 PetscViewerFormat format; 283 284 PetscFunctionBegin; 285 PetscValidHeaderSpecific(pf,PF_CLASSID,1); 286 if (!viewer) { 287 ierr = PetscViewerASCIIGetStdout(((PetscObject)pf)->comm,&viewer);CHKERRQ(ierr); 288 } 289 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 290 PetscCheckSameComm(pf,1,viewer,2); 291 292 ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 293 if (iascii) { 294 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 295 ierr = PetscViewerASCIIPrintf(viewer,"PF Object:\n");CHKERRQ(ierr); 296 ierr = PFGetType(pf,&cstr);CHKERRQ(ierr); 297 if (cstr) { 298 ierr = PetscViewerASCIIPrintf(viewer," type: %s\n",cstr);CHKERRQ(ierr); 299 } else { 300 ierr = PetscViewerASCIIPrintf(viewer," type: not yet set\n");CHKERRQ(ierr); 301 } 302 if (pf->ops->view) { 303 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 304 ierr = (*pf->ops->view)(pf->data,viewer);CHKERRQ(ierr); 305 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 306 } 307 } else { 308 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported by PF",((PetscObject)viewer)->type_name); 309 } 310 PetscFunctionReturn(0); 311 } 312 313 /*MC 314 PFRegisterDynamic - Adds a method to the mathematical function package. 315 316 Synopsis: 317 PetscErrorCode PFRegisterDynamic(char *name_solver,char *path,char *name_create,PetscErrorCode (*routine_create)(PF)) 318 319 Not collective 320 321 Input Parameters: 322 + name_solver - name of a new user-defined solver 323 . path - path (either absolute or relative) the library containing this solver 324 . name_create - name of routine to create method context 325 - routine_create - routine to create method context 326 327 Notes: 328 PFRegisterDynamic() may be called multiple times to add several user-defined functions 329 330 If dynamic libraries are used, then the fourth input argument (routine_create) 331 is ignored. 332 333 Sample usage: 334 .vb 335 PFRegisterDynamic("my_function","/home/username/my_lib/lib/libO/solaris/mylib", 336 "MyFunctionCreate",MyFunctionSetCreate); 337 .ve 338 339 Then, your solver can be chosen with the procedural interface via 340 $ PFSetType(pf,"my_function") 341 or at runtime via the option 342 $ -pf_type my_function 343 344 Level: advanced 345 346 ${PETSC_ARCH}, ${PETSC_DIR}, ${PETSC_LIB_DIR}, or ${any environmental variable} 347 occuring in pathname will be replaced with appropriate values. 348 349 .keywords: PF, register 350 351 .seealso: PFRegisterAll(), PFRegisterDestroy(), PFRegister() 352 M*/ 353 354 #undef __FUNCT__ 355 #define __FUNCT__ "PFRegister" 356 PetscErrorCode PETSCVEC_DLLEXPORT PFRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(PF,void*)) 357 { 358 PetscErrorCode ierr; 359 char fullname[PETSC_MAX_PATH_LEN]; 360 361 PetscFunctionBegin; 362 ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 363 ierr = PetscFListAdd(&PFList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 364 PetscFunctionReturn(0); 365 } 366 367 #undef __FUNCT__ 368 #define __FUNCT__ "PFGetType" 369 /*@C 370 PFGetType - Gets the PF method type and name (as a string) from the PF 371 context. 372 373 Not Collective 374 375 Input Parameter: 376 . pf - the function context 377 378 Output Parameter: 379 . type - name of function 380 381 Level: intermediate 382 383 .keywords: PF, get, method, name, type 384 385 .seealso: PFSetType() 386 387 @*/ 388 PetscErrorCode PETSCVEC_DLLEXPORT PFGetType(PF pf,const PFType *type) 389 { 390 PetscFunctionBegin; 391 PetscValidHeaderSpecific(pf,PF_CLASSID,1); 392 PetscValidPointer(type,2); 393 *type = ((PetscObject)pf)->type_name; 394 PetscFunctionReturn(0); 395 } 396 397 398 #undef __FUNCT__ 399 #define __FUNCT__ "PFSetType" 400 /*@C 401 PFSetType - Builds PF for a particular function 402 403 Collective on PF 404 405 Input Parameter: 406 + pf - the function context. 407 . type - a known method 408 - ctx - optional type dependent context 409 410 Options Database Key: 411 . -pf_type <type> - Sets PF type 412 413 414 Notes: 415 See "petsc/include/petscpf.h" for available methods (for instance, 416 PFCONSTANT) 417 418 Level: intermediate 419 420 .keywords: PF, set, method, type 421 422 .seealso: PFSet(), PFRegisterDynamic(), PFCreate(), DACreatePF() 423 424 @*/ 425 PetscErrorCode PETSCVEC_DLLEXPORT PFSetType(PF pf,const PFType type,void *ctx) 426 { 427 PetscErrorCode ierr,(*r)(PF,void*); 428 PetscTruth match; 429 430 PetscFunctionBegin; 431 PetscValidHeaderSpecific(pf,PF_CLASSID,1); 432 PetscValidCharPointer(type,2); 433 434 ierr = PetscTypeCompare((PetscObject)pf,type,&match);CHKERRQ(ierr); 435 if (match) PetscFunctionReturn(0); 436 437 if (pf->ops->destroy) {ierr = (*pf->ops->destroy)(pf);CHKERRQ(ierr);} 438 pf->data = 0; 439 440 /* Determine the PFCreateXXX routine for a particular function */ 441 ierr = PetscFListFind(PFList,((PetscObject)pf)->comm,type,(void (**)(void)) &r);CHKERRQ(ierr); 442 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested PF type %s",type); 443 pf->ops->destroy = 0; 444 pf->ops->view = 0; 445 pf->ops->apply = 0; 446 pf->ops->applyvec = 0; 447 448 /* Call the PFCreateXXX routine for this particular function */ 449 ierr = (*r)(pf,ctx);CHKERRQ(ierr); 450 451 ierr = PetscObjectChangeTypeName((PetscObject)pf,type);CHKERRQ(ierr); 452 PetscFunctionReturn(0); 453 } 454 455 #undef __FUNCT__ 456 #define __FUNCT__ "PFSetFromOptions" 457 /*@ 458 PFSetFromOptions - Sets PF options from the options database. 459 460 Collective on PF 461 462 Input Parameters: 463 . pf - the mathematical function context 464 465 Options Database Keys: 466 467 Notes: 468 To see all options, run your program with the -help option 469 or consult the users manual. 470 471 Level: intermediate 472 473 .keywords: PF, set, from, options, database 474 475 .seealso: 476 @*/ 477 PetscErrorCode PETSCVEC_DLLEXPORT PFSetFromOptions(PF pf) 478 { 479 PetscErrorCode ierr; 480 char type[256]; 481 PetscTruth flg; 482 483 PetscFunctionBegin; 484 PetscValidHeaderSpecific(pf,PF_CLASSID,1); 485 486 ierr = PetscOptionsBegin(((PetscObject)pf)->comm,((PetscObject)pf)->prefix,"Mathematical functions options","Vec");CHKERRQ(ierr); 487 ierr = PetscOptionsList("-pf_type","Type of function","PFSetType",PFList,0,type,256,&flg);CHKERRQ(ierr); 488 if (flg) { 489 ierr = PFSetType(pf,type,PETSC_NULL);CHKERRQ(ierr); 490 } 491 if (pf->ops->setfromoptions) { 492 ierr = (*pf->ops->setfromoptions)(pf);CHKERRQ(ierr); 493 } 494 495 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 496 ierr = PetscObjectProcessOptionsHandlers((PetscObject)pf);CHKERRQ(ierr); 497 ierr = PetscOptionsEnd();CHKERRQ(ierr); 498 499 PetscFunctionReturn(0); 500 } 501 502 static PetscTruth PFPackageInitialized = PETSC_FALSE; 503 #undef __FUNCT__ 504 #define __FUNCT__ "PFFinalizePackage" 505 /*@C 506 PFFinalizePackage - This function destroys everything in the Petsc interface to Mathematica. It is 507 called from PetscFinalize(). 508 509 Level: developer 510 511 .keywords: Petsc, destroy, package, mathematica 512 .seealso: PetscFinalize() 513 @*/ 514 PetscErrorCode PETSCVEC_DLLEXPORT PFFinalizePackage(void) 515 { 516 PetscFunctionBegin; 517 PFPackageInitialized = PETSC_FALSE; 518 PFList = PETSC_NULL; 519 PFRegisterAllCalled = PETSC_FALSE; 520 PetscFunctionReturn(0); 521 } 522 523 #undef __FUNCT__ 524 #define __FUNCT__ "PFInitializePackage" 525 /*@C 526 PFInitializePackage - This function initializes everything in the PF package. It is called 527 from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to PFCreate() 528 when using static libraries. 529 530 Input Parameter: 531 . path - The dynamic library path, or PETSC_NULL 532 533 Level: developer 534 535 .keywords: Vec, initialize, package 536 .seealso: PetscInitialize() 537 @*/ 538 PetscErrorCode PETSCVEC_DLLEXPORT PFInitializePackage(const char path[]) 539 { 540 char logList[256]; 541 char *className; 542 PetscTruth opt; 543 PetscErrorCode ierr; 544 545 PetscFunctionBegin; 546 if (PFPackageInitialized) PetscFunctionReturn(0); 547 PFPackageInitialized = PETSC_TRUE; 548 /* Register Classes */ 549 ierr = PetscClassIdRegister("PointFunction",&PF_CLASSID);CHKERRQ(ierr); 550 /* Register Constructors */ 551 ierr = PFRegisterAll(path);CHKERRQ(ierr); 552 /* Process info exclusions */ 553 ierr = PetscOptionsGetString(PETSC_NULL, "-info_exclude", logList, 256, &opt);CHKERRQ(ierr); 554 if (opt) { 555 ierr = PetscStrstr(logList, "pf", &className);CHKERRQ(ierr); 556 if (className) { 557 ierr = PetscInfoDeactivateClass(PF_CLASSID);CHKERRQ(ierr); 558 } 559 } 560 /* Process summary exclusions */ 561 ierr = PetscOptionsGetString(PETSC_NULL, "-log_summary_exclude", logList, 256, &opt);CHKERRQ(ierr); 562 if (opt) { 563 ierr = PetscStrstr(logList, "pf", &className);CHKERRQ(ierr); 564 if (className) { 565 ierr = PetscLogEventDeactivateClass(PF_CLASSID);CHKERRQ(ierr); 566 } 567 } 568 ierr = PetscRegisterFinalize(PFFinalizePackage);CHKERRQ(ierr); 569 PetscFunctionReturn(0); 570 } 571 572 573 574 575 576 577 578 579 580