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