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