Actual source code: pf.c
petsc-3.4.5 2014-06-29
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: {
62: PetscBool flg = PETSC_FALSE;
65: if (!*pf) return(0);
67: if (--((PetscObject)(*pf))->refct > 0) return(0);
69: PetscOptionsGetBool(((PetscObject)(*pf))->prefix,"-pf_view",&flg,NULL);
70: if (flg) {
71: PetscViewer viewer;
72: PetscViewerASCIIGetStdout(((PetscObject)(*pf))->comm,&viewer);
73: PFView((*pf),viewer);
74: }
76: /* if memory was published with AMS then destroy it */
77: PetscObjectAMSViewOff((PetscObject)*pf);
79: if ((*pf)->ops->destroy) { (*(*pf)->ops->destroy)((*pf)->data);}
80: PetscHeaderDestroy(pf);
81: return(0);
82: }
86: /*@C
87: PFCreate - Creates a mathematical function context.
89: Collective on MPI_Comm
91: Input Parameter:
92: + comm - MPI communicator
93: . dimin - dimension of the space you are mapping from
94: - dimout - dimension of the space you are mapping to
96: Output Parameter:
97: . pf - the function context
99: Level: developer
101: .keywords: PF, create, context
103: .seealso: PFSet(), PFApply(), PFDestroy(), PFApplyVec()
104: @*/
105: PetscErrorCode PFCreate(MPI_Comm comm,PetscInt dimin,PetscInt dimout,PF *pf)
106: {
107: PF newpf;
112: *pf = NULL;
113: #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
114: PFInitializePackage();
115: #endif
117: PetscHeaderCreate(newpf,_p_PF,struct _PFOps,PF_CLASSID,"PF","Mathematical functions","Vec",comm,PFDestroy,PFView);
118: newpf->data = 0;
119: newpf->ops->destroy = 0;
120: newpf->ops->apply = 0;
121: newpf->ops->applyvec = 0;
122: newpf->ops->view = 0;
123: newpf->dimin = dimin;
124: newpf->dimout = dimout;
126: *pf = newpf;
127: return(0);
129: }
131: /* -------------------------------------------------------------------------------*/
135: /*@
136: PFApplyVec - Applies the mathematical function to a vector
138: Collective on PF
140: Input Parameters:
141: + pf - the function context
142: - x - input vector (or NULL for the vector (0,1, .... N-1)
144: Output Parameter:
145: . y - output vector
147: Level: beginner
149: .keywords: PF, apply
151: .seealso: PFApply(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
152: @*/
153: PetscErrorCode PFApplyVec(PF pf,Vec x,Vec y)
154: {
156: PetscInt i,rstart,rend,n,p;
157: PetscBool nox = PETSC_FALSE;
162: if (x) {
164: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"x and y must be different vectors");
165: } else {
166: PetscScalar *xx;
167: PetscInt lsize;
169: VecGetLocalSize(y,&lsize);
170: lsize = pf->dimin*lsize/pf->dimout;
171: VecCreateMPI(PetscObjectComm((PetscObject)y),lsize,PETSC_DETERMINE,&x);
172: nox = PETSC_TRUE;
173: VecGetOwnershipRange(x,&rstart,&rend);
174: VecGetArray(x,&xx);
175: for (i=rstart; i<rend; i++) xx[i-rstart] = (PetscScalar)i;
176: VecRestoreArray(x,&xx);
177: }
179: VecGetLocalSize(x,&n);
180: VecGetLocalSize(y,&p);
181: 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);
182: 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);
183: 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);
185: if (pf->ops->applyvec) {
186: (*pf->ops->applyvec)(pf->data,x,y);
187: } else {
188: PetscScalar *xx,*yy;
190: VecGetLocalSize(x,&n);
191: n = n/pf->dimin;
192: VecGetArray(x,&xx);
193: VecGetArray(y,&yy);
194: if (!pf->ops->apply) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No function has been provided for this PF");
195: (*pf->ops->apply)(pf->data,n,xx,yy);
196: VecRestoreArray(x,&xx);
197: VecRestoreArray(y,&yy);
198: }
199: if (nox) {
200: VecDestroy(&x);
201: }
202: return(0);
203: }
207: /*@
208: PFApply - Applies the mathematical function to an array of values.
210: Collective on PF
212: Input Parameters:
213: + pf - the function context
214: . n - number of pointwise function evaluations to perform, each pointwise function evaluation
215: is a function of dimin variables and computes dimout variables where dimin and dimout are defined
216: in the call to PFCreate()
217: - x - input array
219: Output Parameter:
220: . y - output array
222: Level: beginner
224: Notes:
226: .keywords: PF, apply
228: .seealso: PFApplyVec(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
229: @*/
230: PetscErrorCode PFApply(PF pf,PetscInt n,const PetscScalar *x,PetscScalar *y)
231: {
238: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"x and y must be different arrays");
239: if (!pf->ops->apply) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No function has been provided for this PF");
241: (*pf->ops->apply)(pf->data,n,x,y);
242: return(0);
243: }
247: /*@
248: PFView - Prints information about a mathematical function
250: Collective on PF unless PetscViewer is PETSC_VIEWER_STDOUT_SELF
252: Input Parameters:
253: + PF - the PF context
254: - viewer - optional visualization context
256: Note:
257: The available visualization contexts include
258: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
259: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
260: output where only the first processor opens
261: the file. All other processors send their
262: data to the first processor to print.
264: The user can open an alternative visualization contexts with
265: PetscViewerASCIIOpen() (output to a specified file).
267: Level: developer
269: .keywords: PF, view
271: .seealso: PetscViewerCreate(), PetscViewerASCIIOpen()
272: @*/
273: PetscErrorCode PFView(PF pf,PetscViewer viewer)
274: {
275: PetscErrorCode ierr;
276: PetscBool iascii;
277: PetscViewerFormat format;
281: if (!viewer) {
282: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pf),&viewer);
283: }
287: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
288: if (iascii) {
289: PetscViewerGetFormat(viewer,&format);
290: PetscObjectPrintClassNamePrefixType((PetscObject)pf,viewer,"PF Object");
291: if (pf->ops->view) {
292: PetscViewerASCIIPushTab(viewer);
293: (*pf->ops->view)(pf->data,viewer);
294: PetscViewerASCIIPopTab(viewer);
295: }
296: }
297: return(0);
298: }
303: /*@C
304: PFRegister - Adds a method to the mathematical function package.
306: Not collective
308: Input Parameters:
309: + name_solver - name of a new user-defined solver
310: - routine_create - routine to create method context
312: Notes:
313: PFRegister() may be called multiple times to add several user-defined functions
315: Sample usage:
316: .vb
317: PFRegister("my_function",MyFunctionSetCreate);
318: .ve
320: Then, your solver can be chosen with the procedural interface via
321: $ PFSetType(pf,"my_function")
322: or at runtime via the option
323: $ -pf_type my_function
325: Level: advanced
327: .keywords: PF, register
329: .seealso: PFRegisterAll(), PFRegisterDestroy(), PFRegister()
330: @*/
331: PetscErrorCode PFRegister(const char sname[],PetscErrorCode (*function)(PF,void*))
332: {
336: PetscFunctionListAdd(&PFList,sname,function);
337: return(0);
338: }
342: /*@C
343: PFGetType - Gets the PF method type and name (as a string) from the PF
344: context.
346: Not Collective
348: Input Parameter:
349: . pf - the function context
351: Output Parameter:
352: . type - name of function
354: Level: intermediate
356: .keywords: PF, get, method, name, type
358: .seealso: PFSetType()
360: @*/
361: PetscErrorCode PFGetType(PF pf,PFType *type)
362: {
366: *type = ((PetscObject)pf)->type_name;
367: return(0);
368: }
373: /*@C
374: PFSetType - Builds PF for a particular function
376: Collective on PF
378: Input Parameter:
379: + pf - the function context.
380: . type - a known method
381: - ctx - optional type dependent context
383: Options Database Key:
384: . -pf_type <type> - Sets PF type
387: Notes:
388: See "petsc/include/petscpf.h" for available methods (for instance,
389: PFCONSTANT)
391: Level: intermediate
393: .keywords: PF, set, method, type
395: .seealso: PFSet(), PFRegister(), PFCreate(), DMDACreatePF()
397: @*/
398: PetscErrorCode PFSetType(PF pf,PFType type,void *ctx)
399: {
400: PetscErrorCode ierr,(*r)(PF,void*);
401: PetscBool match;
407: PetscObjectTypeCompare((PetscObject)pf,type,&match);
408: if (match) return(0);
410: if (pf->ops->destroy) { (*pf->ops->destroy)(pf);}
411: pf->data = 0;
413: /* Determine the PFCreateXXX routine for a particular function */
414: PetscFunctionListFind(PFList,type,&r);
415: if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested PF type %s",type);
416: pf->ops->destroy = 0;
417: pf->ops->view = 0;
418: pf->ops->apply = 0;
419: pf->ops->applyvec = 0;
421: /* Call the PFCreateXXX routine for this particular function */
422: (*r)(pf,ctx);
424: PetscObjectChangeTypeName((PetscObject)pf,type);
425: return(0);
426: }
430: /*@
431: PFSetFromOptions - Sets PF options from the options database.
433: Collective on PF
435: Input Parameters:
436: . pf - the mathematical function context
438: Options Database Keys:
440: Notes:
441: To see all options, run your program with the -help option
442: or consult the users manual.
444: Level: intermediate
446: .keywords: PF, set, from, options, database
448: .seealso:
449: @*/
450: PetscErrorCode PFSetFromOptions(PF pf)
451: {
453: char type[256];
454: PetscBool flg;
459: PetscObjectOptionsBegin((PetscObject)pf);
460: PetscOptionsList("-pf_type","Type of function","PFSetType",PFList,0,type,256,&flg);
461: if (flg) {
462: PFSetType(pf,type,NULL);
463: }
464: if (pf->ops->setfromoptions) {
465: (*pf->ops->setfromoptions)(pf);
466: }
468: /* process any options handlers added with PetscObjectAddOptionsHandler() */
469: PetscObjectProcessOptionsHandlers((PetscObject)pf);
470: PetscOptionsEnd();
471: return(0);
472: }
474: static PetscBool PFPackageInitialized = PETSC_FALSE;
477: /*@C
478: PFFinalizePackage - This function destroys everything in the Petsc interface to Mathematica. It is
479: called from PetscFinalize().
481: Level: developer
483: .keywords: Petsc, destroy, package, mathematica
484: .seealso: PetscFinalize()
485: @*/
486: PetscErrorCode PFFinalizePackage(void)
487: {
491: PetscFunctionListDestroy(&PFList);
492: PFPackageInitialized = PETSC_FALSE;
493: PFRegisterAllCalled = PETSC_FALSE;
494: return(0);
495: }
499: /*@C
500: PFInitializePackage - This function initializes everything in the PF package. It is called
501: from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to PFCreate()
502: when using static libraries.
504: Level: developer
506: .keywords: Vec, initialize, package
507: .seealso: PetscInitialize()
508: @*/
509: PetscErrorCode PFInitializePackage(void)
510: {
511: char logList[256];
512: char *className;
513: PetscBool opt;
517: if (PFPackageInitialized) return(0);
518: PFPackageInitialized = PETSC_TRUE;
519: /* Register Classes */
520: PetscClassIdRegister("PointFunction",&PF_CLASSID);
521: /* Register Constructors */
522: PFRegisterAll();
523: /* Process info exclusions */
524: PetscOptionsGetString(NULL, "-info_exclude", logList, 256, &opt);
525: if (opt) {
526: PetscStrstr(logList, "pf", &className);
527: if (className) {
528: PetscInfoDeactivateClass(PF_CLASSID);
529: }
530: }
531: /* Process summary exclusions */
532: PetscOptionsGetString(NULL, "-log_summary_exclude", logList, 256, &opt);
533: if (opt) {
534: PetscStrstr(logList, "pf", &className);
535: if (className) {
536: PetscLogEventDeactivateClass(PF_CLASSID);
537: }
538: }
539: PetscRegisterFinalize(PFFinalizePackage);
540: return(0);
541: }