Actual source code: pf.c
petsc-3.8.4 2018-03-24
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 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: 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)
30: {
33: pf->data = ctx;
34: pf->ops->destroy = destroy;
35: pf->ops->apply = apply;
36: pf->ops->applyvec = applyvec;
37: pf->ops->view = view;
38: return(0);
39: }
41: /*@C
42: PFDestroy - Destroys PF context that was created with PFCreate().
44: Collective on PF
46: Input Parameter:
47: . pf - the function context
49: Level: beginner
51: .keywords: PF, destroy
53: .seealso: PFCreate(), PFSet(), PFSetType()
54: @*/
55: PetscErrorCode PFDestroy(PF *pf)
56: {
60: if (!*pf) return(0);
62: if (--((PetscObject)(*pf))->refct > 0) return(0);
64: PFViewFromOptions(*pf,NULL,"-pf_view");
65: /* if memory was published with SAWs then destroy it */
66: PetscObjectSAWsViewOff((PetscObject)*pf);
68: if ((*pf)->ops->destroy) { (*(*pf)->ops->destroy)((*pf)->data);}
69: PetscHeaderDestroy(pf);
70: return(0);
71: }
73: /*@C
74: PFCreate - Creates a mathematical function context.
76: Collective on MPI_Comm
78: Input Parameter:
79: + comm - MPI communicator
80: . dimin - dimension of the space you are mapping from
81: - dimout - dimension of the space you are mapping to
83: Output Parameter:
84: . pf - the function context
86: Level: developer
88: .keywords: PF, create, context
90: .seealso: PFSet(), PFApply(), PFDestroy(), PFApplyVec()
91: @*/
92: PetscErrorCode PFCreate(MPI_Comm comm,PetscInt dimin,PetscInt dimout,PF *pf)
93: {
94: PF newpf;
99: *pf = NULL;
100: PFInitializePackage();
102: PetscHeaderCreate(newpf,PF_CLASSID,"PF","Mathematical functions","Vec",comm,PFDestroy,PFView);
103: newpf->data = 0;
104: newpf->ops->destroy = 0;
105: newpf->ops->apply = 0;
106: newpf->ops->applyvec = 0;
107: newpf->ops->view = 0;
108: newpf->dimin = dimin;
109: newpf->dimout = dimout;
111: *pf = newpf;
112: return(0);
114: }
116: /* -------------------------------------------------------------------------------*/
118: /*@
119: PFApplyVec - Applies the mathematical function to a vector
121: Collective on PF
123: Input Parameters:
124: + pf - the function context
125: - x - input vector (or NULL for the vector (0,1, .... N-1)
127: Output Parameter:
128: . y - output vector
130: Level: beginner
132: .keywords: PF, apply
134: .seealso: PFApply(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
135: @*/
136: PetscErrorCode PFApplyVec(PF pf,Vec x,Vec y)
137: {
139: PetscInt i,rstart,rend,n,p;
140: PetscBool nox = PETSC_FALSE;
145: if (x) {
147: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"x and y must be different vectors");
148: } else {
149: PetscScalar *xx;
150: PetscInt lsize;
152: VecGetLocalSize(y,&lsize);
153: lsize = pf->dimin*lsize/pf->dimout;
154: VecCreateMPI(PetscObjectComm((PetscObject)y),lsize,PETSC_DETERMINE,&x);
155: nox = PETSC_TRUE;
156: VecGetOwnershipRange(x,&rstart,&rend);
157: VecGetArray(x,&xx);
158: for (i=rstart; i<rend; i++) xx[i-rstart] = (PetscScalar)i;
159: VecRestoreArray(x,&xx);
160: }
162: VecGetLocalSize(x,&n);
163: VecGetLocalSize(y,&p);
164: if ((pf->dimin*(n/pf->dimin)) != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Local input vector length %D not divisible by dimin %D of function",n,pf->dimin);
165: if ((pf->dimout*(p/pf->dimout)) != p) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Local output vector length %D not divisible by dimout %D of function",p,pf->dimout);
166: if ((n/pf->dimin) != (p/pf->dimout)) SETERRQ4(PETSC_COMM_SELF,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);
168: if (pf->ops->applyvec) {
169: (*pf->ops->applyvec)(pf->data,x,y);
170: } else {
171: PetscScalar *xx,*yy;
173: VecGetLocalSize(x,&n);
174: n = n/pf->dimin;
175: VecGetArray(x,&xx);
176: VecGetArray(y,&yy);
177: if (!pf->ops->apply) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No function has been provided for this PF");
178: (*pf->ops->apply)(pf->data,n,xx,yy);
179: VecRestoreArray(x,&xx);
180: VecRestoreArray(y,&yy);
181: }
182: if (nox) {
183: VecDestroy(&x);
184: }
185: return(0);
186: }
188: /*@
189: PFApply - Applies the mathematical function to an array of values.
191: Collective on PF
193: Input Parameters:
194: + pf - the function context
195: . n - number of pointwise function evaluations to perform, each pointwise function evaluation
196: is a function of dimin variables and computes dimout variables where dimin and dimout are defined
197: in the call to PFCreate()
198: - x - input array
200: Output Parameter:
201: . y - output array
203: Level: beginner
205: Notes:
207: .keywords: PF, apply
209: .seealso: PFApplyVec(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
210: @*/
211: PetscErrorCode PFApply(PF pf,PetscInt n,const PetscScalar *x,PetscScalar *y)
212: {
219: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"x and y must be different arrays");
220: if (!pf->ops->apply) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No function has been provided for this PF");
222: (*pf->ops->apply)(pf->data,n,x,y);
223: return(0);
224: }
226: /*@
227: PFView - Prints information about a mathematical function
229: Collective on PF unless PetscViewer is PETSC_VIEWER_STDOUT_SELF
231: Input Parameters:
232: + PF - the PF context
233: - viewer - optional visualization context
235: Note:
236: The available visualization contexts include
237: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
238: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
239: output where only the first processor opens
240: the file. All other processors send their
241: data to the first processor to print.
243: The user can open an alternative visualization contexts with
244: PetscViewerASCIIOpen() (output to a specified file).
246: Level: developer
248: .keywords: PF, view
250: .seealso: PetscViewerCreate(), PetscViewerASCIIOpen()
251: @*/
252: PetscErrorCode PFView(PF pf,PetscViewer viewer)
253: {
254: PetscErrorCode ierr;
255: PetscBool iascii;
256: PetscViewerFormat format;
260: if (!viewer) {
261: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pf),&viewer);
262: }
266: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
267: if (iascii) {
268: PetscViewerGetFormat(viewer,&format);
269: PetscObjectPrintClassNamePrefixType((PetscObject)pf,viewer);
270: if (pf->ops->view) {
271: PetscViewerASCIIPushTab(viewer);
272: (*pf->ops->view)(pf->data,viewer);
273: PetscViewerASCIIPopTab(viewer);
274: }
275: }
276: return(0);
277: }
280: /*@C
281: PFRegister - Adds a method to the mathematical function package.
283: Not collective
285: Input Parameters:
286: + name_solver - name of a new user-defined solver
287: - routine_create - routine to create method context
289: Notes:
290: PFRegister() may be called multiple times to add several user-defined functions
292: Sample usage:
293: .vb
294: PFRegister("my_function",MyFunctionSetCreate);
295: .ve
297: Then, your solver can be chosen with the procedural interface via
298: $ PFSetType(pf,"my_function")
299: or at runtime via the option
300: $ -pf_type my_function
302: Level: advanced
304: .keywords: PF, register
306: .seealso: PFRegisterAll(), PFRegisterDestroy(), PFRegister()
307: @*/
308: PetscErrorCode PFRegister(const char sname[],PetscErrorCode (*function)(PF,void*))
309: {
313: PetscFunctionListAdd(&PFList,sname,function);
314: return(0);
315: }
317: /*@C
318: PFGetType - Gets the PF method type and name (as a string) from the PF
319: context.
321: Not Collective
323: Input Parameter:
324: . pf - the function context
326: Output Parameter:
327: . type - name of function
329: Level: intermediate
331: .keywords: PF, get, method, name, type
333: .seealso: PFSetType()
335: @*/
336: PetscErrorCode PFGetType(PF pf,PFType *type)
337: {
341: *type = ((PetscObject)pf)->type_name;
342: return(0);
343: }
346: /*@C
347: PFSetType - Builds PF for a particular function
349: Collective on PF
351: Input Parameter:
352: + pf - the function context.
353: . type - a known method
354: - ctx - optional type dependent context
356: Options Database Key:
357: . -pf_type <type> - Sets PF type
360: Notes:
361: See "petsc/include/petscpf.h" for available methods (for instance,
362: PFCONSTANT)
364: Level: intermediate
366: .keywords: PF, set, method, type
368: .seealso: PFSet(), PFRegister(), PFCreate(), DMDACreatePF()
370: @*/
371: PetscErrorCode PFSetType(PF pf,PFType type,void *ctx)
372: {
373: PetscErrorCode ierr,(*r)(PF,void*);
374: PetscBool match;
380: PetscObjectTypeCompare((PetscObject)pf,type,&match);
381: if (match) return(0);
383: if (pf->ops->destroy) { (*pf->ops->destroy)(pf);}
384: pf->data = 0;
386: /* Determine the PFCreateXXX routine for a particular function */
387: PetscFunctionListFind(PFList,type,&r);
388: if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested PF type %s",type);
389: pf->ops->destroy = 0;
390: pf->ops->view = 0;
391: pf->ops->apply = 0;
392: pf->ops->applyvec = 0;
394: /* Call the PFCreateXXX routine for this particular function */
395: (*r)(pf,ctx);
397: PetscObjectChangeTypeName((PetscObject)pf,type);
398: return(0);
399: }
401: /*@
402: PFSetFromOptions - Sets PF options from the options database.
404: Collective on PF
406: Input Parameters:
407: . pf - the mathematical function context
409: Options Database Keys:
411: Notes:
412: To see all options, run your program with the -help option
413: or consult the users manual.
415: Level: intermediate
417: .keywords: PF, set, from, options, database
419: .seealso:
420: @*/
421: PetscErrorCode PFSetFromOptions(PF pf)
422: {
424: char type[256];
425: PetscBool flg;
430: PetscObjectOptionsBegin((PetscObject)pf);
431: PetscOptionsFList("-pf_type","Type of function","PFSetType",PFList,0,type,256,&flg);
432: if (flg) {
433: PFSetType(pf,type,NULL);
434: }
435: if (pf->ops->setfromoptions) {
436: (*pf->ops->setfromoptions)(PetscOptionsObject,pf);
437: }
439: /* process any options handlers added with PetscObjectAddOptionsHandler() */
440: PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)pf);
441: PetscOptionsEnd();
442: return(0);
443: }
445: static PetscBool PFPackageInitialized = PETSC_FALSE;
446: /*@C
447: PFFinalizePackage - This function destroys everything in the Petsc interface to Mathematica. It is
448: called from PetscFinalize().
450: Level: developer
452: .keywords: Petsc, destroy, package, mathematica
453: .seealso: PetscFinalize()
454: @*/
455: PetscErrorCode PFFinalizePackage(void)
456: {
460: PetscFunctionListDestroy(&PFList);
461: PFPackageInitialized = PETSC_FALSE;
462: PFRegisterAllCalled = PETSC_FALSE;
463: return(0);
464: }
466: /*@C
467: PFInitializePackage - This function initializes everything in the PF package. It is called
468: from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to PFCreate()
469: when using static libraries.
471: Level: developer
473: .keywords: Vec, initialize, package
474: .seealso: PetscInitialize()
475: @*/
476: PetscErrorCode PFInitializePackage(void)
477: {
478: char logList[256];
479: char *className;
480: PetscBool opt;
484: if (PFPackageInitialized) return(0);
485: PFPackageInitialized = PETSC_TRUE;
486: /* Register Classes */
487: PetscClassIdRegister("PointFunction",&PF_CLASSID);
488: /* Register Constructors */
489: PFRegisterAll();
490: /* Process info exclusions */
491: PetscOptionsGetString(NULL,NULL, "-info_exclude", logList, 256, &opt);
492: if (opt) {
493: PetscStrstr(logList, "pf", &className);
494: if (className) {
495: PetscInfoDeactivateClass(PF_CLASSID);
496: }
497: }
498: /* Process summary exclusions */
499: PetscOptionsGetString(NULL,NULL, "-log_exclude", logList, 256, &opt);
500: if (opt) {
501: PetscStrstr(logList, "pf", &className);
502: if (className) {
503: PetscLogEventDeactivateClass(PF_CLASSID);
504: }
505: }
506: PetscRegisterFinalize(PFFinalizePackage);
507: return(0);
508: }