Actual source code: pf.c
petsc-3.13.6 2020-09-29
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: .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: {
31: pf->data = ctx;
32: pf->ops->destroy = destroy;
33: pf->ops->apply = apply;
34: pf->ops->applyvec = applyvec;
35: pf->ops->view = view;
36: return(0);
37: }
39: /*@C
40: PFDestroy - Destroys PF context that was created with PFCreate().
42: Collective on PF
44: Input Parameter:
45: . pf - the function context
47: Level: beginner
49: .seealso: PFCreate(), PFSet(), PFSetType()
50: @*/
51: PetscErrorCode PFDestroy(PF *pf)
52: {
56: if (!*pf) return(0);
58: if (--((PetscObject)(*pf))->refct > 0) return(0);
60: PFViewFromOptions(*pf,NULL,"-pf_view");
61: /* if memory was published with SAWs then destroy it */
62: PetscObjectSAWsViewOff((PetscObject)*pf);
64: if ((*pf)->ops->destroy) { (*(*pf)->ops->destroy)((*pf)->data);}
65: PetscHeaderDestroy(pf);
66: return(0);
67: }
69: /*@C
70: PFCreate - Creates a mathematical function context.
72: Collective
74: Input Parameter:
75: + comm - MPI communicator
76: . dimin - dimension of the space you are mapping from
77: - dimout - dimension of the space you are mapping to
79: Output Parameter:
80: . pf - the function context
82: Level: developer
84: .seealso: PFSet(), PFApply(), PFDestroy(), PFApplyVec()
85: @*/
86: PetscErrorCode PFCreate(MPI_Comm comm,PetscInt dimin,PetscInt dimout,PF *pf)
87: {
88: PF newpf;
93: *pf = NULL;
94: PFInitializePackage();
96: PetscHeaderCreate(newpf,PF_CLASSID,"PF","Mathematical functions","Vec",comm,PFDestroy,PFView);
97: newpf->data = 0;
98: newpf->ops->destroy = 0;
99: newpf->ops->apply = 0;
100: newpf->ops->applyvec = 0;
101: newpf->ops->view = 0;
102: newpf->dimin = dimin;
103: newpf->dimout = dimout;
105: *pf = newpf;
106: return(0);
108: }
110: /* -------------------------------------------------------------------------------*/
112: /*@
113: PFApplyVec - Applies the mathematical function to a vector
115: Collective on PF
117: Input Parameters:
118: + pf - the function context
119: - x - input vector (or NULL for the vector (0,1, .... N-1)
121: Output Parameter:
122: . y - output vector
124: Level: beginner
126: .seealso: PFApply(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
127: @*/
128: PetscErrorCode PFApplyVec(PF pf,Vec x,Vec y)
129: {
131: PetscInt i,rstart,rend,n,p;
132: PetscBool nox = PETSC_FALSE;
137: if (x) {
139: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"x and y must be different vectors");
140: } else {
141: PetscScalar *xx;
142: PetscInt lsize;
144: VecGetLocalSize(y,&lsize);
145: lsize = pf->dimin*lsize/pf->dimout;
146: VecCreateMPI(PetscObjectComm((PetscObject)y),lsize,PETSC_DETERMINE,&x);
147: nox = PETSC_TRUE;
148: VecGetOwnershipRange(x,&rstart,&rend);
149: VecGetArray(x,&xx);
150: for (i=rstart; i<rend; i++) xx[i-rstart] = (PetscScalar)i;
151: VecRestoreArray(x,&xx);
152: }
154: VecGetLocalSize(x,&n);
155: VecGetLocalSize(y,&p);
156: 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);
157: 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);
158: 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);
160: if (pf->ops->applyvec) {
161: (*pf->ops->applyvec)(pf->data,x,y);
162: } else {
163: PetscScalar *xx,*yy;
165: VecGetLocalSize(x,&n);
166: n = n/pf->dimin;
167: VecGetArray(x,&xx);
168: VecGetArray(y,&yy);
169: if (!pf->ops->apply) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No function has been provided for this PF");
170: (*pf->ops->apply)(pf->data,n,xx,yy);
171: VecRestoreArray(x,&xx);
172: VecRestoreArray(y,&yy);
173: }
174: if (nox) {
175: VecDestroy(&x);
176: }
177: return(0);
178: }
180: /*@
181: PFApply - Applies the mathematical function to an array of values.
183: Collective on PF
185: Input Parameters:
186: + pf - the function context
187: . n - number of pointwise function evaluations to perform, each pointwise function evaluation
188: is a function of dimin variables and computes dimout variables where dimin and dimout are defined
189: in the call to PFCreate()
190: - x - input array
192: Output Parameter:
193: . y - output array
195: Level: beginner
197: Notes:
199: .seealso: PFApplyVec(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
200: @*/
201: PetscErrorCode PFApply(PF pf,PetscInt n,const PetscScalar *x,PetscScalar *y)
202: {
209: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"x and y must be different arrays");
210: if (!pf->ops->apply) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No function has been provided for this PF");
212: (*pf->ops->apply)(pf->data,n,x,y);
213: return(0);
214: }
216: /*@C
217: PFViewFromOptions - View from Options
219: Collective on PF
221: Input Parameters:
222: + A - the PF context
223: . obj - Optional object
224: - name - command line option
226: Level: intermediate
227: .seealso: PF, PFView, PetscObjectViewFromOptions(), PFCreate()
228: @*/
229: PetscErrorCode PFViewFromOptions(PF A,PetscObject obj,const char name[])
230: {
235: PetscObjectViewFromOptions((PetscObject)A,obj,name);
236: return(0);
237: }
239: /*@
240: PFView - Prints information about a mathematical function
242: Collective on PF unless PetscViewer is PETSC_VIEWER_STDOUT_SELF
244: Input Parameters:
245: + PF - the PF context
246: - viewer - optional visualization context
248: Note:
249: The available visualization contexts include
250: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
251: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
252: output where only the first processor opens
253: the file. All other processors send their
254: data to the first processor to print.
256: The user can open an alternative visualization contexts with
257: PetscViewerASCIIOpen() (output to a specified file).
259: Level: developer
261: .seealso: PetscViewerCreate(), PetscViewerASCIIOpen()
262: @*/
263: PetscErrorCode PFView(PF pf,PetscViewer viewer)
264: {
265: PetscErrorCode ierr;
266: PetscBool iascii;
267: PetscViewerFormat format;
271: if (!viewer) {
272: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pf),&viewer);
273: }
277: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
278: if (iascii) {
279: PetscViewerGetFormat(viewer,&format);
280: PetscObjectPrintClassNamePrefixType((PetscObject)pf,viewer);
281: if (pf->ops->view) {
282: PetscViewerASCIIPushTab(viewer);
283: (*pf->ops->view)(pf->data,viewer);
284: PetscViewerASCIIPopTab(viewer);
285: }
286: }
287: return(0);
288: }
291: /*@C
292: PFRegister - Adds a method to the mathematical function package.
294: Not collective
296: Input Parameters:
297: + name_solver - name of a new user-defined solver
298: - routine_create - routine to create method context
300: Notes:
301: PFRegister() may be called multiple times to add several user-defined functions
303: Sample usage:
304: .vb
305: PFRegister("my_function",MyFunctionSetCreate);
306: .ve
308: Then, your solver can be chosen with the procedural interface via
309: $ PFSetType(pf,"my_function")
310: or at runtime via the option
311: $ -pf_type my_function
313: Level: advanced
315: .seealso: PFRegisterAll(), PFRegisterDestroy(), PFRegister()
316: @*/
317: PetscErrorCode PFRegister(const char sname[],PetscErrorCode (*function)(PF,void*))
318: {
322: PFInitializePackage();
323: PetscFunctionListAdd(&PFList,sname,function);
324: return(0);
325: }
327: /*@C
328: PFGetType - Gets the PF method type and name (as a string) from the PF
329: context.
331: Not Collective
333: Input Parameter:
334: . pf - the function context
336: Output Parameter:
337: . type - name of function
339: Level: intermediate
341: .seealso: PFSetType()
343: @*/
344: PetscErrorCode PFGetType(PF pf,PFType *type)
345: {
349: *type = ((PetscObject)pf)->type_name;
350: return(0);
351: }
354: /*@C
355: PFSetType - Builds PF for a particular function
357: Collective on PF
359: Input Parameter:
360: + pf - the function context.
361: . type - a known method
362: - ctx - optional type dependent context
364: Options Database Key:
365: . -pf_type <type> - Sets PF type
368: Notes:
369: See "petsc/include/petscpf.h" for available methods (for instance,
370: PFCONSTANT)
372: Level: intermediate
374: .seealso: PFSet(), PFRegister(), PFCreate(), DMDACreatePF()
376: @*/
377: PetscErrorCode PFSetType(PF pf,PFType type,void *ctx)
378: {
379: PetscErrorCode ierr,(*r)(PF,void*);
380: PetscBool match;
386: PetscObjectTypeCompare((PetscObject)pf,type,&match);
387: if (match) return(0);
389: if (pf->ops->destroy) { (*pf->ops->destroy)(pf);}
390: pf->data = 0;
392: /* Determine the PFCreateXXX routine for a particular function */
393: PetscFunctionListFind(PFList,type,&r);
394: if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested PF type %s",type);
395: pf->ops->destroy = 0;
396: pf->ops->view = 0;
397: pf->ops->apply = 0;
398: pf->ops->applyvec = 0;
400: /* Call the PFCreateXXX routine for this particular function */
401: (*r)(pf,ctx);
403: PetscObjectChangeTypeName((PetscObject)pf,type);
404: return(0);
405: }
407: /*@
408: PFSetFromOptions - Sets PF options from the options database.
410: Collective on PF
412: Input Parameters:
413: . pf - the mathematical function context
415: Options Database Keys:
417: Notes:
418: To see all options, run your program with the -help option
419: or consult the users manual.
421: Level: intermediate
423: .seealso:
424: @*/
425: PetscErrorCode PFSetFromOptions(PF pf)
426: {
428: char type[256];
429: PetscBool flg;
434: PetscObjectOptionsBegin((PetscObject)pf);
435: PetscOptionsFList("-pf_type","Type of function","PFSetType",PFList,0,type,256,&flg);
436: if (flg) {
437: PFSetType(pf,type,NULL);
438: }
439: if (pf->ops->setfromoptions) {
440: (*pf->ops->setfromoptions)(PetscOptionsObject,pf);
441: }
443: /* process any options handlers added with PetscObjectAddOptionsHandler() */
444: PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)pf);
445: PetscOptionsEnd();
446: return(0);
447: }
449: static PetscBool PFPackageInitialized = PETSC_FALSE;
450: /*@C
451: PFFinalizePackage - This function destroys everything in the Petsc interface to Mathematica. It is
452: called from PetscFinalize().
454: Level: developer
456: .seealso: PetscFinalize()
457: @*/
458: PetscErrorCode PFFinalizePackage(void)
459: {
463: PetscFunctionListDestroy(&PFList);
464: PFPackageInitialized = PETSC_FALSE;
465: PFRegisterAllCalled = PETSC_FALSE;
466: return(0);
467: }
469: /*@C
470: PFInitializePackage - This function initializes everything in the PF package. It is called
471: from PetscDLLibraryRegister_petscvec() when using dynamic libraries, and on the first call to PFCreate()
472: when using shared or static libraries.
474: Level: developer
476: .seealso: PetscInitialize()
477: @*/
478: PetscErrorCode PFInitializePackage(void)
479: {
480: char logList[256];
481: PetscBool opt,pkg;
485: if (PFPackageInitialized) return(0);
486: PFPackageInitialized = PETSC_TRUE;
487: /* Register Classes */
488: PetscClassIdRegister("PointFunction",&PF_CLASSID);
489: /* Register Constructors */
490: PFRegisterAll();
491: /* Process Info */
492: {
493: PetscClassId classids[1];
495: classids[0] = PF_CLASSID;
496: PetscInfoProcessClass("pf", 1, classids);
497: }
498: /* Process summary exclusions */
499: PetscOptionsGetString(NULL,NULL,"-log_exclude",logList,sizeof(logList),&opt);
500: if (opt) {
501: PetscStrInList("pf",logList,',',&pkg);
502: if (pkg) {PetscLogEventExcludeClass(PF_CLASSID);}
503: }
504: /* Register package finalizer */
505: PetscRegisterFinalize(PFFinalizePackage);
506: return(0);
507: }