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: /* Logging support */
8: int PF_COOKIE;
10: PetscFList PPetscFList = PETSC_NULL; /* list of all registered PD functions */
11: PetscTruth PFRegisterAllCalled = PETSC_FALSE;
13: #undef __FUNCT__
15: /*@C
16: PFSet - Sets the C/C++/Fortran functions to be used by the PF function
18: Collective on PF
20: Input Parameter:
21: + pf - the function context
22: . apply - function to apply to an array
23: . applyvec - function to apply to a Vec
24: . view - function that prints information about the PF
25: . destroy - function to free the private function context
26: - ctx - private function context
28: Level: beginner
30: .keywords: PF, setting
32: .seealso: PFCreate(), PFDestroy(), PFSetType(), PFApply(), PFApplyVec()
33: @*/
34: int PFSet(PF pf,int(*apply)(void*,int,PetscScalar*,PetscScalar*),int(*applyvec)(void*,Vec,Vec),int(*view)(void*,PetscViewer),int(*destroy)(void*),void*ctx)
35: {
38: pf->data = ctx;
40: pf->ops->destroy = destroy;
41: pf->ops->apply = apply;
42: pf->ops->applyvec = applyvec;
43: pf->ops->view = view;
45: return(0);
46: }
48: #undef __FUNCT__
50: /*@C
51: PFDestroy - Destroys PF context that was created with PFCreate().
53: Collective on PF
55: Input Parameter:
56: . pf - the function context
58: Level: beginner
60: .keywords: PF, destroy
62: .seealso: PFCreate(), PFSet(), PFSetType()
63: @*/
64: int PFDestroy(PF pf)
65: {
66: int ierr;
67: PetscTruth flg;
71: if (--pf->refct > 0) return(0);
73: PetscOptionsHasName(pf->prefix,"-pf_view",&flg);
74: if (flg) {
75: PFView(pf,PETSC_VIEWER_STDOUT_(pf->comm));
76: }
78: /* if memory was published with AMS then destroy it */
79: PetscObjectDepublish(pf);
81: if (pf->ops->destroy) { (*pf->ops->destroy)(pf->data);}
82: PetscLogObjectDestroy(pf);
83: PetscHeaderDestroy(pf);
84: return(0);
85: }
87: #undef __FUNCT__
89: static int PFPublish_Petsc(PetscObject obj)
90: {
91: #if defined(PETSC_HAVE_AMS)
92: PF v = (PF) obj;
93: int ierr;
94: #endif
98: #if defined(PETSC_HAVE_AMS)
99: /* if it is already published then return */
100: if (v->amem >=0) return(0);
102: PetscObjectPublishBaseBegin(obj);
103: PetscObjectPublishBaseEnd(obj);
104: #endif
106: return(0);
107: }
109: #undef __FUNCT__
111: /*@C
112: PFCreate - Creates a mathematical function context.
114: Collective on MPI_Comm
116: Input Parameter:
117: + comm - MPI communicator
118: . dimin - dimension of the space you are mapping from
119: - dimout - dimension of the space you are mapping to
121: Output Parameter:
122: . pf - the function context
124: Level: developer
126: .keywords: PF, create, context
128: .seealso: PFSetUp(), PFApply(), PFDestroy(), PFApplyVec()
129: @*/
130: int PFCreate(MPI_Comm comm,int dimin,int dimout,PF *pf)
131: {
132: PF newpf;
137: *pf = PETSC_NULL;
138: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
139: VecInitializePackage(PETSC_NULL);
140: #endif
142: PetscHeaderCreate(newpf,_p_PF,struct _PFOps,PF_COOKIE,-1,"PF",comm,PFDestroy,PFView);
143: PetscLogObjectCreate(newpf);
144: newpf->bops->publish = PFPublish_Petsc;
145: newpf->data = 0;
147: newpf->ops->destroy = 0;
148: newpf->ops->apply = 0;
149: newpf->ops->applyvec = 0;
150: newpf->ops->view = 0;
151: newpf->dimin = dimin;
152: newpf->dimout = dimout;
154: *pf = newpf;
155: PetscPublishAll(pf);
156: return(0);
158: }
160: /* -------------------------------------------------------------------------------*/
162: #undef __FUNCT__
164: /*@
165: PFApplyVec - Applies the mathematical function to a vector
167: Collective on PF
169: Input Parameters:
170: + pf - the function context
171: - x - input vector (or PETSC_NULL for the vector (0,1, .... N-1)
173: Output Parameter:
174: . y - output vector
176: Level: beginner
178: .keywords: PF, apply
180: .seealso: PFApply(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
181: @*/
182: int PFApplyVec(PF pf,Vec x,Vec y)
183: {
184: int ierr,i,rstart,rend,n,p;
185: PetscTruth nox = PETSC_FALSE;
190: if (x) {
192: if (x == y) SETERRQ(PETSC_ERR_ARG_IDN,"x and y must be different vectors");
193: } else {
194: PetscScalar *xx;
196: VecDuplicate(y,&x);
197: nox = PETSC_TRUE;
198: VecGetOwnershipRange(x,&rstart,&rend);
199: VecGetArray(x,&xx);
200: for (i=rstart; i<rend; i++) {
201: xx[i-rstart] = (PetscScalar)i;
202: }
203: VecRestoreArray(x,&xx);
204: }
206: VecGetLocalSize(x,&n);
207: VecGetLocalSize(y,&p);
208: 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);
209: 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);
210: 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);
212: if (pf->ops->applyvec) {
213: (*pf->ops->applyvec)(pf->data,x,y);
214: } else {
215: PetscScalar *xx,*yy;
217: VecGetLocalSize(x,&n);
218: n = n/pf->dimin;
219: VecGetArray(x,&xx);
220: VecGetArray(y,&yy);
221: if (!pf->ops->apply) SETERRQ(1,"No function has been provided for this PF");
222: (*pf->ops->apply)(pf->data,n,xx,yy);
223: VecRestoreArray(x,&xx);
224: VecRestoreArray(y,&yy);
225: }
226: if (nox) {
227: VecDestroy(x);
228: }
229: return(0);
230: }
232: #undef __FUNCT__
234: /*@
235: PFApply - Applies the mathematical function to an array of values.
237: Collective on PF
239: Input Parameters:
240: + pf - the function context
241: . n - number of pointwise function evaluations to perform, each pointwise function evaluation
242: is a function of dimin variables and computes dimout variables where dimin and dimout are defined
243: in the call to PFCreate()
244: - x - input array
246: Output Parameter:
247: . y - output array
249: Level: beginner
251: Notes:
253: .keywords: PF, apply
255: .seealso: PFApplyVec(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
256: @*/
257: int PFApply(PF pf,int n,PetscScalar* x,PetscScalar* y)
258: {
259: int ierr;
263: if (x == y) SETERRQ(PETSC_ERR_ARG_IDN,"x and y must be different arrays");
264: if (!pf->ops->apply) SETERRQ(1,"No function has been provided for this PF");
266: (*pf->ops->apply)(pf->data,n,x,y);
267: return(0);
268: }
270: #undef __FUNCT__
272: /*@
273: PFView - Prints information about a mathematical function
275: Collective on PF unless PetscViewer is PETSC_VIEWER_STDOUT_SELF
277: Input Parameters:
278: + PF - the PF context
279: - viewer - optional visualization context
281: Note:
282: The available visualization contexts include
283: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
284: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
285: output where only the first processor opens
286: the file. All other processors send their
287: data to the first processor to print.
289: The user can open an alternative visualization contexts with
290: PetscViewerASCIIOpen() (output to a specified file).
292: Level: developer
294: .keywords: PF, view
296: .seealso: PetscViewerCreate(), PetscViewerASCIIOpen()
297: @*/
298: int PFView(PF pf,PetscViewer viewer)
299: {
300: PFType cstr;
301: int ierr;
302: PetscTruth isascii;
303: PetscViewerFormat format;
307: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(pf->comm);
311: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
312: if (isascii) {
313: PetscViewerGetFormat(viewer,&format);
314: PetscViewerASCIIPrintf(viewer,"PF Object:n");
315: PFGetType(pf,&cstr);
316: if (cstr) {
317: PetscViewerASCIIPrintf(viewer," type: %sn",cstr);
318: } else {
319: PetscViewerASCIIPrintf(viewer," type: not yet setn");
320: }
321: if (pf->ops->view) {
322: PetscViewerASCIIPushTab(viewer);
323: (*pf->ops->view)(pf->data,viewer);
324: PetscViewerASCIIPopTab(viewer);
325: }
326: } else {
327: SETERRQ1(1,"Viewer type %s not supported by PF",((PetscObject)viewer)->type_name);
328: }
329: return(0);
330: }
332: /*MC
333: PFRegisterDynamic - Adds a method to the mathematical function package.
335: Synopsis:
336: int PFRegisterDynamic(char *name_solver,char *path,char *name_create,int (*routine_create)(PF))
338: Not collective
340: Input Parameters:
341: + name_solver - name of a new user-defined solver
342: . path - path (either absolute or relative) the library containing this solver
343: . name_create - name of routine to create method context
344: - routine_create - routine to create method context
346: Notes:
347: PFRegisterDynamic() may be called multiple times to add several user-defined functions
349: If dynamic libraries are used, then the fourth input argument (routine_create)
350: is ignored.
352: Sample usage:
353: .vb
354: PFRegisterDynamic("my_function","/home/username/my_lib/lib/libO/solaris/mylib",
355: "MyFunctionCreate",MyFunctionSetCreate);
356: .ve
358: Then, your solver can be chosen with the procedural interface via
359: $ PFSetType(pf,"my_function")
360: or at runtime via the option
361: $ -pf_type my_function
363: Level: advanced
365: ${PETSC_ARCH}, ${PETSC_DIR}, ${PETSC_LIB_DIR}, ${BOPT}, or ${any environmental variable}
366: occuring in pathname will be replaced with appropriate values.
368: .keywords: PF, register
370: .seealso: PFRegisterAll(), PFRegisterDestroy(), PFRegister()
371: M*/
373: #undef __FUNCT__
375: int PFRegister(char *sname,char *path,char *name,int (*function)(PF,void*))
376: {
377: int ierr;
378: char fullname[256];
381: PetscFListConcat(path,name,fullname);
382: PetscFListAdd(&PPetscFList,sname,fullname,(void (*)(void))function);
383: return(0);
384: }
388: #undef __FUNCT__
390: /*@C
391: PFGetType - Gets the PF method type and name (as a string) from the PF
392: context.
394: Not Collective
396: Input Parameter:
397: . pf - the function context
399: Output Parameter:
400: . name - name of function
402: Level: intermediate
404: .keywords: PF, get, method, name, type
406: .seealso: PFSetType()
408: @*/
409: int PFGetType(PF pf,PFType *meth)
410: {
412: *meth = (PFType) pf->type_name;
413: return(0);
414: }
417: #undef __FUNCT__
419: /*@C
420: PFSetType - Builds PF for a particular function
422: Collective on PF
424: Input Parameter:
425: + pf - the function context.
426: . type - a known method
427: - ctx - optional type dependent context
429: Options Database Key:
430: . -pf_type <type> - Sets PF type
433: Notes:
434: See "petsc/include/petscpf.h" for available methods (for instance,
435: PFCONSTANT)
437: Level: intermediate
439: .keywords: PF, set, method, type
441: .seealso: PFSet(), PFRegisterDynamic(), PFCreate(), DACreatePF()
443: @*/
444: int PFSetType(PF pf,PFType type,void *ctx)
445: {
446: int ierr,(*r)(PF,void*);
447: PetscTruth match;
453: PetscTypeCompare((PetscObject)pf,type,&match);
454: if (match) return(0);
456: if (pf->ops->destroy) { (*pf->ops->destroy)(pf);}
457: pf->data = 0;
459: /* Get the function pointers for the method requested */
460: if (!PFRegisterAllCalled) {PFRegisterAll(0);}
462: /* Determine the PFCreateXXX routine for a particular function */
463: PetscFListFind(pf->comm,PPetscFList,type,(void (**)(void)) &r);
464: if (!r) SETERRQ1(1,"Unable to find requested PF type %s",type);
466: pf->ops->destroy = 0;
467: pf->ops->view = 0;
468: pf->ops->apply = 0;
469: pf->ops->applyvec = 0;
471: /* Call the PFCreateXXX routine for this particular function */
472: (*r)(pf,ctx);
474: PetscObjectChangeTypeName((PetscObject)pf,type);
475: return(0);
476: }
478: #undef __FUNCT__
480: /*@
481: PFSetFromOptions - Sets PF options from the options database.
483: Collective on PF
485: Input Parameters:
486: . pf - the mathematical function context
488: Options Database Keys:
490: Notes:
491: To see all options, run your program with the -help option
492: or consult the users manual.
494: Level: intermediate
496: .keywords: PF, set, from, options, database
498: .seealso:
499: @*/
500: int PFSetFromOptions(PF pf)
501: {
502: int ierr;
503: char type[256];
504: PetscTruth flg;
509: if (!PFRegisterAllCalled) {PFRegisterAll(0);}
510: PetscOptionsBegin(pf->comm,pf->prefix,"Mathematical functions options","Vec");
511: PetscOptionsList("-pf_type","Type of function","PFSetType",PPetscFList,0,type,256,&flg);
512: if (flg) {
513: PFSetType(pf,type,PETSC_NULL);
514: }
515: if (pf->ops->setfromoptions) {
516: (*pf->ops->setfromoptions)(pf);
517: }
518: PetscOptionsEnd();
520: return(0);
521: }