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