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 = PetscFunctionListAdd(&PFList,sname,function);CHKERRQ(ierr); 314 PetscFunctionReturn(0); 315 } 316 317 /*@C 318 PFGetType - Gets the PF method type and name (as a string) from the PF 319 context. 320 321 Not Collective 322 323 Input Parameter: 324 . pf - the function context 325 326 Output Parameter: 327 . type - name of function 328 329 Level: intermediate 330 331 .keywords: PF, get, method, name, type 332 333 .seealso: PFSetType() 334 335 @*/ 336 PetscErrorCode PFGetType(PF pf,PFType *type) 337 { 338 PetscFunctionBegin; 339 PetscValidHeaderSpecific(pf,PF_CLASSID,1); 340 PetscValidPointer(type,2); 341 *type = ((PetscObject)pf)->type_name; 342 PetscFunctionReturn(0); 343 } 344 345 346 /*@C 347 PFSetType - Builds PF for a particular function 348 349 Collective on PF 350 351 Input Parameter: 352 + pf - the function context. 353 . type - a known method 354 - ctx - optional type dependent context 355 356 Options Database Key: 357 . -pf_type <type> - Sets PF type 358 359 360 Notes: 361 See "petsc/include/petscpf.h" for available methods (for instance, 362 PFCONSTANT) 363 364 Level: intermediate 365 366 .keywords: PF, set, method, type 367 368 .seealso: PFSet(), PFRegister(), PFCreate(), DMDACreatePF() 369 370 @*/ 371 PetscErrorCode PFSetType(PF pf,PFType type,void *ctx) 372 { 373 PetscErrorCode ierr,(*r)(PF,void*); 374 PetscBool match; 375 376 PetscFunctionBegin; 377 PetscValidHeaderSpecific(pf,PF_CLASSID,1); 378 PetscValidCharPointer(type,2); 379 380 ierr = PetscObjectTypeCompare((PetscObject)pf,type,&match);CHKERRQ(ierr); 381 if (match) PetscFunctionReturn(0); 382 383 if (pf->ops->destroy) {ierr = (*pf->ops->destroy)(pf);CHKERRQ(ierr);} 384 pf->data = 0; 385 386 /* Determine the PFCreateXXX routine for a particular function */ 387 ierr = PetscFunctionListFind(PFList,type,&r);CHKERRQ(ierr); 388 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested PF type %s",type); 389 pf->ops->destroy = 0; 390 pf->ops->view = 0; 391 pf->ops->apply = 0; 392 pf->ops->applyvec = 0; 393 394 /* Call the PFCreateXXX routine for this particular function */ 395 ierr = (*r)(pf,ctx);CHKERRQ(ierr); 396 397 ierr = PetscObjectChangeTypeName((PetscObject)pf,type);CHKERRQ(ierr); 398 PetscFunctionReturn(0); 399 } 400 401 /*@ 402 PFSetFromOptions - Sets PF options from the options database. 403 404 Collective on PF 405 406 Input Parameters: 407 . pf - the mathematical function context 408 409 Options Database Keys: 410 411 Notes: 412 To see all options, run your program with the -help option 413 or consult the users manual. 414 415 Level: intermediate 416 417 .keywords: PF, set, from, options, database 418 419 .seealso: 420 @*/ 421 PetscErrorCode PFSetFromOptions(PF pf) 422 { 423 PetscErrorCode ierr; 424 char type[256]; 425 PetscBool flg; 426 427 PetscFunctionBegin; 428 PetscValidHeaderSpecific(pf,PF_CLASSID,1); 429 430 ierr = PetscObjectOptionsBegin((PetscObject)pf);CHKERRQ(ierr); 431 ierr = PetscOptionsFList("-pf_type","Type of function","PFSetType",PFList,0,type,256,&flg);CHKERRQ(ierr); 432 if (flg) { 433 ierr = PFSetType(pf,type,NULL);CHKERRQ(ierr); 434 } 435 if (pf->ops->setfromoptions) { 436 ierr = (*pf->ops->setfromoptions)(PetscOptionsObject,pf);CHKERRQ(ierr); 437 } 438 439 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 440 ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)pf);CHKERRQ(ierr); 441 ierr = PetscOptionsEnd();CHKERRQ(ierr); 442 PetscFunctionReturn(0); 443 } 444 445 static PetscBool PFPackageInitialized = PETSC_FALSE; 446 /*@C 447 PFFinalizePackage - This function destroys everything in the Petsc interface to Mathematica. It is 448 called from PetscFinalize(). 449 450 Level: developer 451 452 .keywords: Petsc, destroy, package, mathematica 453 .seealso: PetscFinalize() 454 @*/ 455 PetscErrorCode PFFinalizePackage(void) 456 { 457 PetscErrorCode ierr; 458 459 PetscFunctionBegin; 460 ierr = PetscFunctionListDestroy(&PFList);CHKERRQ(ierr); 461 PFPackageInitialized = PETSC_FALSE; 462 PFRegisterAllCalled = PETSC_FALSE; 463 PetscFunctionReturn(0); 464 } 465 466 /*@C 467 PFInitializePackage - This function initializes everything in the PF package. It is called 468 from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to PFCreate() 469 when using static libraries. 470 471 Level: developer 472 473 .keywords: Vec, initialize, package 474 .seealso: PetscInitialize() 475 @*/ 476 PetscErrorCode PFInitializePackage(void) 477 { 478 char logList[256]; 479 PetscBool opt,pkg; 480 PetscErrorCode ierr; 481 482 PetscFunctionBegin; 483 if (PFPackageInitialized) PetscFunctionReturn(0); 484 PFPackageInitialized = PETSC_TRUE; 485 /* Register Classes */ 486 ierr = PetscClassIdRegister("PointFunction",&PF_CLASSID);CHKERRQ(ierr); 487 /* Register Constructors */ 488 ierr = PFRegisterAll();CHKERRQ(ierr); 489 /* Process info exclusions */ 490 ierr = PetscOptionsGetString(NULL,NULL,"-info_exclude",logList,sizeof(logList),&opt);CHKERRQ(ierr); 491 if (opt) { 492 ierr = PetscStrInList("pf",logList,',',&pkg);CHKERRQ(ierr); 493 if (pkg) {ierr = PetscInfoDeactivateClass(PF_CLASSID);CHKERRQ(ierr);} 494 } 495 /* Process summary exclusions */ 496 ierr = PetscOptionsGetString(NULL,NULL,"-log_exclude",logList,sizeof(logList),&opt);CHKERRQ(ierr); 497 if (opt) { 498 ierr = PetscStrInList("pf",logList,',',&pkg);CHKERRQ(ierr); 499 if (pkg) {ierr = PetscLogEventDeactivateClass(PF_CLASSID);CHKERRQ(ierr);} 500 } 501 /* Register package finalizer */ 502 ierr = PetscRegisterFinalize(PFFinalizePackage);CHKERRQ(ierr); 503 PetscFunctionReturn(0); 504 } 505 506 507 508 509 510 511 512 513 514