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; 68 69 PetscFunctionBegin; 70 PetscValidHeaderSpecific(pf,PF_COOKIE,1); 71 if (--((PetscObject)pf)->refct > 0) PetscFunctionReturn(0); 72 73 ierr = PetscOptionsHasName(((PetscObject)pf)->prefix,"-pf_view",&flg);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 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 . name - 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,PFType *meth) 390 { 391 PetscFunctionBegin; 392 *meth = (PFType) ((PetscObject)pf)->type_name; 393 PetscFunctionReturn(0); 394 } 395 396 397 #undef __FUNCT__ 398 #define __FUNCT__ "PFSetType" 399 /*@C 400 PFSetType - Builds PF for a particular function 401 402 Collective on PF 403 404 Input Parameter: 405 + pf - the function context. 406 . type - a known method 407 - ctx - optional type dependent context 408 409 Options Database Key: 410 . -pf_type <type> - Sets PF type 411 412 413 Notes: 414 See "petsc/include/petscpf.h" for available methods (for instance, 415 PFCONSTANT) 416 417 Level: intermediate 418 419 .keywords: PF, set, method, type 420 421 .seealso: PFSet(), PFRegisterDynamic(), PFCreate(), DACreatePF() 422 423 @*/ 424 PetscErrorCode PETSCVEC_DLLEXPORT PFSetType(PF pf,PFType type,void *ctx) 425 { 426 PetscErrorCode ierr,(*r)(PF,void*); 427 PetscTruth match; 428 429 PetscFunctionBegin; 430 PetscValidHeaderSpecific(pf,PF_COOKIE,1); 431 PetscValidCharPointer(type,2); 432 433 ierr = PetscTypeCompare((PetscObject)pf,type,&match);CHKERRQ(ierr); 434 if (match) PetscFunctionReturn(0); 435 436 if (pf->ops->destroy) {ierr = (*pf->ops->destroy)(pf);CHKERRQ(ierr);} 437 pf->data = 0; 438 439 /* Determine the PFCreateXXX routine for a particular function */ 440 ierr = PetscFListFind(PFList,((PetscObject)pf)->comm,type,(void (**)(void)) &r);CHKERRQ(ierr); 441 if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested PF type %s",type); 442 pf->ops->destroy = 0; 443 pf->ops->view = 0; 444 pf->ops->apply = 0; 445 pf->ops->applyvec = 0; 446 447 /* Call the PFCreateXXX routine for this particular function */ 448 ierr = (*r)(pf,ctx);CHKERRQ(ierr); 449 450 ierr = PetscObjectChangeTypeName((PetscObject)pf,type);CHKERRQ(ierr); 451 PetscFunctionReturn(0); 452 } 453 454 #undef __FUNCT__ 455 #define __FUNCT__ "PFSetFromOptions" 456 /*@ 457 PFSetFromOptions - Sets PF options from the options database. 458 459 Collective on PF 460 461 Input Parameters: 462 . pf - the mathematical function context 463 464 Options Database Keys: 465 466 Notes: 467 To see all options, run your program with the -help option 468 or consult the users manual. 469 470 Level: intermediate 471 472 .keywords: PF, set, from, options, database 473 474 .seealso: 475 @*/ 476 PetscErrorCode PETSCVEC_DLLEXPORT PFSetFromOptions(PF pf) 477 { 478 PetscErrorCode ierr; 479 char type[256]; 480 PetscTruth flg; 481 482 PetscFunctionBegin; 483 PetscValidHeaderSpecific(pf,PF_COOKIE,1); 484 485 ierr = PetscOptionsBegin(((PetscObject)pf)->comm,((PetscObject)pf)->prefix,"Mathematical functions options","Vec");CHKERRQ(ierr); 486 ierr = PetscOptionsList("-pf_type","Type of function","PFSetType",PFList,0,type,256,&flg);CHKERRQ(ierr); 487 if (flg) { 488 ierr = PFSetType(pf,type,PETSC_NULL);CHKERRQ(ierr); 489 } 490 if (pf->ops->setfromoptions) { 491 ierr = (*pf->ops->setfromoptions)(pf);CHKERRQ(ierr); 492 } 493 ierr = PetscOptionsEnd();CHKERRQ(ierr); 494 495 PetscFunctionReturn(0); 496 } 497 498 #undef __FUNCT__ 499 #define __FUNCT__ "PFInitializePackage" 500 /*@C 501 PFInitializePackage - This function initializes everything in the PF package. It is called 502 from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to PFCreate() 503 when using static libraries. 504 505 Input Parameter: 506 . path - The dynamic library path, or PETSC_NULL 507 508 Level: developer 509 510 .keywords: Vec, initialize, package 511 .seealso: PetscInitialize() 512 @*/ 513 PetscErrorCode PETSCVEC_DLLEXPORT PFInitializePackage(const char path[]) 514 { 515 static PetscTruth initialized = PETSC_FALSE; 516 char logList[256]; 517 char *className; 518 PetscTruth opt; 519 PetscErrorCode ierr; 520 521 PetscFunctionBegin; 522 if (initialized) PetscFunctionReturn(0); 523 initialized = PETSC_TRUE; 524 /* Register Classes */ 525 ierr = PetscLogClassRegister(&PF_COOKIE, "PointFunction");CHKERRQ(ierr); 526 /* Register Constructors */ 527 ierr = PFRegisterAll(path);CHKERRQ(ierr); 528 /* Process info exclusions */ 529 ierr = PetscOptionsGetString(PETSC_NULL, "-info_exclude", logList, 256, &opt);CHKERRQ(ierr); 530 if (opt) { 531 ierr = PetscStrstr(logList, "pf", &className);CHKERRQ(ierr); 532 if (className) { 533 ierr = PetscInfoDeactivateClass(PF_COOKIE);CHKERRQ(ierr); 534 } 535 } 536 /* Process summary exclusions */ 537 ierr = PetscOptionsGetString(PETSC_NULL, "-log_summary_exclude", logList, 256, &opt);CHKERRQ(ierr); 538 if (opt) { 539 ierr = PetscStrstr(logList, "pf", &className);CHKERRQ(ierr); 540 if (className) { 541 ierr = PetscLogEventDeactivateClass(PF_COOKIE);CHKERRQ(ierr); 542 } 543 } 544 PetscFunctionReturn(0); 545 } 546 547 548 549 550 551 552 553 554 555