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