Actual source code: pf.c

  1: /*
  2:     The PF mathematical functions interface routines, callable by users.
  3: */
  4: #include <../src/vec/pf/pfimpl.h>

  6: PetscClassId      PF_CLASSID          = 0;
  7: PetscFunctionList PFList              = NULL; /* list of all registered PD functions */
  8: PetscBool         PFRegisterAllCalled = PETSC_FALSE;

 10: /*@C
 11:    PFSet - Sets the C/C++/Fortran functions to be used by the PF function

 13:    Collective

 15:    Input Parameters:
 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

 23:    Level: beginner

 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: {
 30:   pf->data          = ctx;
 31:   pf->ops->destroy  = destroy;
 32:   pf->ops->apply    = apply;
 33:   pf->ops->applyvec = applyvec;
 34:   pf->ops->view     = view;
 35:   return 0;
 36: }

 38: /*@C
 39:    PFDestroy - Destroys `PF` context that was created with `PFCreate()`.

 41:    Collective

 43:    Input Parameter:
 44: .  pf - the function context

 46:    Level: beginner

 48: .seealso: `PFCreate()`, `PFSet()`, `PFSetType()`
 49: @*/
 50: PetscErrorCode PFDestroy(PF *pf)
 51: {
 52:   if (!*pf) return 0;
 54:   if (--((PetscObject)(*pf))->refct > 0) return 0;

 56:   PFViewFromOptions(*pf, NULL, "-pf_view");
 57:   /* if memory was published with SAWs then destroy it */
 58:   PetscObjectSAWsViewOff((PetscObject)*pf);

 60:   if ((*pf)->ops->destroy) (*(*pf)->ops->destroy)((*pf)->data);
 61:   PetscHeaderDestroy(pf);
 62:   return 0;
 63: }

 65: /*@C
 66:    PFCreate - Creates a mathematical function context.

 68:    Collective

 70:    Input Parameters:
 71: +  comm - MPI communicator
 72: .  dimin - dimension of the space you are mapping from
 73: -  dimout - dimension of the space you are mapping to

 75:    Output Parameter:
 76: .  pf - the function context

 78:    Level: developer

 80: .seealso: `PFSet()`, `PFApply()`, `PFDestroy()`, `PFApplyVec()`
 81: @*/
 82: PetscErrorCode PFCreate(MPI_Comm comm, PetscInt dimin, PetscInt dimout, PF *pf)
 83: {
 84:   PF newpf;

 87:   *pf = NULL;
 88:   PFInitializePackage();

 90:   PetscHeaderCreate(newpf, PF_CLASSID, "PF", "Mathematical functions", "Vec", comm, PFDestroy, PFView);
 91:   newpf->data          = NULL;
 92:   newpf->ops->destroy  = NULL;
 93:   newpf->ops->apply    = NULL;
 94:   newpf->ops->applyvec = NULL;
 95:   newpf->ops->view     = NULL;
 96:   newpf->dimin         = dimin;
 97:   newpf->dimout        = dimout;

 99:   *pf = newpf;
100:   return 0;
101: }

103: /* -------------------------------------------------------------------------------*/

105: /*@
106:    PFApplyVec - Applies the mathematical function to a vector

108:    Collective

110:    Input Parameters:
111: +  pf - the function context
112: -  x - input vector (or NULL for the vector (0,1, .... N-1)

114:    Output Parameter:
115: .  y - output vector

117:    Level: beginner

119: .seealso: `PFApply()`, `PFCreate()`, `PFDestroy()`, `PFSetType()`, `PFSet()`
120: @*/
121: PetscErrorCode PFApplyVec(PF pf, Vec x, Vec y)
122: {
123:   PetscInt  i, rstart, rend, n, p;
124:   PetscBool nox = PETSC_FALSE;

128:   if (x) {
131:   } else {
132:     PetscScalar *xx;
133:     PetscInt     lsize;

135:     VecGetLocalSize(y, &lsize);
136:     lsize = pf->dimin * lsize / pf->dimout;
137:     VecCreateMPI(PetscObjectComm((PetscObject)y), lsize, PETSC_DETERMINE, &x);
138:     nox = PETSC_TRUE;
139:     VecGetOwnershipRange(x, &rstart, &rend);
140:     VecGetArray(x, &xx);
141:     for (i = rstart; i < rend; i++) xx[i - rstart] = (PetscScalar)i;
142:     VecRestoreArray(x, &xx);
143:   }

145:   VecGetLocalSize(x, &n);
146:   VecGetLocalSize(y, &p);

151:   if (pf->ops->applyvec) (*pf->ops->applyvec)(pf->data, x, y);
152:   else {
153:     PetscScalar *xx, *yy;

155:     VecGetLocalSize(x, &n);
156:     n = n / pf->dimin;
157:     VecGetArray(x, &xx);
158:     VecGetArray(y, &yy);
159:     (*pf->ops->apply)(pf->data, n, xx, yy);
160:     VecRestoreArray(x, &xx);
161:     VecRestoreArray(y, &yy);
162:   }
163:   if (nox) VecDestroy(&x);
164:   return 0;
165: }

167: /*@
168:    PFApply - Applies the mathematical function to an array of values.

170:    Collective

172:    Input Parameters:
173: +  pf - the function context
174: .  n - number of pointwise function evaluations to perform, each pointwise function evaluation
175:        is a function of dimin variables and computes dimout variables where dimin and dimout are defined
176:        in the call to PFCreate()
177: -  x - input array

179:    Output Parameter:
180: .  y - output array

182:    Level: beginner

184:    Notes:

186: .seealso: `PFApplyVec()`, `PFCreate()`, `PFDestroy()`, `PFSetType()`, `PFSet()`
187: @*/
188: PetscErrorCode PFApply(PF pf, PetscInt n, const PetscScalar *x, PetscScalar *y)
189: {

195:   (*pf->ops->apply)(pf->data, n, x, y);
196:   return 0;
197: }

199: /*@C
200:    PFViewFromOptions - View from Options

202:    Collective

204:    Input Parameters:
205: +  A - the PF context
206: .  obj - Optional object
207: -  name - command line option

209:    Level: intermediate
210: .seealso: `PF`, `PFView`, `PetscObjectViewFromOptions()`, `PFCreate()`
211: @*/
212: PetscErrorCode PFViewFromOptions(PF A, PetscObject obj, const char name[])
213: {
215:   PetscObjectViewFromOptions((PetscObject)A, obj, name);
216:   return 0;
217: }

219: /*@
220:    PFView - Prints information about a mathematical function

222:    Collective on PF unless PetscViewer is PETSC_VIEWER_STDOUT_SELF

224:    Input Parameters:
225: +  PF - the PF context
226: -  viewer - optional visualization context

228:    Note:
229:    The available visualization contexts include
230: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
231: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
232:          output where only the first processor opens
233:          the file.  All other processors send their
234:          data to the first processor to print.

236:    The user can open an alternative visualization contexts with
237:    PetscViewerASCIIOpen() (output to a specified file).

239:    Level: developer

241: .seealso: `PetscViewerCreate()`, `PetscViewerASCIIOpen()`
242: @*/
243: PetscErrorCode PFView(PF pf, PetscViewer viewer)
244: {
245:   PetscBool         iascii;
246:   PetscViewerFormat format;

249:   if (!viewer) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pf), &viewer);

253:   PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);
254:   if (iascii) {
255:     PetscViewerGetFormat(viewer, &format);
256:     PetscObjectPrintClassNamePrefixType((PetscObject)pf, viewer);
257:     if (pf->ops->view) {
258:       PetscViewerASCIIPushTab(viewer);
259:       (*pf->ops->view)(pf->data, viewer);
260:       PetscViewerASCIIPopTab(viewer);
261:     }
262:   }
263:   return 0;
264: }

266: /*@C
267:    PFRegister - Adds a method to the mathematical function package.

269:    Not collective

271:    Input Parameters:
272: +  name_solver - name of a new user-defined solver
273: -  routine_create - routine to create method context

275:    Notes:
276:    PFRegister() may be called multiple times to add several user-defined functions

278:    Sample usage:
279: .vb
280:    PFRegister("my_function",MyFunctionSetCreate);
281: .ve

283:    Then, your solver can be chosen with the procedural interface via
284: $     PFSetType(pf,"my_function")
285:    or at runtime via the option
286: $     -pf_type my_function

288:    Level: advanced

290: .seealso: `PFRegisterAll()`, `PFRegisterDestroy()`, `PFRegister()`
291: @*/
292: PetscErrorCode PFRegister(const char sname[], PetscErrorCode (*function)(PF, void *))
293: {
294:   PFInitializePackage();
295:   PetscFunctionListAdd(&PFList, sname, function);
296:   return 0;
297: }

299: /*@C
300:    PFGetType - Gets the PF method type and name (as a string) from the PF
301:    context.

303:    Not Collective

305:    Input Parameter:
306: .  pf - the function context

308:    Output Parameter:
309: .  type - name of function

311:    Level: intermediate

313: .seealso: `PFSetType()`

315: @*/
316: PetscErrorCode PFGetType(PF pf, PFType *type)
317: {
320:   *type = ((PetscObject)pf)->type_name;
321:   return 0;
322: }

324: /*@C
325:    PFSetType - Builds PF for a particular function

327:    Collective

329:    Input Parameters:
330: +  pf - the function context.
331: .  type - a known method
332: -  ctx - optional type dependent context

334:    Options Database Key:
335: .  -pf_type <type> - Sets PF type

337:   Notes:
338:   See "petsc/include/petscpf.h" for available methods (for instance,
339:   PFCONSTANT)

341:   Level: intermediate

343: .seealso: `PFSet()`, `PFRegister()`, `PFCreate()`, `DMDACreatePF()`

345: @*/
346: PetscErrorCode PFSetType(PF pf, PFType type, void *ctx)
347: {
348:   PetscBool match;
349:   PetscErrorCode (*r)(PF, void *);


354:   PetscObjectTypeCompare((PetscObject)pf, type, &match);
355:   if (match) return 0;

357:   PetscTryTypeMethod(pf, destroy);
358:   pf->data = NULL;

360:   /* Determine the PFCreateXXX routine for a particular function */
361:   PetscFunctionListFind(PFList, type, &r);
363:   pf->ops->destroy  = NULL;
364:   pf->ops->view     = NULL;
365:   pf->ops->apply    = NULL;
366:   pf->ops->applyvec = NULL;

368:   /* Call the PFCreateXXX routine for this particular function */
369:   (*r)(pf, ctx);

371:   PetscObjectChangeTypeName((PetscObject)pf, type);
372:   return 0;
373: }

375: /*@
376:    PFSetFromOptions - Sets PF options from the options database.

378:    Collective

380:    Input Parameters:
381: .  pf - the mathematical function context

383:    Options Database Keys:

385:    Notes:
386:    To see all options, run your program with the -help option
387:    or consult the users manual.

389:    Level: intermediate

391: .seealso:
392: @*/
393: PetscErrorCode PFSetFromOptions(PF pf)
394: {
395:   char      type[256];
396:   PetscBool flg;


400:   PetscObjectOptionsBegin((PetscObject)pf);
401:   PetscOptionsFList("-pf_type", "Type of function", "PFSetType", PFList, NULL, type, 256, &flg);
402:   if (flg) PFSetType(pf, type, NULL);
403:   PetscTryTypeMethod(pf, setfromoptions, PetscOptionsObject);

405:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
406:   PetscObjectProcessOptionsHandlers((PetscObject)pf, PetscOptionsObject);
407:   PetscOptionsEnd();
408:   return 0;
409: }

411: static PetscBool PFPackageInitialized = PETSC_FALSE;
412: /*@C
413:   PFFinalizePackage - This function destroys everything in the Petsc interface to Mathematica. It is
414:   called from PetscFinalize().

416:   Level: developer

418: .seealso: `PetscFinalize()`
419: @*/
420: PetscErrorCode PFFinalizePackage(void)
421: {
422:   PetscFunctionListDestroy(&PFList);
423:   PFPackageInitialized = PETSC_FALSE;
424:   PFRegisterAllCalled  = PETSC_FALSE;
425:   return 0;
426: }

428: /*@C
429:   PFInitializePackage - This function initializes everything in the PF package. It is called
430:   from PetscDLLibraryRegister_petscvec() when using dynamic libraries, and on the first call to PFCreate()
431:   when using shared or static libraries.

433:   Level: developer

435: .seealso: `PetscInitialize()`
436: @*/
437: PetscErrorCode PFInitializePackage(void)
438: {
439:   char      logList[256];
440:   PetscBool opt, pkg;

442:   if (PFPackageInitialized) return 0;
443:   PFPackageInitialized = PETSC_TRUE;
444:   /* Register Classes */
445:   PetscClassIdRegister("PointFunction", &PF_CLASSID);
446:   /* Register Constructors */
447:   PFRegisterAll();
448:   /* Process Info */
449:   {
450:     PetscClassId classids[1];

452:     classids[0] = PF_CLASSID;
453:     PetscInfoProcessClass("pf", 1, classids);
454:   }
455:   /* Process summary exclusions */
456:   PetscOptionsGetString(NULL, NULL, "-log_exclude", logList, sizeof(logList), &opt);
457:   if (opt) {
458:     PetscStrInList("pf", logList, ',', &pkg);
459:     if (pkg) PetscLogEventExcludeClass(PF_CLASSID);
460:   }
461:   /* Register package finalizer */
462:   PetscRegisterFinalize(PFFinalizePackage);
463:   return 0;
464: }