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 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,4); 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 = NULL; 98 newpf->ops->destroy = NULL; 99 newpf->ops->apply = NULL; 100 newpf->ops->applyvec = NULL; 101 newpf->ops->view = NULL; 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,3); 208 PetscValidScalarPointer(y,4); 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 /*@C 217 PFViewFromOptions - View from Options 218 219 Collective on PF 220 221 Input Parameters: 222 + A - the PF context 223 . obj - Optional object 224 - name - command line option 225 226 Level: intermediate 227 .seealso: PF, PFView, PetscObjectViewFromOptions(), PFCreate() 228 @*/ 229 PetscErrorCode PFViewFromOptions(PF A,PetscObject obj,const char name[]) 230 { 231 PetscErrorCode ierr; 232 233 PetscFunctionBegin; 234 PetscValidHeaderSpecific(A,PF_CLASSID,1); 235 ierr = PetscObjectViewFromOptions((PetscObject)A,obj,name);CHKERRQ(ierr); 236 PetscFunctionReturn(0); 237 } 238 239 /*@ 240 PFView - Prints information about a mathematical function 241 242 Collective on PF unless PetscViewer is PETSC_VIEWER_STDOUT_SELF 243 244 Input Parameters: 245 + PF - the PF context 246 - viewer - optional visualization context 247 248 Note: 249 The available visualization contexts include 250 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 251 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 252 output where only the first processor opens 253 the file. All other processors send their 254 data to the first processor to print. 255 256 The user can open an alternative visualization contexts with 257 PetscViewerASCIIOpen() (output to a specified file). 258 259 Level: developer 260 261 .seealso: PetscViewerCreate(), PetscViewerASCIIOpen() 262 @*/ 263 PetscErrorCode PFView(PF pf,PetscViewer viewer) 264 { 265 PetscErrorCode ierr; 266 PetscBool iascii; 267 PetscViewerFormat format; 268 269 PetscFunctionBegin; 270 PetscValidHeaderSpecific(pf,PF_CLASSID,1); 271 if (!viewer) { 272 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pf),&viewer);CHKERRQ(ierr); 273 } 274 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 275 PetscCheckSameComm(pf,1,viewer,2); 276 277 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 278 if (iascii) { 279 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 280 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)pf,viewer);CHKERRQ(ierr); 281 if (pf->ops->view) { 282 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 283 ierr = (*pf->ops->view)(pf->data,viewer);CHKERRQ(ierr); 284 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 285 } 286 } 287 PetscFunctionReturn(0); 288 } 289 290 /*@C 291 PFRegister - Adds a method to the mathematical function package. 292 293 Not collective 294 295 Input Parameters: 296 + name_solver - name of a new user-defined solver 297 - routine_create - routine to create method context 298 299 Notes: 300 PFRegister() may be called multiple times to add several user-defined functions 301 302 Sample usage: 303 .vb 304 PFRegister("my_function",MyFunctionSetCreate); 305 .ve 306 307 Then, your solver can be chosen with the procedural interface via 308 $ PFSetType(pf,"my_function") 309 or at runtime via the option 310 $ -pf_type my_function 311 312 Level: advanced 313 314 .seealso: PFRegisterAll(), PFRegisterDestroy(), PFRegister() 315 @*/ 316 PetscErrorCode PFRegister(const char sname[],PetscErrorCode (*function)(PF,void*)) 317 { 318 PetscErrorCode ierr; 319 320 PetscFunctionBegin; 321 ierr = PFInitializePackage();CHKERRQ(ierr); 322 ierr = PetscFunctionListAdd(&PFList,sname,function);CHKERRQ(ierr); 323 PetscFunctionReturn(0); 324 } 325 326 /*@C 327 PFGetType - Gets the PF method type and name (as a string) from the PF 328 context. 329 330 Not Collective 331 332 Input Parameter: 333 . pf - the function context 334 335 Output Parameter: 336 . type - name of function 337 338 Level: intermediate 339 340 .seealso: PFSetType() 341 342 @*/ 343 PetscErrorCode PFGetType(PF pf,PFType *type) 344 { 345 PetscFunctionBegin; 346 PetscValidHeaderSpecific(pf,PF_CLASSID,1); 347 PetscValidPointer(type,2); 348 *type = ((PetscObject)pf)->type_name; 349 PetscFunctionReturn(0); 350 } 351 352 /*@C 353 PFSetType - Builds PF for a particular function 354 355 Collective on PF 356 357 Input Parameter: 358 + pf - the function context. 359 . type - a known method 360 - ctx - optional type dependent context 361 362 Options Database Key: 363 . -pf_type <type> - Sets PF type 364 365 Notes: 366 See "petsc/include/petscpf.h" for available methods (for instance, 367 PFCONSTANT) 368 369 Level: intermediate 370 371 .seealso: PFSet(), PFRegister(), PFCreate(), DMDACreatePF() 372 373 @*/ 374 PetscErrorCode PFSetType(PF pf,PFType type,void *ctx) 375 { 376 PetscErrorCode ierr,(*r)(PF,void*); 377 PetscBool match; 378 379 PetscFunctionBegin; 380 PetscValidHeaderSpecific(pf,PF_CLASSID,1); 381 PetscValidCharPointer(type,2); 382 383 ierr = PetscObjectTypeCompare((PetscObject)pf,type,&match);CHKERRQ(ierr); 384 if (match) PetscFunctionReturn(0); 385 386 if (pf->ops->destroy) {ierr = (*pf->ops->destroy)(pf);CHKERRQ(ierr);} 387 pf->data = NULL; 388 389 /* Determine the PFCreateXXX routine for a particular function */ 390 ierr = PetscFunctionListFind(PFList,type,&r);CHKERRQ(ierr); 391 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested PF type %s",type); 392 pf->ops->destroy = NULL; 393 pf->ops->view = NULL; 394 pf->ops->apply = NULL; 395 pf->ops->applyvec = NULL; 396 397 /* Call the PFCreateXXX routine for this particular function */ 398 ierr = (*r)(pf,ctx);CHKERRQ(ierr); 399 400 ierr = PetscObjectChangeTypeName((PetscObject)pf,type);CHKERRQ(ierr); 401 PetscFunctionReturn(0); 402 } 403 404 /*@ 405 PFSetFromOptions - Sets PF options from the options database. 406 407 Collective on PF 408 409 Input Parameters: 410 . pf - the mathematical function context 411 412 Options Database Keys: 413 414 Notes: 415 To see all options, run your program with the -help option 416 or consult the users manual. 417 418 Level: intermediate 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,NULL,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 .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_petscvec() when using dynamic libraries, and on the first call to PFCreate() 469 when using shared or static libraries. 470 471 Level: developer 472 473 .seealso: PetscInitialize() 474 @*/ 475 PetscErrorCode PFInitializePackage(void) 476 { 477 char logList[256]; 478 PetscBool opt,pkg; 479 PetscErrorCode ierr; 480 481 PetscFunctionBegin; 482 if (PFPackageInitialized) PetscFunctionReturn(0); 483 PFPackageInitialized = PETSC_TRUE; 484 /* Register Classes */ 485 ierr = PetscClassIdRegister("PointFunction",&PF_CLASSID);CHKERRQ(ierr); 486 /* Register Constructors */ 487 ierr = PFRegisterAll();CHKERRQ(ierr); 488 /* Process Info */ 489 { 490 PetscClassId classids[1]; 491 492 classids[0] = PF_CLASSID; 493 ierr = PetscInfoProcessClass("pf", 1, classids);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 = PetscLogEventExcludeClass(PF_CLASSID);CHKERRQ(ierr);} 500 } 501 /* Register package finalizer */ 502 ierr = PetscRegisterFinalize(PFFinalizePackage);CHKERRQ(ierr); 503 PetscFunctionReturn(0); 504 } 505 506