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