Actual source code: pf.c

  1: /*$Id: pf.c,v 1.25 2001/08/07 03:05:06 balay Exp $*/
  2: /*
  3:     The PF mathematical functions interface routines, callable by users.
  4: */
 5:  #include src/pf/pfimpl.h

  7: PetscFList      PPetscFList = 0; /* list of all registered PD functions */
  8: PetscTruth 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 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

 23:    Level: beginner

 25: .keywords: PF, setting

 27: .seealso: PFCreate(), PFDestroy(), PFSetType(), PFApply(), PFApplyVec()
 28: @*/
 29: int PFSet(PF pf,int(*apply)(void*,int,PetscScalar*,PetscScalar*),int(*applyvec)(void*,Vec,Vec),int(*view)(void*,PetscViewer),int(*destroy)(void*),void*ctx)
 30: {
 33:   pf->data             = ctx;

 35:   pf->ops->destroy     = destroy;
 36:   pf->ops->apply       = apply;
 37:   pf->ops->applyvec    = applyvec;
 38:   pf->ops->view        = view;

 40:   return(0);
 41: }

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

 46:    Collective on PF

 48:    Input Parameter:
 49: .  pf - the function context

 51:    Level: beginner

 53: .keywords: PF, destroy

 55: .seealso: PFCreate(), PFSet(), PFSetType()
 56: @*/
 57: int PFDestroy(PF pf)
 58: {
 59:   int        ierr;
 60:   PetscTruth flg;

 64:   if (--pf->refct > 0) return(0);

 66:   PetscOptionsHasName(pf->prefix,"-pf_view",&flg);
 67:   if (flg) {
 68:     PFView(pf,PETSC_VIEWER_STDOUT_(pf->comm));
 69:   }

 71:   /* if memory was published with AMS then destroy it */
 72:   PetscObjectDepublish(pf);

 74:   if (pf->ops->destroy) { (*pf->ops->destroy)(pf->data);}
 75:   PetscLogObjectDestroy(pf);
 76:   PetscHeaderDestroy(pf);
 77:   return(0);
 78: }

 80: static int PFPublish_Petsc(PetscObject obj)
 81: {
 82: #if defined(PETSC_HAVE_AMS)
 83:   PF          v = (PF) obj;
 84:   int         ierr;
 85: #endif


 89: #if defined(PETSC_HAVE_AMS)
 90:   /* if it is already published then return */
 91:   if (v->amem >=0) return(0);

 93:   PetscObjectPublishBaseBegin(obj);
 94:   PetscObjectPublishBaseEnd(obj);
 95: #endif

 97:   return(0);
 98: }

100: /*@C
101:    PFCreate - Creates a mathematical function context.

103:    Collective on MPI_Comm

105:    Input Parameter:
106: +  comm - MPI communicator 
107: .  dimin - dimension of the space you are mapping from
108: -  dimout - dimension of the space you are mapping to

110:    Output Parameter:
111: .  pf - the function context

113:    Level: developer

115: .keywords: PF, create, context

117: .seealso: PFSetUp(), PFApply(), PFDestroy(), PFApplyVec()
118: @*/
119: int PFCreate(MPI_Comm comm,int dimin,int dimout,PF *pf)
120: {
121:   PF  newpf;

125:   *pf          = 0;

127:   PetscHeaderCreate(newpf,_p_PF,struct _PFOps,PF_COOKIE,-1,"PF",comm,PFDestroy,PFView);
128:   PetscLogObjectCreate(newpf);
129:   newpf->bops->publish    = PFPublish_Petsc;
130:   newpf->data             = 0;

132:   newpf->ops->destroy     = 0;
133:   newpf->ops->apply       = 0;
134:   newpf->ops->applyvec    = 0;
135:   newpf->ops->view        = 0;
136:   newpf->dimin            = dimin;
137:   newpf->dimout           = dimout;

139:   *pf                     = newpf;
140:   PetscPublishAll(pf);
141:   return(0);

143: }

145: /* -------------------------------------------------------------------------------*/

147: /*@
148:    PFApplyVec - Applies the mathematical function to a vector

150:    Collective on PF

152:    Input Parameters:
153: +  pf - the function context
154: -  x - input vector (or PETSC_NULL for the vector (0,1, .... N-1)

156:    Output Parameter:
157: .  y - output vector

159:    Level: beginner

161: .keywords: PF, apply

163: .seealso: PFApply(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
164: @*/
165: int PFApplyVec(PF pf,Vec x,Vec y)
166: {
167:   int        ierr,i,rstart,rend,n,p;
168:   PetscTruth nox = PETSC_FALSE;

173:   if (x) {
175:     if (x == y) SETERRQ(PETSC_ERR_ARG_IDN,"x and y must be different vectors");
176:   } else {
177:     PetscScalar *xx;

179:     VecDuplicate(y,&x);
180:     nox  = PETSC_TRUE;
181:     VecGetOwnershipRange(x,&rstart,&rend);
182:     VecGetArray(x,&xx);
183:     for (i=rstart; i<rend; i++) {
184:       xx[i-rstart] = (PetscScalar)i;
185:     }
186:     VecRestoreArray(x,&xx);
187:   }

189:   VecGetLocalSize(x,&n);
190:   VecGetLocalSize(y,&p);
191:   if (pf->dimin*(n/pf->dimin) != n) SETERRQ2(PETSC_ERR_ARG_IDN,"Local input vector length %d not divisible by dimin %d of function",n,pf->dimin);
192:   if (pf->dimout*(p/pf->dimout) != p) SETERRQ2(PETSC_ERR_ARG_IDN,"Local output vector length %d not divisible by dimout %d of function",p,pf->dimout);
193:   if (n/pf->dimin != p/pf->dimout) SETERRQ4(PETSC_ERR_ARG_IDN,"Local vector lengths %d %d are wrong for dimin and dimout %d %d of function",n,p,pf->dimin,pf->dimout);

195:   if (pf->ops->applyvec) {
196:     (*pf->ops->applyvec)(pf->data,x,y);
197:   } else {
198:     PetscScalar *xx,*yy;

200:     VecGetLocalSize(x,&n);
201:     n    = n/pf->dimin;
202:     VecGetArray(x,&xx);
203:     VecGetArray(y,&yy);
204:     if (!pf->ops->apply) SETERRQ(1,"No function has been provided for this PF");
205:     (*pf->ops->apply)(pf->data,n,xx,yy);
206:     VecRestoreArray(x,&xx);
207:     VecRestoreArray(y,&yy);
208:   }
209:   if (nox) {
210:     VecDestroy(x);
211:   }
212:   return(0);
213: }

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

218:    Collective on PF

220:    Input Parameters:
221: +  pf - the function context
222: .  n - number of pointwise function evaluations to perform, each pointwise function evaluation
223:        is a function of dimin variables and computes dimout variables where dimin and dimout are defined
224:        in the call to PFCreate()
225: -  x - input array

227:    Output Parameter:
228: .  y - output array

230:    Level: beginner

232:    Notes: 

234: .keywords: PF, apply

236: .seealso: PFApplyVec(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
237: @*/
238: int PFApply(PF pf,int n,PetscScalar* x,PetscScalar* y)
239: {
240:   int        ierr;

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

247:   (*pf->ops->apply)(pf->data,n,x,y);
248:   return(0);
249: }

251: /*@ 
252:    PFView - Prints information about a mathematical function

254:    Collective on PF unless PetscViewer is PETSC_VIEWER_STDOUT_SELF  

256:    Input Parameters:
257: +  PF - the PF context
258: -  viewer - optional visualization context

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

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

271:    Level: developer

273: .keywords: PF, view

275: .seealso: PetscViewerCreate(), PetscViewerASCIIOpen()
276: @*/
277: int PFView(PF pf,PetscViewer viewer)
278: {
279:   PFType            cstr;
280:   int               ierr;
281:   PetscTruth        isascii;
282:   PetscViewerFormat format;

286:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(pf->comm);

290:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
291:   if (isascii) {
292:     PetscViewerGetFormat(viewer,&format);
293:     PetscViewerASCIIPrintf(viewer,"PF Object:n");
294:     PFGetType(pf,&cstr);
295:     if (cstr) {
296:       PetscViewerASCIIPrintf(viewer,"  type: %sn",cstr);
297:     } else {
298:       PetscViewerASCIIPrintf(viewer,"  type: not yet setn");
299:     }
300:     if (pf->ops->view) {
301:       PetscViewerASCIIPushTab(viewer);
302:       (*pf->ops->view)(pf->data,viewer);
303:       PetscViewerASCIIPopTab(viewer);
304:     }
305:   } else {
306:     SETERRQ1(1,"Viewer type %s not supported by PF",((PetscObject)viewer)->type_name);
307:   }
308:   return(0);
309: }

311: /*MC
312:    PFRegisterDynamic - Adds a method to the mathematical function package.

314:    Synopsis:
315:    int PFRegisterDynamic(char *name_solver,char *path,char *name_create,int (*routine_create)(PF))

317:    Not collective

319:    Input Parameters:
320: +  name_solver - name of a new user-defined solver
321: .  path - path (either absolute or relative) the library containing this solver
322: .  name_create - name of routine to create method context
323: -  routine_create - routine to create method context

325:    Notes:
326:    PFRegisterDynamic() may be called multiple times to add several user-defined functions

328:    If dynamic libraries are used, then the fourth input argument (routine_create)
329:    is ignored.

331:    Sample usage:
332: .vb
333:    PFRegisterDynamic("my_function","/home/username/my_lib/lib/libO/solaris/mylib",
334:               "MyFunctionCreate",MyFunctionSetCreate);
335: .ve

337:    Then, your solver can be chosen with the procedural interface via
338: $     PFSetType(pf,"my_function")
339:    or at runtime via the option
340: $     -pf_type my_function

342:    Level: advanced

344:    ${PETSC_ARCH}, ${PETSC_DIR}, ${PETSC_LIB_DIR}, ${BOPT}, or ${any environmental variable}
345:  occuring in pathname will be replaced with appropriate values.

347: .keywords: PF, register

349: .seealso: PFRegisterAll(), PFRegisterDestroy(), PFRegister()
350: M*/

352: int PFRegister(char *sname,char *path,char *name,int (*function)(PF,void*))
353: {
354:   int  ierr;
355:   char fullname[256];

358:   PetscFListConcat(path,name,fullname);
359:   PetscFListAdd(&PPetscFList,sname,fullname,(void (*)(void))function);
360:   return(0);
361: }



365: /*@C
366:    PFGetType - Gets the PF method type and name (as a string) from the PF
367:    context.

369:    Not Collective

371:    Input Parameter:
372: .  pf - the function context

374:    Output Parameter:
375: .  name - name of function 

377:    Level: intermediate

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

381: .seealso: PFSetType()

383: @*/
384: int PFGetType(PF pf,PFType *meth)
385: {
387:   *meth = (PFType) pf->type_name;
388:   return(0);
389: }


392: /*@C
393:    PFSetType - Builds PF for a particular function

395:    Collective on PF

397:    Input Parameter:
398: +  pf - the function context.
399: .  type - a known method
400: -  ctx - optional type dependent context

402:    Options Database Key:
403: .  -pf_type <type> - Sets PF type


406:   Notes:
407:   See "petsc/include/petscpf.h" for available methods (for instance,
408:   PFCONSTANT)

410:   Level: intermediate

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

414: .seealso: PFSet(), PFRegisterDynamic(), PFCreate(), DACreatePF()

416: @*/
417: int PFSetType(PF pf,PFType type,void *ctx)
418: {
419:   int        ierr,(*r)(PF,void*);
420:   PetscTruth match;


426:   PetscTypeCompare((PetscObject)pf,type,&match);
427:   if (match) return(0);

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

432:   /* Get the function pointers for the method requested */
433:   if (!PFRegisterAllCalled) {PFRegisterAll(0);}

435:   /* Determine the PFCreateXXX routine for a particular function */
436:    PetscFListFind(pf->comm,PPetscFList,type,(void (**)(void)) &r);
437:   if (!r) SETERRQ1(1,"Unable to find requested PF type %s",type);

439:   pf->ops->destroy             = 0;
440:   pf->ops->view                = 0;
441:   pf->ops->apply               = 0;
442:   pf->ops->applyvec            = 0;

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

447:   PetscObjectChangeTypeName((PetscObject)pf,type);
448:   return(0);
449: }

451: /*@
452:    PFSetFromOptions - Sets PF options from the options database.

454:    Collective on PF

456:    Input Parameters:
457: .  pf - the mathematical function context

459:    Options Database Keys:

461:    Notes:  
462:    To see all options, run your program with the -help option
463:    or consult the users manual.

465:    Level: intermediate

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

469: .seealso:
470: @*/
471: int PFSetFromOptions(PF pf)
472: {
473:   int        ierr;
474:   char       type[256];
475:   PetscTruth flg;


480:   if (!PFRegisterAllCalled) {PFRegisterAll(0);}
481:   PetscOptionsBegin(pf->comm,pf->prefix,"Mathematical functions options","Vec");
482:     PetscOptionsList("-pf_type","Type of function","PFSetType",PPetscFList,0,type,256,&flg);
483:     if (flg) {
484:       PFSetType(pf,type,PETSC_NULL);
485:     }
486:     if (pf->ops->setfromoptions) {
487:       (*pf->ops->setfromoptions)(pf);
488:     }
489:   PetscOptionsEnd();

491:   return(0);
492: }