Actual source code: pf.c
1: /*
2: The PF mathematical functions interface routines, callable by users.
3: */
4: #include <../src/vec/pf/pfimpl.h>
6: PetscClassId PF_CLASSID = 0;
7: PetscFunctionList PFList = NULL; /* list of all registered PD functions */
8: PetscBool PFRegisterAllCalled = PETSC_FALSE;
10: /*@C
11: PFSet - Sets the C/C++/Fortran functions to be used by the PF function
13: Collective
15: Input Parameters:
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: .seealso: `PFCreate()`, `PFDestroy()`, `PFSetType()`, `PFApply()`, `PFApplyVec()`
26: @*/
27: 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)
28: {
30: pf->data = ctx;
31: pf->ops->destroy = destroy;
32: pf->ops->apply = apply;
33: pf->ops->applyvec = applyvec;
34: pf->ops->view = view;
35: return 0;
36: }
38: /*@C
39: PFDestroy - Destroys `PF` context that was created with `PFCreate()`.
41: Collective
43: Input Parameter:
44: . pf - the function context
46: Level: beginner
48: .seealso: `PFCreate()`, `PFSet()`, `PFSetType()`
49: @*/
50: PetscErrorCode PFDestroy(PF *pf)
51: {
52: if (!*pf) return 0;
54: if (--((PetscObject)(*pf))->refct > 0) return 0;
56: PFViewFromOptions(*pf, NULL, "-pf_view");
57: /* if memory was published with SAWs then destroy it */
58: PetscObjectSAWsViewOff((PetscObject)*pf);
60: if ((*pf)->ops->destroy) (*(*pf)->ops->destroy)((*pf)->data);
61: PetscHeaderDestroy(pf);
62: return 0;
63: }
65: /*@C
66: PFCreate - Creates a mathematical function context.
68: Collective
70: Input Parameters:
71: + comm - MPI communicator
72: . dimin - dimension of the space you are mapping from
73: - dimout - dimension of the space you are mapping to
75: Output Parameter:
76: . pf - the function context
78: Level: developer
80: .seealso: `PFSet()`, `PFApply()`, `PFDestroy()`, `PFApplyVec()`
81: @*/
82: PetscErrorCode PFCreate(MPI_Comm comm, PetscInt dimin, PetscInt dimout, PF *pf)
83: {
84: PF newpf;
87: *pf = NULL;
88: PFInitializePackage();
90: PetscHeaderCreate(newpf, PF_CLASSID, "PF", "Mathematical functions", "Vec", comm, PFDestroy, PFView);
91: newpf->data = NULL;
92: newpf->ops->destroy = NULL;
93: newpf->ops->apply = NULL;
94: newpf->ops->applyvec = NULL;
95: newpf->ops->view = NULL;
96: newpf->dimin = dimin;
97: newpf->dimout = dimout;
99: *pf = newpf;
100: return 0;
101: }
103: /* -------------------------------------------------------------------------------*/
105: /*@
106: PFApplyVec - Applies the mathematical function to a vector
108: Collective
110: Input Parameters:
111: + pf - the function context
112: - x - input vector (or NULL for the vector (0,1, .... N-1)
114: Output Parameter:
115: . y - output vector
117: Level: beginner
119: .seealso: `PFApply()`, `PFCreate()`, `PFDestroy()`, `PFSetType()`, `PFSet()`
120: @*/
121: PetscErrorCode PFApplyVec(PF pf, Vec x, Vec y)
122: {
123: PetscInt i, rstart, rend, n, p;
124: PetscBool nox = PETSC_FALSE;
128: if (x) {
131: } else {
132: PetscScalar *xx;
133: PetscInt lsize;
135: VecGetLocalSize(y, &lsize);
136: lsize = pf->dimin * lsize / pf->dimout;
137: VecCreateMPI(PetscObjectComm((PetscObject)y), lsize, PETSC_DETERMINE, &x);
138: nox = PETSC_TRUE;
139: VecGetOwnershipRange(x, &rstart, &rend);
140: VecGetArray(x, &xx);
141: for (i = rstart; i < rend; i++) xx[i - rstart] = (PetscScalar)i;
142: VecRestoreArray(x, &xx);
143: }
145: VecGetLocalSize(x, &n);
146: VecGetLocalSize(y, &p);
151: if (pf->ops->applyvec) (*pf->ops->applyvec)(pf->data, x, y);
152: else {
153: PetscScalar *xx, *yy;
155: VecGetLocalSize(x, &n);
156: n = n / pf->dimin;
157: VecGetArray(x, &xx);
158: VecGetArray(y, &yy);
159: (*pf->ops->apply)(pf->data, n, xx, yy);
160: VecRestoreArray(x, &xx);
161: VecRestoreArray(y, &yy);
162: }
163: if (nox) VecDestroy(&x);
164: return 0;
165: }
167: /*@
168: PFApply - Applies the mathematical function to an array of values.
170: Collective
172: Input Parameters:
173: + pf - the function context
174: . n - number of pointwise function evaluations to perform, each pointwise function evaluation
175: is a function of dimin variables and computes dimout variables where dimin and dimout are defined
176: in the call to PFCreate()
177: - x - input array
179: Output Parameter:
180: . y - output array
182: Level: beginner
184: Notes:
186: .seealso: `PFApplyVec()`, `PFCreate()`, `PFDestroy()`, `PFSetType()`, `PFSet()`
187: @*/
188: PetscErrorCode PFApply(PF pf, PetscInt n, const PetscScalar *x, PetscScalar *y)
189: {
195: (*pf->ops->apply)(pf->data, n, x, y);
196: return 0;
197: }
199: /*@C
200: PFViewFromOptions - View from Options
202: Collective
204: Input Parameters:
205: + A - the PF context
206: . obj - Optional object
207: - name - command line option
209: Level: intermediate
210: .seealso: `PF`, `PFView`, `PetscObjectViewFromOptions()`, `PFCreate()`
211: @*/
212: PetscErrorCode PFViewFromOptions(PF A, PetscObject obj, const char name[])
213: {
215: PetscObjectViewFromOptions((PetscObject)A, obj, name);
216: return 0;
217: }
219: /*@
220: PFView - Prints information about a mathematical function
222: Collective on PF unless PetscViewer is PETSC_VIEWER_STDOUT_SELF
224: Input Parameters:
225: + PF - the PF context
226: - viewer - optional visualization context
228: Note:
229: The available visualization contexts include
230: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
231: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
232: output where only the first processor opens
233: the file. All other processors send their
234: data to the first processor to print.
236: The user can open an alternative visualization contexts with
237: PetscViewerASCIIOpen() (output to a specified file).
239: Level: developer
241: .seealso: `PetscViewerCreate()`, `PetscViewerASCIIOpen()`
242: @*/
243: PetscErrorCode PFView(PF pf, PetscViewer viewer)
244: {
245: PetscBool iascii;
246: PetscViewerFormat format;
249: if (!viewer) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pf), &viewer);
253: PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);
254: if (iascii) {
255: PetscViewerGetFormat(viewer, &format);
256: PetscObjectPrintClassNamePrefixType((PetscObject)pf, viewer);
257: if (pf->ops->view) {
258: PetscViewerASCIIPushTab(viewer);
259: (*pf->ops->view)(pf->data, viewer);
260: PetscViewerASCIIPopTab(viewer);
261: }
262: }
263: return 0;
264: }
266: /*@C
267: PFRegister - Adds a method to the mathematical function package.
269: Not collective
271: Input Parameters:
272: + name_solver - name of a new user-defined solver
273: - routine_create - routine to create method context
275: Notes:
276: PFRegister() may be called multiple times to add several user-defined functions
278: Sample usage:
279: .vb
280: PFRegister("my_function",MyFunctionSetCreate);
281: .ve
283: Then, your solver can be chosen with the procedural interface via
284: $ PFSetType(pf,"my_function")
285: or at runtime via the option
286: $ -pf_type my_function
288: Level: advanced
290: .seealso: `PFRegisterAll()`, `PFRegisterDestroy()`, `PFRegister()`
291: @*/
292: PetscErrorCode PFRegister(const char sname[], PetscErrorCode (*function)(PF, void *))
293: {
294: PFInitializePackage();
295: PetscFunctionListAdd(&PFList, sname, function);
296: return 0;
297: }
299: /*@C
300: PFGetType - Gets the PF method type and name (as a string) from the PF
301: context.
303: Not Collective
305: Input Parameter:
306: . pf - the function context
308: Output Parameter:
309: . type - name of function
311: Level: intermediate
313: .seealso: `PFSetType()`
315: @*/
316: PetscErrorCode PFGetType(PF pf, PFType *type)
317: {
320: *type = ((PetscObject)pf)->type_name;
321: return 0;
322: }
324: /*@C
325: PFSetType - Builds PF for a particular function
327: Collective
329: Input Parameters:
330: + pf - the function context.
331: . type - a known method
332: - ctx - optional type dependent context
334: Options Database Key:
335: . -pf_type <type> - Sets PF type
337: Notes:
338: See "petsc/include/petscpf.h" for available methods (for instance,
339: PFCONSTANT)
341: Level: intermediate
343: .seealso: `PFSet()`, `PFRegister()`, `PFCreate()`, `DMDACreatePF()`
345: @*/
346: PetscErrorCode PFSetType(PF pf, PFType type, void *ctx)
347: {
348: PetscBool match;
349: PetscErrorCode (*r)(PF, void *);
354: PetscObjectTypeCompare((PetscObject)pf, type, &match);
355: if (match) return 0;
357: PetscTryTypeMethod(pf, destroy);
358: pf->data = NULL;
360: /* Determine the PFCreateXXX routine for a particular function */
361: PetscFunctionListFind(PFList, type, &r);
363: pf->ops->destroy = NULL;
364: pf->ops->view = NULL;
365: pf->ops->apply = NULL;
366: pf->ops->applyvec = NULL;
368: /* Call the PFCreateXXX routine for this particular function */
369: (*r)(pf, ctx);
371: PetscObjectChangeTypeName((PetscObject)pf, type);
372: return 0;
373: }
375: /*@
376: PFSetFromOptions - Sets PF options from the options database.
378: Collective
380: Input Parameters:
381: . pf - the mathematical function context
383: Options Database Keys:
385: Notes:
386: To see all options, run your program with the -help option
387: or consult the users manual.
389: Level: intermediate
391: .seealso:
392: @*/
393: PetscErrorCode PFSetFromOptions(PF pf)
394: {
395: char type[256];
396: PetscBool flg;
400: PetscObjectOptionsBegin((PetscObject)pf);
401: PetscOptionsFList("-pf_type", "Type of function", "PFSetType", PFList, NULL, type, 256, &flg);
402: if (flg) PFSetType(pf, type, NULL);
403: PetscTryTypeMethod(pf, setfromoptions, PetscOptionsObject);
405: /* process any options handlers added with PetscObjectAddOptionsHandler() */
406: PetscObjectProcessOptionsHandlers((PetscObject)pf, PetscOptionsObject);
407: PetscOptionsEnd();
408: return 0;
409: }
411: static PetscBool PFPackageInitialized = PETSC_FALSE;
412: /*@C
413: PFFinalizePackage - This function destroys everything in the Petsc interface to Mathematica. It is
414: called from PetscFinalize().
416: Level: developer
418: .seealso: `PetscFinalize()`
419: @*/
420: PetscErrorCode PFFinalizePackage(void)
421: {
422: PetscFunctionListDestroy(&PFList);
423: PFPackageInitialized = PETSC_FALSE;
424: PFRegisterAllCalled = PETSC_FALSE;
425: return 0;
426: }
428: /*@C
429: PFInitializePackage - This function initializes everything in the PF package. It is called
430: from PetscDLLibraryRegister_petscvec() when using dynamic libraries, and on the first call to PFCreate()
431: when using shared or static libraries.
433: Level: developer
435: .seealso: `PetscInitialize()`
436: @*/
437: PetscErrorCode PFInitializePackage(void)
438: {
439: char logList[256];
440: PetscBool opt, pkg;
442: if (PFPackageInitialized) return 0;
443: PFPackageInitialized = PETSC_TRUE;
444: /* Register Classes */
445: PetscClassIdRegister("PointFunction", &PF_CLASSID);
446: /* Register Constructors */
447: PFRegisterAll();
448: /* Process Info */
449: {
450: PetscClassId classids[1];
452: classids[0] = PF_CLASSID;
453: PetscInfoProcessClass("pf", 1, classids);
454: }
455: /* Process summary exclusions */
456: PetscOptionsGetString(NULL, NULL, "-log_exclude", logList, sizeof(logList), &opt);
457: if (opt) {
458: PetscStrInList("pf", logList, ',', &pkg);
459: if (pkg) PetscLogEventExcludeClass(PF_CLASSID);
460: }
461: /* Register package finalizer */
462: PetscRegisterFinalize(PFFinalizePackage);
463: return 0;
464: }