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: }