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