Actual source code: pf.c

petsc-3.4.4 2014-03-13
  1: /*
  2:     The PF mathematical functions interface routines, callable by users.
  3: */
  4: #include <../src/vec/pf/pfimpl.h>            /*I "petscpf.h" I*/

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

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

 15:    Collective on PF

 17:    Input Parameter:
 18: +  pf - the function context
 19: .  apply - function to apply to an array
 20: .  applyvec - function to apply to a Vec
 21: .  view - function that prints information about the PF
 22: .  destroy - function to free the private function context
 23: -  ctx - private function context

 25:    Level: beginner

 27: .keywords: PF, setting

 29: .seealso: PFCreate(), PFDestroy(), PFSetType(), PFApply(), PFApplyVec()
 30: @*/
 31: 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)
 32: {
 35:   pf->data          = ctx;
 36:   pf->ops->destroy  = destroy;
 37:   pf->ops->apply    = apply;
 38:   pf->ops->applyvec = applyvec;
 39:   pf->ops->view     = view;
 40:   return(0);
 41: }

 45: /*@C
 46:    PFDestroy - Destroys PF context that was created with PFCreate().

 48:    Collective on PF

 50:    Input Parameter:
 51: .  pf - the function context

 53:    Level: beginner

 55: .keywords: PF, destroy

 57: .seealso: PFCreate(), PFSet(), PFSetType()
 58: @*/
 59: PetscErrorCode  PFDestroy(PF *pf)
 60: {
 62:   PetscBool      flg = PETSC_FALSE;

 65:   if (!*pf) return(0);
 67:   if (--((PetscObject)(*pf))->refct > 0) return(0);

 69:   PetscOptionsGetBool(((PetscObject)(*pf))->prefix,"-pf_view",&flg,NULL);
 70:   if (flg) {
 71:     PetscViewer viewer;
 72:     PetscViewerASCIIGetStdout(((PetscObject)(*pf))->comm,&viewer);
 73:     PFView((*pf),viewer);
 74:   }

 76:   /* if memory was published with AMS then destroy it */
 77:   PetscObjectAMSViewOff((PetscObject)*pf);

 79:   if ((*pf)->ops->destroy) { (*(*pf)->ops->destroy)((*pf)->data);}
 80:   PetscHeaderDestroy(pf);
 81:   return(0);
 82: }

 86: /*@C
 87:    PFCreate - Creates a mathematical function context.

 89:    Collective on MPI_Comm

 91:    Input Parameter:
 92: +  comm - MPI communicator
 93: .  dimin - dimension of the space you are mapping from
 94: -  dimout - dimension of the space you are mapping to

 96:    Output Parameter:
 97: .  pf - the function context

 99:    Level: developer

101: .keywords: PF, create, context

103: .seealso: PFSet(), PFApply(), PFDestroy(), PFApplyVec()
104: @*/
105: PetscErrorCode  PFCreate(MPI_Comm comm,PetscInt dimin,PetscInt dimout,PF *pf)
106: {
107:   PF             newpf;

112:   *pf = NULL;
113: #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
114:   PFInitializePackage();
115: #endif

117:   PetscHeaderCreate(newpf,_p_PF,struct _PFOps,PF_CLASSID,"PF","Mathematical functions","Vec",comm,PFDestroy,PFView);
118:   newpf->data          = 0;
119:   newpf->ops->destroy  = 0;
120:   newpf->ops->apply    = 0;
121:   newpf->ops->applyvec = 0;
122:   newpf->ops->view     = 0;
123:   newpf->dimin         = dimin;
124:   newpf->dimout        = dimout;

126:   *pf                  = newpf;
127:   return(0);

129: }

131: /* -------------------------------------------------------------------------------*/

135: /*@
136:    PFApplyVec - Applies the mathematical function to a vector

138:    Collective on PF

140:    Input Parameters:
141: +  pf - the function context
142: -  x - input vector (or NULL for the vector (0,1, .... N-1)

144:    Output Parameter:
145: .  y - output vector

147:    Level: beginner

149: .keywords: PF, apply

151: .seealso: PFApply(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
152: @*/
153: PetscErrorCode  PFApplyVec(PF pf,Vec x,Vec y)
154: {
156:   PetscInt       i,rstart,rend,n,p;
157:   PetscBool      nox = PETSC_FALSE;

162:   if (x) {
164:     if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"x and y must be different vectors");
165:   } else {
166:     PetscScalar *xx;
167:     PetscInt    lsize;

169:     VecGetLocalSize(y,&lsize);
170:     lsize = pf->dimin*lsize/pf->dimout;
171:     VecCreateMPI(PetscObjectComm((PetscObject)y),lsize,PETSC_DETERMINE,&x);
172:     nox   = PETSC_TRUE;
173:     VecGetOwnershipRange(x,&rstart,&rend);
174:     VecGetArray(x,&xx);
175:     for (i=rstart; i<rend; i++) xx[i-rstart] = (PetscScalar)i;
176:     VecRestoreArray(x,&xx);
177:   }

179:   VecGetLocalSize(x,&n);
180:   VecGetLocalSize(y,&p);
181:   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);
182:   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);
183:   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);

185:   if (pf->ops->applyvec) {
186:     (*pf->ops->applyvec)(pf->data,x,y);
187:   } else {
188:     PetscScalar *xx,*yy;

190:     VecGetLocalSize(x,&n);
191:     n    = n/pf->dimin;
192:     VecGetArray(x,&xx);
193:     VecGetArray(y,&yy);
194:     if (!pf->ops->apply) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No function has been provided for this PF");
195:     (*pf->ops->apply)(pf->data,n,xx,yy);
196:     VecRestoreArray(x,&xx);
197:     VecRestoreArray(y,&yy);
198:   }
199:   if (nox) {
200:     VecDestroy(&x);
201:   }
202:   return(0);
203: }

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

210:    Collective on PF

212:    Input Parameters:
213: +  pf - the function context
214: .  n - number of pointwise function evaluations to perform, each pointwise function evaluation
215:        is a function of dimin variables and computes dimout variables where dimin and dimout are defined
216:        in the call to PFCreate()
217: -  x - input array

219:    Output Parameter:
220: .  y - output array

222:    Level: beginner

224:    Notes:

226: .keywords: PF, apply

228: .seealso: PFApplyVec(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
229: @*/
230: PetscErrorCode  PFApply(PF pf,PetscInt n,const PetscScalar *x,PetscScalar *y)
231: {

238:   if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"x and y must be different arrays");
239:   if (!pf->ops->apply) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No function has been provided for this PF");

241:   (*pf->ops->apply)(pf->data,n,x,y);
242:   return(0);
243: }

247: /*@
248:    PFView - Prints information about a mathematical function

250:    Collective on PF unless PetscViewer is PETSC_VIEWER_STDOUT_SELF

252:    Input Parameters:
253: +  PF - the PF context
254: -  viewer - optional visualization context

256:    Note:
257:    The available visualization contexts include
258: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
259: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
260:          output where only the first processor opens
261:          the file.  All other processors send their
262:          data to the first processor to print.

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

267:    Level: developer

269: .keywords: PF, view

271: .seealso: PetscViewerCreate(), PetscViewerASCIIOpen()
272: @*/
273: PetscErrorCode  PFView(PF pf,PetscViewer viewer)
274: {
275:   PetscErrorCode    ierr;
276:   PetscBool         iascii;
277:   PetscViewerFormat format;

281:   if (!viewer) {
282:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pf),&viewer);
283:   }

287:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
288:   if (iascii) {
289:     PetscViewerGetFormat(viewer,&format);
290:     PetscObjectPrintClassNamePrefixType((PetscObject)pf,viewer,"PF Object");
291:     if (pf->ops->view) {
292:       PetscViewerASCIIPushTab(viewer);
293:       (*pf->ops->view)(pf->data,viewer);
294:       PetscViewerASCIIPopTab(viewer);
295:     }
296:   }
297:   return(0);
298: }


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

306:    Not collective

308:    Input Parameters:
309: +  name_solver - name of a new user-defined solver
310: -  routine_create - routine to create method context

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

315:    Sample usage:
316: .vb
317:    PFRegister("my_function",MyFunctionSetCreate);
318: .ve

320:    Then, your solver can be chosen with the procedural interface via
321: $     PFSetType(pf,"my_function")
322:    or at runtime via the option
323: $     -pf_type my_function

325:    Level: advanced

327: .keywords: PF, register

329: .seealso: PFRegisterAll(), PFRegisterDestroy(), PFRegister()
330: @*/
331: PetscErrorCode  PFRegister(const char sname[],PetscErrorCode (*function)(PF,void*))
332: {

336:   PetscFunctionListAdd(&PFList,sname,function);
337:   return(0);
338: }

342: /*@C
343:    PFGetType - Gets the PF method type and name (as a string) from the PF
344:    context.

346:    Not Collective

348:    Input Parameter:
349: .  pf - the function context

351:    Output Parameter:
352: .  type - name of function

354:    Level: intermediate

356: .keywords: PF, get, method, name, type

358: .seealso: PFSetType()

360: @*/
361: PetscErrorCode  PFGetType(PF pf,PFType *type)
362: {
366:   *type = ((PetscObject)pf)->type_name;
367:   return(0);
368: }


373: /*@C
374:    PFSetType - Builds PF for a particular function

376:    Collective on PF

378:    Input Parameter:
379: +  pf - the function context.
380: .  type - a known method
381: -  ctx - optional type dependent context

383:    Options Database Key:
384: .  -pf_type <type> - Sets PF type


387:   Notes:
388:   See "petsc/include/petscpf.h" for available methods (for instance,
389:   PFCONSTANT)

391:   Level: intermediate

393: .keywords: PF, set, method, type

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

397: @*/
398: PetscErrorCode  PFSetType(PF pf,PFType type,void *ctx)
399: {
400:   PetscErrorCode ierr,(*r)(PF,void*);
401:   PetscBool      match;


407:   PetscObjectTypeCompare((PetscObject)pf,type,&match);
408:   if (match) return(0);

410:   if (pf->ops->destroy) { (*pf->ops->destroy)(pf);}
411:   pf->data = 0;

413:   /* Determine the PFCreateXXX routine for a particular function */
414:   PetscFunctionListFind(PFList,type,&r);
415:   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested PF type %s",type);
416:   pf->ops->destroy  = 0;
417:   pf->ops->view     = 0;
418:   pf->ops->apply    = 0;
419:   pf->ops->applyvec = 0;

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

424:   PetscObjectChangeTypeName((PetscObject)pf,type);
425:   return(0);
426: }

430: /*@
431:    PFSetFromOptions - Sets PF options from the options database.

433:    Collective on PF

435:    Input Parameters:
436: .  pf - the mathematical function context

438:    Options Database Keys:

440:    Notes:
441:    To see all options, run your program with the -help option
442:    or consult the users manual.

444:    Level: intermediate

446: .keywords: PF, set, from, options, database

448: .seealso:
449: @*/
450: PetscErrorCode  PFSetFromOptions(PF pf)
451: {
453:   char           type[256];
454:   PetscBool      flg;


459:   PetscObjectOptionsBegin((PetscObject)pf);
460:   PetscOptionsList("-pf_type","Type of function","PFSetType",PFList,0,type,256,&flg);
461:   if (flg) {
462:     PFSetType(pf,type,NULL);
463:   }
464:   if (pf->ops->setfromoptions) {
465:     (*pf->ops->setfromoptions)(pf);
466:   }

468:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
469:   PetscObjectProcessOptionsHandlers((PetscObject)pf);
470:   PetscOptionsEnd();
471:   return(0);
472: }

474: static PetscBool PFPackageInitialized = PETSC_FALSE;
477: /*@C
478:   PFFinalizePackage - This function destroys everything in the Petsc interface to Mathematica. It is
479:   called from PetscFinalize().

481:   Level: developer

483: .keywords: Petsc, destroy, package, mathematica
484: .seealso: PetscFinalize()
485: @*/
486: PetscErrorCode  PFFinalizePackage(void)
487: {

491:   PetscFunctionListDestroy(&PFList);
492:   PFPackageInitialized = PETSC_FALSE;
493:   PFRegisterAllCalled  = PETSC_FALSE;
494:   return(0);
495: }

499: /*@C
500:   PFInitializePackage - This function initializes everything in the PF package. It is called
501:   from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to PFCreate()
502:   when using static libraries.

504:   Level: developer

506: .keywords: Vec, initialize, package
507: .seealso: PetscInitialize()
508: @*/
509: PetscErrorCode  PFInitializePackage(void)
510: {
511:   char           logList[256];
512:   char           *className;
513:   PetscBool      opt;

517:   if (PFPackageInitialized) return(0);
518:   PFPackageInitialized = PETSC_TRUE;
519:   /* Register Classes */
520:   PetscClassIdRegister("PointFunction",&PF_CLASSID);
521:   /* Register Constructors */
522:   PFRegisterAll();
523:   /* Process info exclusions */
524:   PetscOptionsGetString(NULL, "-info_exclude", logList, 256, &opt);
525:   if (opt) {
526:     PetscStrstr(logList, "pf", &className);
527:     if (className) {
528:       PetscInfoDeactivateClass(PF_CLASSID);
529:     }
530:   }
531:   /* Process summary exclusions */
532:   PetscOptionsGetString(NULL, "-log_summary_exclude", logList, 256, &opt);
533:   if (opt) {
534:     PetscStrstr(logList, "pf", &className);
535:     if (className) {
536:       PetscLogEventDeactivateClass(PF_CLASSID);
537:     }
538:   }
539:   PetscRegisterFinalize(PFFinalizePackage);
540:   return(0);
541: }