Actual source code: pf.c
1: #define PETSCVEC_DLL
2: /*
3: The PF mathematical functions interface routines, callable by users.
4: */
5: #include ../src/vec/pf/pfimpl.h
7: /* Logging support */
8: PetscCookie PF_COOKIE = 0;
10: PetscFList PFList = PETSC_NULL; /* list of all registered PD functions */
11: PetscTruth PFRegisterAllCalled = PETSC_FALSE;
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: PetscErrorCode PFSet(PF pf,PetscErrorCode (*apply)(void*,PetscInt,PetscScalar*,PetscScalar*),PetscErrorCode (*applyvec)(void*,Vec,Vec),PetscErrorCode (*view)(void*,PetscViewer),PetscErrorCode (*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: }
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: PetscErrorCode PFDestroy(PF pf)
65: {
67: PetscTruth flg = PETSC_FALSE;
71: if (--((PetscObject)pf)->refct > 0) return(0);
73: PetscOptionsGetTruth(((PetscObject)pf)->prefix,"-pf_view",&flg,PETSC_NULL);
74: if (flg) {
75: PetscViewer viewer;
76: PetscViewerASCIIGetStdout(((PetscObject)pf)->comm,&viewer);
77: PFView(pf,viewer);
78: }
80: /* if memory was published with AMS then destroy it */
81: PetscObjectDepublish(pf);
83: if (pf->ops->destroy) { (*pf->ops->destroy)(pf->data);}
84: PetscHeaderDestroy(pf);
85: return(0);
86: }
90: /*@C
91: PFCreate - Creates a mathematical function context.
93: Collective on MPI_Comm
95: Input Parameter:
96: + comm - MPI communicator
97: . dimin - dimension of the space you are mapping from
98: - dimout - dimension of the space you are mapping to
100: Output Parameter:
101: . pf - the function context
103: Level: developer
105: .keywords: PF, create, context
107: .seealso: PFSetUp(), PFApply(), PFDestroy(), PFApplyVec()
108: @*/
109: PetscErrorCode PFCreate(MPI_Comm comm,PetscInt dimin,PetscInt dimout,PF *pf)
110: {
111: PF newpf;
116: *pf = PETSC_NULL;
117: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
118: PFInitializePackage(PETSC_NULL);
119: #endif
121: PetscHeaderCreate(newpf,_p_PF,struct _PFOps,PF_COOKIE,-1,"PF",comm,PFDestroy,PFView);
122: newpf->data = 0;
124: newpf->ops->destroy = 0;
125: newpf->ops->apply = 0;
126: newpf->ops->applyvec = 0;
127: newpf->ops->view = 0;
128: newpf->dimin = dimin;
129: newpf->dimout = dimout;
131: *pf = newpf;
132: PetscPublishAll(pf);
133: return(0);
135: }
137: /* -------------------------------------------------------------------------------*/
141: /*@
142: PFApplyVec - Applies the mathematical function to a vector
144: Collective on PF
146: Input Parameters:
147: + pf - the function context
148: - x - input vector (or PETSC_NULL for the vector (0,1, .... N-1)
150: Output Parameter:
151: . y - output vector
153: Level: beginner
155: .keywords: PF, apply
157: .seealso: PFApply(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
158: @*/
159: PetscErrorCode PFApplyVec(PF pf,Vec x,Vec y)
160: {
162: PetscInt i,rstart,rend,n,p;
163: PetscTruth nox = PETSC_FALSE;
168: if (x) {
170: if (x == y) SETERRQ(PETSC_ERR_ARG_IDN,"x and y must be different vectors");
171: } else {
172: PetscScalar *xx;
174: VecDuplicate(y,&x);
175: nox = PETSC_TRUE;
176: VecGetOwnershipRange(x,&rstart,&rend);
177: VecGetArray(x,&xx);
178: for (i=rstart; i<rend; i++) {
179: xx[i-rstart] = (PetscScalar)i;
180: }
181: VecRestoreArray(x,&xx);
182: }
184: VecGetLocalSize(x,&n);
185: VecGetLocalSize(y,&p);
186: if ((pf->dimin*(n/pf->dimin)) != n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Local input vector length %D not divisible by dimin %D of function",n,pf->dimin);
187: if ((pf->dimout*(p/pf->dimout)) != p) SETERRQ2(PETSC_ERR_ARG_SIZ,"Local output vector length %D not divisible by dimout %D of function",p,pf->dimout);
188: if ((n/pf->dimin) != (p/pf->dimout)) SETERRQ4(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);
190: if (pf->ops->applyvec) {
191: (*pf->ops->applyvec)(pf->data,x,y);
192: } else {
193: PetscScalar *xx,*yy;
195: VecGetLocalSize(x,&n);
196: n = n/pf->dimin;
197: VecGetArray(x,&xx);
198: VecGetArray(y,&yy);
199: if (!pf->ops->apply) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No function has been provided for this PF");
200: (*pf->ops->apply)(pf->data,n,xx,yy);
201: VecRestoreArray(x,&xx);
202: VecRestoreArray(y,&yy);
203: }
204: if (nox) {
205: VecDestroy(x);
206: }
207: return(0);
208: }
212: /*@
213: PFApply - Applies the mathematical function to an array of values.
215: Collective on PF
217: Input Parameters:
218: + pf - the function context
219: . n - number of pointwise function evaluations to perform, each pointwise function evaluation
220: is a function of dimin variables and computes dimout variables where dimin and dimout are defined
221: in the call to PFCreate()
222: - x - input array
224: Output Parameter:
225: . y - output array
227: Level: beginner
229: Notes:
231: .keywords: PF, apply
233: .seealso: PFApplyVec(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
234: @*/
235: PetscErrorCode PFApply(PF pf,PetscInt n,PetscScalar* x,PetscScalar* y)
236: {
243: if (x == y) SETERRQ(PETSC_ERR_ARG_IDN,"x and y must be different arrays");
244: if (!pf->ops->apply) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No function has been provided for this PF");
246: (*pf->ops->apply)(pf->data,n,x,y);
247: return(0);
248: }
252: /*@
253: PFView - Prints information about a mathematical function
255: Collective on PF unless PetscViewer is PETSC_VIEWER_STDOUT_SELF
257: Input Parameters:
258: + PF - the PF context
259: - viewer - optional visualization context
261: Note:
262: The available visualization contexts include
263: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
264: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
265: output where only the first processor opens
266: the file. All other processors send their
267: data to the first processor to print.
269: The user can open an alternative visualization contexts with
270: PetscViewerASCIIOpen() (output to a specified file).
272: Level: developer
274: .keywords: PF, view
276: .seealso: PetscViewerCreate(), PetscViewerASCIIOpen()
277: @*/
278: PetscErrorCode PFView(PF pf,PetscViewer viewer)
279: {
280: const PFType cstr;
281: PetscErrorCode ierr;
282: PetscTruth iascii;
283: PetscViewerFormat format;
287: if (!viewer) {
288: PetscViewerASCIIGetStdout(((PetscObject)pf)->comm,&viewer);
289: }
293: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
294: if (iascii) {
295: PetscViewerGetFormat(viewer,&format);
296: PetscViewerASCIIPrintf(viewer,"PF Object:\n");
297: PFGetType(pf,&cstr);
298: if (cstr) {
299: PetscViewerASCIIPrintf(viewer," type: %s\n",cstr);
300: } else {
301: PetscViewerASCIIPrintf(viewer," type: not yet set\n");
302: }
303: if (pf->ops->view) {
304: PetscViewerASCIIPushTab(viewer);
305: (*pf->ops->view)(pf->data,viewer);
306: PetscViewerASCIIPopTab(viewer);
307: }
308: } else {
309: SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by PF",((PetscObject)viewer)->type_name);
310: }
311: return(0);
312: }
314: /*MC
315: PFRegisterDynamic - Adds a method to the mathematical function package.
317: Synopsis:
318: PetscErrorCode PFRegisterDynamic(char *name_solver,char *path,char *name_create,PetscErrorCode (*routine_create)(PF))
320: Not collective
322: Input Parameters:
323: + name_solver - name of a new user-defined solver
324: . path - path (either absolute or relative) the library containing this solver
325: . name_create - name of routine to create method context
326: - routine_create - routine to create method context
328: Notes:
329: PFRegisterDynamic() may be called multiple times to add several user-defined functions
331: If dynamic libraries are used, then the fourth input argument (routine_create)
332: is ignored.
334: Sample usage:
335: .vb
336: PFRegisterDynamic("my_function","/home/username/my_lib/lib/libO/solaris/mylib",
337: "MyFunctionCreate",MyFunctionSetCreate);
338: .ve
340: Then, your solver can be chosen with the procedural interface via
341: $ PFSetType(pf,"my_function")
342: or at runtime via the option
343: $ -pf_type my_function
345: Level: advanced
347: ${PETSC_ARCH}, ${PETSC_DIR}, ${PETSC_LIB_DIR}, or ${any environmental variable}
348: occuring in pathname will be replaced with appropriate values.
350: .keywords: PF, register
352: .seealso: PFRegisterAll(), PFRegisterDestroy(), PFRegister()
353: M*/
357: PetscErrorCode PFRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(PF,void*))
358: {
360: char fullname[PETSC_MAX_PATH_LEN];
363: PetscFListConcat(path,name,fullname);
364: PetscFListAdd(&PFList,sname,fullname,(void (*)(void))function);
365: return(0);
366: }
370: /*@C
371: PFGetType - Gets the PF method type and name (as a string) from the PF
372: context.
374: Not Collective
376: Input Parameter:
377: . pf - the function context
379: Output Parameter:
380: . type - name of function
382: Level: intermediate
384: .keywords: PF, get, method, name, type
386: .seealso: PFSetType()
388: @*/
389: PetscErrorCode PFGetType(PF pf,const PFType *type)
390: {
394: *type = ((PetscObject)pf)->type_name;
395: return(0);
396: }
401: /*@C
402: PFSetType - Builds PF for a particular function
404: Collective on PF
406: Input Parameter:
407: + pf - the function context.
408: . type - a known method
409: - ctx - optional type dependent context
411: Options Database Key:
412: . -pf_type <type> - Sets PF type
415: Notes:
416: See "petsc/include/petscpf.h" for available methods (for instance,
417: PFCONSTANT)
419: Level: intermediate
421: .keywords: PF, set, method, type
423: .seealso: PFSet(), PFRegisterDynamic(), PFCreate(), DACreatePF()
425: @*/
426: PetscErrorCode PFSetType(PF pf,const PFType type,void *ctx)
427: {
428: PetscErrorCode ierr,(*r)(PF,void*);
429: PetscTruth match;
435: PetscTypeCompare((PetscObject)pf,type,&match);
436: if (match) return(0);
438: if (pf->ops->destroy) { (*pf->ops->destroy)(pf);}
439: pf->data = 0;
441: /* Determine the PFCreateXXX routine for a particular function */
442: PetscFListFind(PFList,((PetscObject)pf)->comm,type,(void (**)(void)) &r);
443: if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested PF type %s",type);
444: pf->ops->destroy = 0;
445: pf->ops->view = 0;
446: pf->ops->apply = 0;
447: pf->ops->applyvec = 0;
449: /* Call the PFCreateXXX routine for this particular function */
450: (*r)(pf,ctx);
452: PetscObjectChangeTypeName((PetscObject)pf,type);
453: return(0);
454: }
458: /*@
459: PFSetFromOptions - Sets PF options from the options database.
461: Collective on PF
463: Input Parameters:
464: . pf - the mathematical function context
466: Options Database Keys:
468: Notes:
469: To see all options, run your program with the -help option
470: or consult the users manual.
472: Level: intermediate
474: .keywords: PF, set, from, options, database
476: .seealso:
477: @*/
478: PetscErrorCode PFSetFromOptions(PF pf)
479: {
481: char type[256];
482: PetscTruth flg;
487: PetscOptionsBegin(((PetscObject)pf)->comm,((PetscObject)pf)->prefix,"Mathematical functions options","Vec");
488: PetscOptionsList("-pf_type","Type of function","PFSetType",PFList,0,type,256,&flg);
489: if (flg) {
490: PFSetType(pf,type,PETSC_NULL);
491: }
492: if (pf->ops->setfromoptions) {
493: (*pf->ops->setfromoptions)(pf);
494: }
495: PetscOptionsEnd();
497: return(0);
498: }
500: static PetscTruth PFPackageInitialized = PETSC_FALSE;
503: /*@C
504: PFFinalizePackage - This function destroys everything in the Petsc interface to Mathematica. It is
505: called from PetscFinalize().
507: Level: developer
509: .keywords: Petsc, destroy, package, mathematica
510: .seealso: PetscFinalize()
511: @*/
512: PetscErrorCode PFFinalizePackage(void)
513: {
515: PFPackageInitialized = PETSC_FALSE;
516: PFList = PETSC_NULL;
517: PFRegisterAllCalled = PETSC_FALSE;
518: return(0);
519: }
523: /*@C
524: PFInitializePackage - This function initializes everything in the PF package. It is called
525: from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to PFCreate()
526: when using static libraries.
528: Input Parameter:
529: . path - The dynamic library path, or PETSC_NULL
531: Level: developer
533: .keywords: Vec, initialize, package
534: .seealso: PetscInitialize()
535: @*/
536: PetscErrorCode PFInitializePackage(const char path[])
537: {
538: char logList[256];
539: char *className;
540: PetscTruth opt;
541: PetscErrorCode ierr;
544: if (PFPackageInitialized) return(0);
545: PFPackageInitialized = PETSC_TRUE;
546: /* Register Classes */
547: PetscCookieRegister("PointFunction",&PF_COOKIE);
548: /* Register Constructors */
549: PFRegisterAll(path);
550: /* Process info exclusions */
551: PetscOptionsGetString(PETSC_NULL, "-info_exclude", logList, 256, &opt);
552: if (opt) {
553: PetscStrstr(logList, "pf", &className);
554: if (className) {
555: PetscInfoDeactivateClass(PF_COOKIE);
556: }
557: }
558: /* Process summary exclusions */
559: PetscOptionsGetString(PETSC_NULL, "-log_summary_exclude", logList, 256, &opt);
560: if (opt) {
561: PetscStrstr(logList, "pf", &className);
562: if (className) {
563: PetscLogEventDeactivateClass(PF_COOKIE);
564: }
565: }
566: PetscRegisterFinalize(PFFinalizePackage);
567: return(0);
568: }