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