Actual source code: pf.c
petsc-3.6.4 2016-04-12
1: /*
2: The PF mathematical functions interface routines, callable by users.
3: */
4: #include <../src/vec/pf/pfimpl.h> /*I "petscpf.h" I*/
6: PetscClassId PF_CLASSID = 0;
7: PetscFunctionList PFList = NULL; /* list of all registered PD functions */
8: PetscBool PFRegisterAllCalled = PETSC_FALSE;
12: /*@C
13: PFSet - Sets the C/C++/Fortran functions to be used by the PF function
15: Collective on PF
17: Input Parameter:
18: + pf - the function context
19: . apply - function to apply to an array
20: . applyvec - function to apply to a Vec
21: . view - function that prints information about the PF
22: . destroy - function to free the private function context
23: - ctx - private function context
25: Level: beginner
27: .keywords: PF, setting
29: .seealso: PFCreate(), PFDestroy(), PFSetType(), PFApply(), PFApplyVec()
30: @*/
31: 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)
32: {
35: pf->data = ctx;
36: pf->ops->destroy = destroy;
37: pf->ops->apply = apply;
38: pf->ops->applyvec = applyvec;
39: pf->ops->view = view;
40: return(0);
41: }
45: /*@C
46: PFDestroy - Destroys PF context that was created with PFCreate().
48: Collective on PF
50: Input Parameter:
51: . pf - the function context
53: Level: beginner
55: .keywords: PF, destroy
57: .seealso: PFCreate(), PFSet(), PFSetType()
58: @*/
59: PetscErrorCode PFDestroy(PF *pf)
60: {
64: if (!*pf) return(0);
66: if (--((PetscObject)(*pf))->refct > 0) return(0);
68: PFViewFromOptions(*pf,NULL,"-pf_view");
69: /* if memory was published with SAWs then destroy it */
70: PetscObjectSAWsViewOff((PetscObject)*pf);
72: if ((*pf)->ops->destroy) { (*(*pf)->ops->destroy)((*pf)->data);}
73: PetscHeaderDestroy(pf);
74: return(0);
75: }
79: /*@C
80: PFCreate - Creates a mathematical function context.
82: Collective on MPI_Comm
84: Input Parameter:
85: + comm - MPI communicator
86: . dimin - dimension of the space you are mapping from
87: - dimout - dimension of the space you are mapping to
89: Output Parameter:
90: . pf - the function context
92: Level: developer
94: .keywords: PF, create, context
96: .seealso: PFSet(), PFApply(), PFDestroy(), PFApplyVec()
97: @*/
98: PetscErrorCode PFCreate(MPI_Comm comm,PetscInt dimin,PetscInt dimout,PF *pf)
99: {
100: PF newpf;
105: *pf = NULL;
106: PFInitializePackage();
108: PetscHeaderCreate(newpf,PF_CLASSID,"PF","Mathematical functions","Vec",comm,PFDestroy,PFView);
109: newpf->data = 0;
110: newpf->ops->destroy = 0;
111: newpf->ops->apply = 0;
112: newpf->ops->applyvec = 0;
113: newpf->ops->view = 0;
114: newpf->dimin = dimin;
115: newpf->dimout = dimout;
117: *pf = newpf;
118: return(0);
120: }
122: /* -------------------------------------------------------------------------------*/
126: /*@
127: PFApplyVec - Applies the mathematical function to a vector
129: Collective on PF
131: Input Parameters:
132: + pf - the function context
133: - x - input vector (or NULL for the vector (0,1, .... N-1)
135: Output Parameter:
136: . y - output vector
138: Level: beginner
140: .keywords: PF, apply
142: .seealso: PFApply(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
143: @*/
144: PetscErrorCode PFApplyVec(PF pf,Vec x,Vec y)
145: {
147: PetscInt i,rstart,rend,n,p;
148: PetscBool nox = PETSC_FALSE;
153: if (x) {
155: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"x and y must be different vectors");
156: } else {
157: PetscScalar *xx;
158: PetscInt lsize;
160: VecGetLocalSize(y,&lsize);
161: lsize = pf->dimin*lsize/pf->dimout;
162: VecCreateMPI(PetscObjectComm((PetscObject)y),lsize,PETSC_DETERMINE,&x);
163: nox = PETSC_TRUE;
164: VecGetOwnershipRange(x,&rstart,&rend);
165: VecGetArray(x,&xx);
166: for (i=rstart; i<rend; i++) xx[i-rstart] = (PetscScalar)i;
167: VecRestoreArray(x,&xx);
168: }
170: VecGetLocalSize(x,&n);
171: VecGetLocalSize(y,&p);
172: 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);
173: 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);
174: 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);
176: if (pf->ops->applyvec) {
177: (*pf->ops->applyvec)(pf->data,x,y);
178: } else {
179: PetscScalar *xx,*yy;
181: VecGetLocalSize(x,&n);
182: n = n/pf->dimin;
183: VecGetArray(x,&xx);
184: VecGetArray(y,&yy);
185: if (!pf->ops->apply) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No function has been provided for this PF");
186: (*pf->ops->apply)(pf->data,n,xx,yy);
187: VecRestoreArray(x,&xx);
188: VecRestoreArray(y,&yy);
189: }
190: if (nox) {
191: VecDestroy(&x);
192: }
193: return(0);
194: }
198: /*@
199: PFApply - Applies the mathematical function to an array of values.
201: Collective on PF
203: Input Parameters:
204: + pf - the function context
205: . n - number of pointwise function evaluations to perform, each pointwise function evaluation
206: is a function of dimin variables and computes dimout variables where dimin and dimout are defined
207: in the call to PFCreate()
208: - x - input array
210: Output Parameter:
211: . y - output array
213: Level: beginner
215: Notes:
217: .keywords: PF, apply
219: .seealso: PFApplyVec(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
220: @*/
221: PetscErrorCode PFApply(PF pf,PetscInt n,const PetscScalar *x,PetscScalar *y)
222: {
229: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"x and y must be different arrays");
230: if (!pf->ops->apply) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No function has been provided for this PF");
232: (*pf->ops->apply)(pf->data,n,x,y);
233: return(0);
234: }
238: /*@
239: PFView - Prints information about a mathematical function
241: Collective on PF unless PetscViewer is PETSC_VIEWER_STDOUT_SELF
243: Input Parameters:
244: + PF - the PF context
245: - viewer - optional visualization context
247: Note:
248: The available visualization contexts include
249: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
250: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
251: output where only the first processor opens
252: the file. All other processors send their
253: data to the first processor to print.
255: The user can open an alternative visualization contexts with
256: PetscViewerASCIIOpen() (output to a specified file).
258: Level: developer
260: .keywords: PF, view
262: .seealso: PetscViewerCreate(), PetscViewerASCIIOpen()
263: @*/
264: PetscErrorCode PFView(PF pf,PetscViewer viewer)
265: {
266: PetscErrorCode ierr;
267: PetscBool iascii;
268: PetscViewerFormat format;
272: if (!viewer) {
273: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pf),&viewer);
274: }
278: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
279: if (iascii) {
280: PetscViewerGetFormat(viewer,&format);
281: PetscObjectPrintClassNamePrefixType((PetscObject)pf,viewer);
282: if (pf->ops->view) {
283: PetscViewerASCIIPushTab(viewer);
284: (*pf->ops->view)(pf->data,viewer);
285: PetscViewerASCIIPopTab(viewer);
286: }
287: }
288: return(0);
289: }
294: /*@C
295: PFRegister - Adds a method to the mathematical function package.
297: Not collective
299: Input Parameters:
300: + name_solver - name of a new user-defined solver
301: - routine_create - routine to create method context
303: Notes:
304: PFRegister() may be called multiple times to add several user-defined functions
306: Sample usage:
307: .vb
308: PFRegister("my_function",MyFunctionSetCreate);
309: .ve
311: Then, your solver can be chosen with the procedural interface via
312: $ PFSetType(pf,"my_function")
313: or at runtime via the option
314: $ -pf_type my_function
316: Level: advanced
318: .keywords: PF, register
320: .seealso: PFRegisterAll(), PFRegisterDestroy(), PFRegister()
321: @*/
322: PetscErrorCode PFRegister(const char sname[],PetscErrorCode (*function)(PF,void*))
323: {
327: PetscFunctionListAdd(&PFList,sname,function);
328: return(0);
329: }
333: /*@C
334: PFGetType - Gets the PF method type and name (as a string) from the PF
335: context.
337: Not Collective
339: Input Parameter:
340: . pf - the function context
342: Output Parameter:
343: . type - name of function
345: Level: intermediate
347: .keywords: PF, get, method, name, type
349: .seealso: PFSetType()
351: @*/
352: PetscErrorCode PFGetType(PF pf,PFType *type)
353: {
357: *type = ((PetscObject)pf)->type_name;
358: return(0);
359: }
364: /*@C
365: PFSetType - Builds PF for a particular function
367: Collective on PF
369: Input Parameter:
370: + pf - the function context.
371: . type - a known method
372: - ctx - optional type dependent context
374: Options Database Key:
375: . -pf_type <type> - Sets PF type
378: Notes:
379: See "petsc/include/petscpf.h" for available methods (for instance,
380: PFCONSTANT)
382: Level: intermediate
384: .keywords: PF, set, method, type
386: .seealso: PFSet(), PFRegister(), PFCreate(), DMDACreatePF()
388: @*/
389: PetscErrorCode PFSetType(PF pf,PFType type,void *ctx)
390: {
391: PetscErrorCode ierr,(*r)(PF,void*);
392: PetscBool match;
398: PetscObjectTypeCompare((PetscObject)pf,type,&match);
399: if (match) return(0);
401: if (pf->ops->destroy) { (*pf->ops->destroy)(pf);}
402: pf->data = 0;
404: /* Determine the PFCreateXXX routine for a particular function */
405: PetscFunctionListFind(PFList,type,&r);
406: if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested PF type %s",type);
407: pf->ops->destroy = 0;
408: pf->ops->view = 0;
409: pf->ops->apply = 0;
410: pf->ops->applyvec = 0;
412: /* Call the PFCreateXXX routine for this particular function */
413: (*r)(pf,ctx);
415: PetscObjectChangeTypeName((PetscObject)pf,type);
416: return(0);
417: }
421: /*@
422: PFSetFromOptions - Sets PF options from the options database.
424: Collective on PF
426: Input Parameters:
427: . pf - the mathematical function context
429: Options Database Keys:
431: Notes:
432: To see all options, run your program with the -help option
433: or consult the users manual.
435: Level: intermediate
437: .keywords: PF, set, from, options, database
439: .seealso:
440: @*/
441: PetscErrorCode PFSetFromOptions(PF pf)
442: {
444: char type[256];
445: PetscBool flg;
450: PetscObjectOptionsBegin((PetscObject)pf);
451: PetscOptionsFList("-pf_type","Type of function","PFSetType",PFList,0,type,256,&flg);
452: if (flg) {
453: PFSetType(pf,type,NULL);
454: }
455: if (pf->ops->setfromoptions) {
456: (*pf->ops->setfromoptions)(PetscOptionsObject,pf);
457: }
459: /* process any options handlers added with PetscObjectAddOptionsHandler() */
460: PetscObjectProcessOptionsHandlers((PetscObject)pf);
461: PetscOptionsEnd();
462: return(0);
463: }
465: static PetscBool PFPackageInitialized = PETSC_FALSE;
468: /*@C
469: PFFinalizePackage - This function destroys everything in the Petsc interface to Mathematica. It is
470: called from PetscFinalize().
472: Level: developer
474: .keywords: Petsc, destroy, package, mathematica
475: .seealso: PetscFinalize()
476: @*/
477: PetscErrorCode PFFinalizePackage(void)
478: {
482: PetscFunctionListDestroy(&PFList);
483: PFPackageInitialized = PETSC_FALSE;
484: PFRegisterAllCalled = PETSC_FALSE;
485: return(0);
486: }
490: /*@C
491: PFInitializePackage - This function initializes everything in the PF package. It is called
492: from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to PFCreate()
493: when using static libraries.
495: Level: developer
497: .keywords: Vec, initialize, package
498: .seealso: PetscInitialize()
499: @*/
500: PetscErrorCode PFInitializePackage(void)
501: {
502: char logList[256];
503: char *className;
504: PetscBool opt;
508: if (PFPackageInitialized) return(0);
509: PFPackageInitialized = PETSC_TRUE;
510: /* Register Classes */
511: PetscClassIdRegister("PointFunction",&PF_CLASSID);
512: /* Register Constructors */
513: PFRegisterAll();
514: /* Process info exclusions */
515: PetscOptionsGetString(NULL, "-info_exclude", logList, 256, &opt);
516: if (opt) {
517: PetscStrstr(logList, "pf", &className);
518: if (className) {
519: PetscInfoDeactivateClass(PF_CLASSID);
520: }
521: }
522: /* Process summary exclusions */
523: PetscOptionsGetString(NULL, "-log_summary_exclude", logList, 256, &opt);
524: if (opt) {
525: PetscStrstr(logList, "pf", &className);
526: if (className) {
527: PetscLogEventDeactivateClass(PF_CLASSID);
528: }
529: }
530: PetscRegisterFinalize(PFFinalizePackage);
531: return(0);
532: }