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