Actual source code: pf.c

petsc-3.6.1 2015-08-06
Report Typos and Errors
  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: {

 64:   if (!*pf) return(0);
 66:   if (--((PetscObject)(*pf))->refct > 0) return(0);

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

 72:   if ((*pf)->ops->destroy) { (*(*pf)->ops->destroy)((*pf)->data);}
 73:   PetscHeaderDestroy(pf);
 74:   return(0);
 75: }

 79: /*@C
 80:    PFCreate - Creates a mathematical function context.

 82:    Collective on MPI_Comm

 84:    Input Parameter:
 85: +  comm - MPI communicator
 86: .  dimin - dimension of the space you are mapping from
 87: -  dimout - dimension of the space you are mapping to

 89:    Output Parameter:
 90: .  pf - the function context

 92:    Level: developer

 94: .keywords: PF, create, context

 96: .seealso: PFSet(), PFApply(), PFDestroy(), PFApplyVec()
 97: @*/
 98: PetscErrorCode  PFCreate(MPI_Comm comm,PetscInt dimin,PetscInt dimout,PF *pf)
 99: {
100:   PF             newpf;

105:   *pf = NULL;
106:   PFInitializePackage();

108:   PetscHeaderCreate(newpf,PF_CLASSID,"PF","Mathematical functions","Vec",comm,PFDestroy,PFView);
109:   newpf->data          = 0;
110:   newpf->ops->destroy  = 0;
111:   newpf->ops->apply    = 0;
112:   newpf->ops->applyvec = 0;
113:   newpf->ops->view     = 0;
114:   newpf->dimin         = dimin;
115:   newpf->dimout        = dimout;

117:   *pf                  = newpf;
118:   return(0);

120: }

122: /* -------------------------------------------------------------------------------*/

126: /*@
127:    PFApplyVec - Applies the mathematical function to a vector

129:    Collective on PF

131:    Input Parameters:
132: +  pf - the function context
133: -  x - input vector (or NULL for the vector (0,1, .... N-1)

135:    Output Parameter:
136: .  y - output vector

138:    Level: beginner

140: .keywords: PF, apply

142: .seealso: PFApply(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
143: @*/
144: PetscErrorCode  PFApplyVec(PF pf,Vec x,Vec y)
145: {
147:   PetscInt       i,rstart,rend,n,p;
148:   PetscBool      nox = PETSC_FALSE;

153:   if (x) {
155:     if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"x and y must be different vectors");
156:   } else {
157:     PetscScalar *xx;
158:     PetscInt    lsize;

160:     VecGetLocalSize(y,&lsize);
161:     lsize = pf->dimin*lsize/pf->dimout;
162:     VecCreateMPI(PetscObjectComm((PetscObject)y),lsize,PETSC_DETERMINE,&x);
163:     nox   = PETSC_TRUE;
164:     VecGetOwnershipRange(x,&rstart,&rend);
165:     VecGetArray(x,&xx);
166:     for (i=rstart; i<rend; i++) xx[i-rstart] = (PetscScalar)i;
167:     VecRestoreArray(x,&xx);
168:   }

170:   VecGetLocalSize(x,&n);
171:   VecGetLocalSize(y,&p);
172:   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);
173:   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);
174:   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);

176:   if (pf->ops->applyvec) {
177:     (*pf->ops->applyvec)(pf->data,x,y);
178:   } else {
179:     PetscScalar *xx,*yy;

181:     VecGetLocalSize(x,&n);
182:     n    = n/pf->dimin;
183:     VecGetArray(x,&xx);
184:     VecGetArray(y,&yy);
185:     if (!pf->ops->apply) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No function has been provided for this PF");
186:     (*pf->ops->apply)(pf->data,n,xx,yy);
187:     VecRestoreArray(x,&xx);
188:     VecRestoreArray(y,&yy);
189:   }
190:   if (nox) {
191:     VecDestroy(&x);
192:   }
193:   return(0);
194: }

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

201:    Collective on PF

203:    Input Parameters:
204: +  pf - the function context
205: .  n - number of pointwise function evaluations to perform, each pointwise function evaluation
206:        is a function of dimin variables and computes dimout variables where dimin and dimout are defined
207:        in the call to PFCreate()
208: -  x - input array

210:    Output Parameter:
211: .  y - output array

213:    Level: beginner

215:    Notes:

217: .keywords: PF, apply

219: .seealso: PFApplyVec(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
220: @*/
221: PetscErrorCode  PFApply(PF pf,PetscInt n,const PetscScalar *x,PetscScalar *y)
222: {

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

232:   (*pf->ops->apply)(pf->data,n,x,y);
233:   return(0);
234: }

238: /*@
239:    PFView - Prints information about a mathematical function

241:    Collective on PF unless PetscViewer is PETSC_VIEWER_STDOUT_SELF

243:    Input Parameters:
244: +  PF - the PF context
245: -  viewer - optional visualization context

247:    Note:
248:    The available visualization contexts include
249: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
250: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
251:          output where only the first processor opens
252:          the file.  All other processors send their
253:          data to the first processor to print.

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

258:    Level: developer

260: .keywords: PF, view

262: .seealso: PetscViewerCreate(), PetscViewerASCIIOpen()
263: @*/
264: PetscErrorCode  PFView(PF pf,PetscViewer viewer)
265: {
266:   PetscErrorCode    ierr;
267:   PetscBool         iascii;
268:   PetscViewerFormat format;

272:   if (!viewer) {
273:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pf),&viewer);
274:   }

278:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
279:   if (iascii) {
280:     PetscViewerGetFormat(viewer,&format);
281:     PetscObjectPrintClassNamePrefixType((PetscObject)pf,viewer);
282:     if (pf->ops->view) {
283:       PetscViewerASCIIPushTab(viewer);
284:       (*pf->ops->view)(pf->data,viewer);
285:       PetscViewerASCIIPopTab(viewer);
286:     }
287:   }
288:   return(0);
289: }


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

297:    Not collective

299:    Input Parameters:
300: +  name_solver - name of a new user-defined solver
301: -  routine_create - routine to create method context

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

306:    Sample usage:
307: .vb
308:    PFRegister("my_function",MyFunctionSetCreate);
309: .ve

311:    Then, your solver can be chosen with the procedural interface via
312: $     PFSetType(pf,"my_function")
313:    or at runtime via the option
314: $     -pf_type my_function

316:    Level: advanced

318: .keywords: PF, register

320: .seealso: PFRegisterAll(), PFRegisterDestroy(), PFRegister()
321: @*/
322: PetscErrorCode  PFRegister(const char sname[],PetscErrorCode (*function)(PF,void*))
323: {

327:   PetscFunctionListAdd(&PFList,sname,function);
328:   return(0);
329: }

333: /*@C
334:    PFGetType - Gets the PF method type and name (as a string) from the PF
335:    context.

337:    Not Collective

339:    Input Parameter:
340: .  pf - the function context

342:    Output Parameter:
343: .  type - name of function

345:    Level: intermediate

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

349: .seealso: PFSetType()

351: @*/
352: PetscErrorCode  PFGetType(PF pf,PFType *type)
353: {
357:   *type = ((PetscObject)pf)->type_name;
358:   return(0);
359: }


364: /*@C
365:    PFSetType - Builds PF for a particular function

367:    Collective on PF

369:    Input Parameter:
370: +  pf - the function context.
371: .  type - a known method
372: -  ctx - optional type dependent context

374:    Options Database Key:
375: .  -pf_type <type> - Sets PF type


378:   Notes:
379:   See "petsc/include/petscpf.h" for available methods (for instance,
380:   PFCONSTANT)

382:   Level: intermediate

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

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

388: @*/
389: PetscErrorCode  PFSetType(PF pf,PFType type,void *ctx)
390: {
391:   PetscErrorCode ierr,(*r)(PF,void*);
392:   PetscBool      match;


398:   PetscObjectTypeCompare((PetscObject)pf,type,&match);
399:   if (match) return(0);

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

404:   /* Determine the PFCreateXXX routine for a particular function */
405:   PetscFunctionListFind(PFList,type,&r);
406:   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested PF type %s",type);
407:   pf->ops->destroy  = 0;
408:   pf->ops->view     = 0;
409:   pf->ops->apply    = 0;
410:   pf->ops->applyvec = 0;

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

415:   PetscObjectChangeTypeName((PetscObject)pf,type);
416:   return(0);
417: }

421: /*@
422:    PFSetFromOptions - Sets PF options from the options database.

424:    Collective on PF

426:    Input Parameters:
427: .  pf - the mathematical function context

429:    Options Database Keys:

431:    Notes:
432:    To see all options, run your program with the -help option
433:    or consult the users manual.

435:    Level: intermediate

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

439: .seealso:
440: @*/
441: PetscErrorCode  PFSetFromOptions(PF pf)
442: {
444:   char           type[256];
445:   PetscBool      flg;


450:   PetscObjectOptionsBegin((PetscObject)pf);
451:   PetscOptionsFList("-pf_type","Type of function","PFSetType",PFList,0,type,256,&flg);
452:   if (flg) {
453:     PFSetType(pf,type,NULL);
454:   }
455:   if (pf->ops->setfromoptions) {
456:     (*pf->ops->setfromoptions)(PetscOptionsObject,pf);
457:   }

459:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
460:   PetscObjectProcessOptionsHandlers((PetscObject)pf);
461:   PetscOptionsEnd();
462:   return(0);
463: }

465: static PetscBool PFPackageInitialized = PETSC_FALSE;
468: /*@C
469:   PFFinalizePackage - This function destroys everything in the Petsc interface to Mathematica. It is
470:   called from PetscFinalize().

472:   Level: developer

474: .keywords: Petsc, destroy, package, mathematica
475: .seealso: PetscFinalize()
476: @*/
477: PetscErrorCode  PFFinalizePackage(void)
478: {

482:   PetscFunctionListDestroy(&PFList);
483:   PFPackageInitialized = PETSC_FALSE;
484:   PFRegisterAllCalled  = PETSC_FALSE;
485:   return(0);
486: }

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

495:   Level: developer

497: .keywords: Vec, initialize, package
498: .seealso: PetscInitialize()
499: @*/
500: PetscErrorCode  PFInitializePackage(void)
501: {
502:   char           logList[256];
503:   char           *className;
504:   PetscBool      opt;

508:   if (PFPackageInitialized) return(0);
509:   PFPackageInitialized = PETSC_TRUE;
510:   /* Register Classes */
511:   PetscClassIdRegister("PointFunction",&PF_CLASSID);
512:   /* Register Constructors */
513:   PFRegisterAll();
514:   /* Process info exclusions */
515:   PetscOptionsGetString(NULL, "-info_exclude", logList, 256, &opt);
516:   if (opt) {
517:     PetscStrstr(logList, "pf", &className);
518:     if (className) {
519:       PetscInfoDeactivateClass(PF_CLASSID);
520:     }
521:   }
522:   /* Process summary exclusions */
523:   PetscOptionsGetString(NULL, "-log_summary_exclude", logList, 256, &opt);
524:   if (opt) {
525:     PetscStrstr(logList, "pf", &className);
526:     if (className) {
527:       PetscLogEventDeactivateClass(PF_CLASSID);
528:     }
529:   }
530:   PetscRegisterFinalize(PFFinalizePackage);
531:   return(0);
532: }