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 on PF

 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 on PF

 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;

102: }

104: /* -------------------------------------------------------------------------------*/

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

109:    Collective on PF

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

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

118:    Level: beginner

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

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

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

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

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

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

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

175:    Collective on PF

177:    Input Parameters:
178: +  pf - the function context
179: .  n - number of pointwise function evaluations to perform, each pointwise function evaluation
180:        is a function of dimin variables and computes dimout variables where dimin and dimout are defined
181:        in the call to PFCreate()
182: -  x - input array

184:    Output Parameter:
185: .  y - output array

187:    Level: beginner

189:    Notes:

191: .seealso: PFApplyVec(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
192: @*/
193: PetscErrorCode  PFApply(PF pf,PetscInt n,const PetscScalar *x,PetscScalar *y)
194: {

201:   (*pf->ops->apply)(pf->data,n,x,y);
202:   return 0;
203: }

205: /*@C
206:    PFViewFromOptions - View from Options

208:    Collective on PF

210:    Input Parameters:
211: +  A - the PF context
212: .  obj - Optional object
213: -  name - command line option

215:    Level: intermediate
216: .seealso:  PF, PFView, PetscObjectViewFromOptions(), PFCreate()
217: @*/
218: PetscErrorCode  PFViewFromOptions(PF A,PetscObject obj,const char name[])
219: {
221:   PetscObjectViewFromOptions((PetscObject)A,obj,name);
222:   return 0;
223: }

225: /*@
226:    PFView - Prints information about a mathematical function

228:    Collective on PF unless PetscViewer is PETSC_VIEWER_STDOUT_SELF

230:    Input Parameters:
231: +  PF - the PF context
232: -  viewer - optional visualization context

234:    Note:
235:    The available visualization contexts include
236: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
237: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
238:          output where only the first processor opens
239:          the file.  All other processors send their
240:          data to the first processor to print.

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

245:    Level: developer

247: .seealso: PetscViewerCreate(), PetscViewerASCIIOpen()
248: @*/
249: PetscErrorCode  PFView(PF pf,PetscViewer viewer)
250: {
251:   PetscBool         iascii;
252:   PetscViewerFormat format;

255:   if (!viewer) {
256:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pf),&viewer);
257:   }

261:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
262:   if (iascii) {
263:     PetscViewerGetFormat(viewer,&format);
264:     PetscObjectPrintClassNamePrefixType((PetscObject)pf,viewer);
265:     if (pf->ops->view) {
266:       PetscViewerASCIIPushTab(viewer);
267:       (*pf->ops->view)(pf->data,viewer);
268:       PetscViewerASCIIPopTab(viewer);
269:     }
270:   }
271:   return 0;
272: }

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

277:    Not collective

279:    Input Parameters:
280: +  name_solver - name of a new user-defined solver
281: -  routine_create - routine to create method context

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

286:    Sample usage:
287: .vb
288:    PFRegister("my_function",MyFunctionSetCreate);
289: .ve

291:    Then, your solver can be chosen with the procedural interface via
292: $     PFSetType(pf,"my_function")
293:    or at runtime via the option
294: $     -pf_type my_function

296:    Level: advanced

298: .seealso: PFRegisterAll(), PFRegisterDestroy(), PFRegister()
299: @*/
300: PetscErrorCode  PFRegister(const char sname[],PetscErrorCode (*function)(PF,void*))
301: {
302:   PFInitializePackage();
303:   PetscFunctionListAdd(&PFList,sname,function);
304:   return 0;
305: }

307: /*@C
308:    PFGetType - Gets the PF method type and name (as a string) from the PF
309:    context.

311:    Not Collective

313:    Input Parameter:
314: .  pf - the function context

316:    Output Parameter:
317: .  type - name of function

319:    Level: intermediate

321: .seealso: PFSetType()

323: @*/
324: PetscErrorCode  PFGetType(PF pf,PFType *type)
325: {
328:   *type = ((PetscObject)pf)->type_name;
329:   return 0;
330: }

332: /*@C
333:    PFSetType - Builds PF for a particular function

335:    Collective on PF

337:    Input Parameters:
338: +  pf - the function context.
339: .  type - a known method
340: -  ctx - optional type dependent context

342:    Options Database Key:
343: .  -pf_type <type> - Sets PF type

345:   Notes:
346:   See "petsc/include/petscpf.h" for available methods (for instance,
347:   PFCONSTANT)

349:   Level: intermediate

351: .seealso: PFSet(), PFRegister(), PFCreate(), DMDACreatePF()

353: @*/
354: PetscErrorCode  PFSetType(PF pf,PFType type,void *ctx)
355: {
356:   PetscBool      match;
357:   PetscErrorCode (*r)(PF,void*);


362:   PetscObjectTypeCompare((PetscObject)pf,type,&match);
363:   if (match) return 0;

365:   if (pf->ops->destroy) (*pf->ops->destroy)(pf);
366:   pf->data = NULL;

368:   /* Determine the PFCreateXXX routine for a particular function */
369:   PetscFunctionListFind(PFList,type,&r);
371:   pf->ops->destroy  = NULL;
372:   pf->ops->view     = NULL;
373:   pf->ops->apply    = NULL;
374:   pf->ops->applyvec = NULL;

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

379:   PetscObjectChangeTypeName((PetscObject)pf,type);
380:   return 0;
381: }

383: /*@
384:    PFSetFromOptions - Sets PF options from the options database.

386:    Collective on PF

388:    Input Parameters:
389: .  pf - the mathematical function context

391:    Options Database Keys:

393:    Notes:
394:    To see all options, run your program with the -help option
395:    or consult the users manual.

397:    Level: intermediate

399: .seealso:
400: @*/
401: PetscErrorCode  PFSetFromOptions(PF pf)
402: {
404:   char           type[256];
405:   PetscBool      flg;


409:   PetscObjectOptionsBegin((PetscObject)pf);
410:   PetscOptionsFList("-pf_type","Type of function","PFSetType",PFList,NULL,type,256,&flg);
411:   if (flg) {
412:     PFSetType(pf,type,NULL);
413:   }
414:   if (pf->ops->setfromoptions) {
415:     (*pf->ops->setfromoptions)(PetscOptionsObject,pf);
416:   }

418:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
419:   PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)pf);
420:   PetscOptionsEnd();
421:   return 0;
422: }

424: static PetscBool PFPackageInitialized = PETSC_FALSE;
425: /*@C
426:   PFFinalizePackage - This function destroys everything in the Petsc interface to Mathematica. It is
427:   called from PetscFinalize().

429:   Level: developer

431: .seealso: PetscFinalize()
432: @*/
433: PetscErrorCode  PFFinalizePackage(void)
434: {
435:   PetscFunctionListDestroy(&PFList);
436:   PFPackageInitialized = PETSC_FALSE;
437:   PFRegisterAllCalled  = PETSC_FALSE;
438:   return 0;
439: }

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

446:   Level: developer

448: .seealso: PetscInitialize()
449: @*/
450: PetscErrorCode  PFInitializePackage(void)
451: {
452:   char           logList[256];
453:   PetscBool      opt,pkg;

455:   if (PFPackageInitialized) return 0;
456:   PFPackageInitialized = PETSC_TRUE;
457:   /* Register Classes */
458:   PetscClassIdRegister("PointFunction",&PF_CLASSID);
459:   /* Register Constructors */
460:   PFRegisterAll();
461:   /* Process Info */
462:   {
463:     PetscClassId  classids[1];

465:     classids[0] = PF_CLASSID;
466:     PetscInfoProcessClass("pf", 1, classids);
467:   }
468:   /* Process summary exclusions */
469:   PetscOptionsGetString(NULL,NULL,"-log_exclude",logList,sizeof(logList),&opt);
470:   if (opt) {
471:     PetscStrInList("pf",logList,',',&pkg);
472:     if (pkg) PetscLogEventExcludeClass(PF_CLASSID);
473:   }
474:   /* Register package finalizer */
475:   PetscRegisterFinalize(PFFinalizePackage);
476:   return 0;
477: }