1 /*
2 The PF mathematical functions interface routines, callable by users.
3 */
4 #include <../src/vec/pf/pfimpl.h> /*I "petscpf.h" I*/
5
6 PetscClassId PF_CLASSID = 0;
7 PetscFunctionList PFList = NULL; /* list of all registered PD functions */
8 PetscBool PFRegisterAllCalled = PETSC_FALSE;
9
10 /*@C
11 PFSet - Sets the C/C++/Fortran functions to be used by the PF function
12
13 Collective on PF
14
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
22
23 Level: beginner
24
25 .seealso: PFCreate(), PFDestroy(), PFSetType(), PFApply(), PFApplyVec()
26 @*/
PFSet(PF pf,PetscErrorCode (* apply)(void *,PetscInt,const PetscScalar *,PetscScalar *),PetscErrorCode (* applyvec)(void *,Vec,Vec),PetscErrorCode (* view)(void *,PetscViewer),PetscErrorCode (* destroy)(void *),void * ctx)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 {
29 PetscFunctionBegin;
30 PetscValidHeaderSpecific(pf,PF_CLASSID,1);
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 PetscFunctionReturn(0);
37 }
38
39 /*@C
40 PFDestroy - Destroys PF context that was created with PFCreate().
41
42 Collective on PF
43
44 Input Parameter:
45 . pf - the function context
46
47 Level: beginner
48
49 .seealso: PFCreate(), PFSet(), PFSetType()
50 @*/
PFDestroy(PF * pf)51 PetscErrorCode PFDestroy(PF *pf)
52 {
53 PetscErrorCode ierr;
54
55 PetscFunctionBegin;
56 if (!*pf) PetscFunctionReturn(0);
57 PetscValidHeaderSpecific((*pf),PF_CLASSID,1);
58 if (--((PetscObject)(*pf))->refct > 0) PetscFunctionReturn(0);
59
60 ierr = PFViewFromOptions(*pf,NULL,"-pf_view");CHKERRQ(ierr);
61 /* if memory was published with SAWs then destroy it */
62 ierr = PetscObjectSAWsViewOff((PetscObject)*pf);CHKERRQ(ierr);
63
64 if ((*pf)->ops->destroy) {ierr = (*(*pf)->ops->destroy)((*pf)->data);CHKERRQ(ierr);}
65 ierr = PetscHeaderDestroy(pf);CHKERRQ(ierr);
66 PetscFunctionReturn(0);
67 }
68
69 /*@C
70 PFCreate - Creates a mathematical function context.
71
72 Collective
73
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
78
79 Output Parameter:
80 . pf - the function context
81
82 Level: developer
83
84 .seealso: PFSet(), PFApply(), PFDestroy(), PFApplyVec()
85 @*/
PFCreate(MPI_Comm comm,PetscInt dimin,PetscInt dimout,PF * pf)86 PetscErrorCode PFCreate(MPI_Comm comm,PetscInt dimin,PetscInt dimout,PF *pf)
87 {
88 PF newpf;
89 PetscErrorCode ierr;
90
91 PetscFunctionBegin;
92 PetscValidPointer(pf,1);
93 *pf = NULL;
94 ierr = PFInitializePackage();CHKERRQ(ierr);
95
96 ierr = PetscHeaderCreate(newpf,PF_CLASSID,"PF","Mathematical functions","Vec",comm,PFDestroy,PFView);CHKERRQ(ierr);
97 newpf->data = NULL;
98 newpf->ops->destroy = NULL;
99 newpf->ops->apply = NULL;
100 newpf->ops->applyvec = NULL;
101 newpf->ops->view = NULL;
102 newpf->dimin = dimin;
103 newpf->dimout = dimout;
104
105 *pf = newpf;
106 PetscFunctionReturn(0);
107
108 }
109
110 /* -------------------------------------------------------------------------------*/
111
112 /*@
113 PFApplyVec - Applies the mathematical function to a vector
114
115 Collective on PF
116
117 Input Parameters:
118 + pf - the function context
119 - x - input vector (or NULL for the vector (0,1, .... N-1)
120
121 Output Parameter:
122 . y - output vector
123
124 Level: beginner
125
126 .seealso: PFApply(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
127 @*/
PFApplyVec(PF pf,Vec x,Vec y)128 PetscErrorCode PFApplyVec(PF pf,Vec x,Vec y)
129 {
130 PetscErrorCode ierr;
131 PetscInt i,rstart,rend,n,p;
132 PetscBool nox = PETSC_FALSE;
133
134 PetscFunctionBegin;
135 PetscValidHeaderSpecific(pf,PF_CLASSID,1);
136 PetscValidHeaderSpecific(y,VEC_CLASSID,3);
137 if (x) {
138 PetscValidHeaderSpecific(x,VEC_CLASSID,2);
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;
143
144 ierr = VecGetLocalSize(y,&lsize);CHKERRQ(ierr);
145 lsize = pf->dimin*lsize/pf->dimout;
146 ierr = VecCreateMPI(PetscObjectComm((PetscObject)y),lsize,PETSC_DETERMINE,&x);CHKERRQ(ierr);
147 nox = PETSC_TRUE;
148 ierr = VecGetOwnershipRange(x,&rstart,&rend);CHKERRQ(ierr);
149 ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
150 for (i=rstart; i<rend; i++) xx[i-rstart] = (PetscScalar)i;
151 ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
152 }
153
154 ierr = VecGetLocalSize(x,&n);CHKERRQ(ierr);
155 ierr = VecGetLocalSize(y,&p);CHKERRQ(ierr);
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);
159
160 if (pf->ops->applyvec) {
161 ierr = (*pf->ops->applyvec)(pf->data,x,y);CHKERRQ(ierr);
162 } else {
163 PetscScalar *xx,*yy;
164
165 ierr = VecGetLocalSize(x,&n);CHKERRQ(ierr);
166 n = n/pf->dimin;
167 ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
168 ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
169 if (!pf->ops->apply) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No function has been provided for this PF");
170 ierr = (*pf->ops->apply)(pf->data,n,xx,yy);CHKERRQ(ierr);
171 ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
172 ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
173 }
174 if (nox) {
175 ierr = VecDestroy(&x);CHKERRQ(ierr);
176 }
177 PetscFunctionReturn(0);
178 }
179
180 /*@
181 PFApply - Applies the mathematical function to an array of values.
182
183 Collective on PF
184
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
191
192 Output Parameter:
193 . y - output array
194
195 Level: beginner
196
197 Notes:
198
199 .seealso: PFApplyVec(), PFCreate(), PFDestroy(), PFSetType(), PFSet()
200 @*/
PFApply(PF pf,PetscInt n,const PetscScalar * x,PetscScalar * y)201 PetscErrorCode PFApply(PF pf,PetscInt n,const PetscScalar *x,PetscScalar *y)
202 {
203 PetscErrorCode ierr;
204
205 PetscFunctionBegin;
206 PetscValidHeaderSpecific(pf,PF_CLASSID,1);
207 PetscValidScalarPointer(x,2);
208 PetscValidScalarPointer(y,3);
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");
211
212 ierr = (*pf->ops->apply)(pf->data,n,x,y);CHKERRQ(ierr);
213 PetscFunctionReturn(0);
214 }
215
216 /*@C
217 PFViewFromOptions - View from Options
218
219 Collective on PF
220
221 Input Parameters:
222 + A - the PF context
223 . obj - Optional object
224 - name - command line option
225
226 Level: intermediate
227 .seealso: PF, PFView, PetscObjectViewFromOptions(), PFCreate()
228 @*/
PFViewFromOptions(PF A,PetscObject obj,const char name[])229 PetscErrorCode PFViewFromOptions(PF A,PetscObject obj,const char name[])
230 {
231 PetscErrorCode ierr;
232
233 PetscFunctionBegin;
234 PetscValidHeaderSpecific(A,PF_CLASSID,1);
235 ierr = PetscObjectViewFromOptions((PetscObject)A,obj,name);CHKERRQ(ierr);
236 PetscFunctionReturn(0);
237 }
238
239 /*@
240 PFView - Prints information about a mathematical function
241
242 Collective on PF unless PetscViewer is PETSC_VIEWER_STDOUT_SELF
243
244 Input Parameters:
245 + PF - the PF context
246 - viewer - optional visualization context
247
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.
255
256 The user can open an alternative visualization contexts with
257 PetscViewerASCIIOpen() (output to a specified file).
258
259 Level: developer
260
261 .seealso: PetscViewerCreate(), PetscViewerASCIIOpen()
262 @*/
PFView(PF pf,PetscViewer viewer)263 PetscErrorCode PFView(PF pf,PetscViewer viewer)
264 {
265 PetscErrorCode ierr;
266 PetscBool iascii;
267 PetscViewerFormat format;
268
269 PetscFunctionBegin;
270 PetscValidHeaderSpecific(pf,PF_CLASSID,1);
271 if (!viewer) {
272 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pf),&viewer);CHKERRQ(ierr);
273 }
274 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
275 PetscCheckSameComm(pf,1,viewer,2);
276
277 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
278 if (iascii) {
279 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
280 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)pf,viewer);CHKERRQ(ierr);
281 if (pf->ops->view) {
282 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
283 ierr = (*pf->ops->view)(pf->data,viewer);CHKERRQ(ierr);
284 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
285 }
286 }
287 PetscFunctionReturn(0);
288 }
289
290
291 /*@C
292 PFRegister - Adds a method to the mathematical function package.
293
294 Not collective
295
296 Input Parameters:
297 + name_solver - name of a new user-defined solver
298 - routine_create - routine to create method context
299
300 Notes:
301 PFRegister() may be called multiple times to add several user-defined functions
302
303 Sample usage:
304 .vb
305 PFRegister("my_function",MyFunctionSetCreate);
306 .ve
307
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
312
313 Level: advanced
314
315 .seealso: PFRegisterAll(), PFRegisterDestroy(), PFRegister()
316 @*/
PFRegister(const char sname[],PetscErrorCode (* function)(PF,void *))317 PetscErrorCode PFRegister(const char sname[],PetscErrorCode (*function)(PF,void*))
318 {
319 PetscErrorCode ierr;
320
321 PetscFunctionBegin;
322 ierr = PFInitializePackage();CHKERRQ(ierr);
323 ierr = PetscFunctionListAdd(&PFList,sname,function);CHKERRQ(ierr);
324 PetscFunctionReturn(0);
325 }
326
327 /*@C
328 PFGetType - Gets the PF method type and name (as a string) from the PF
329 context.
330
331 Not Collective
332
333 Input Parameter:
334 . pf - the function context
335
336 Output Parameter:
337 . type - name of function
338
339 Level: intermediate
340
341 .seealso: PFSetType()
342
343 @*/
PFGetType(PF pf,PFType * type)344 PetscErrorCode PFGetType(PF pf,PFType *type)
345 {
346 PetscFunctionBegin;
347 PetscValidHeaderSpecific(pf,PF_CLASSID,1);
348 PetscValidPointer(type,2);
349 *type = ((PetscObject)pf)->type_name;
350 PetscFunctionReturn(0);
351 }
352
353
354 /*@C
355 PFSetType - Builds PF for a particular function
356
357 Collective on PF
358
359 Input Parameter:
360 + pf - the function context.
361 . type - a known method
362 - ctx - optional type dependent context
363
364 Options Database Key:
365 . -pf_type <type> - Sets PF type
366
367
368 Notes:
369 See "petsc/include/petscpf.h" for available methods (for instance,
370 PFCONSTANT)
371
372 Level: intermediate
373
374 .seealso: PFSet(), PFRegister(), PFCreate(), DMDACreatePF()
375
376 @*/
PFSetType(PF pf,PFType type,void * ctx)377 PetscErrorCode PFSetType(PF pf,PFType type,void *ctx)
378 {
379 PetscErrorCode ierr,(*r)(PF,void*);
380 PetscBool match;
381
382 PetscFunctionBegin;
383 PetscValidHeaderSpecific(pf,PF_CLASSID,1);
384 PetscValidCharPointer(type,2);
385
386 ierr = PetscObjectTypeCompare((PetscObject)pf,type,&match);CHKERRQ(ierr);
387 if (match) PetscFunctionReturn(0);
388
389 if (pf->ops->destroy) {ierr = (*pf->ops->destroy)(pf);CHKERRQ(ierr);}
390 pf->data = NULL;
391
392 /* Determine the PFCreateXXX routine for a particular function */
393 ierr = PetscFunctionListFind(PFList,type,&r);CHKERRQ(ierr);
394 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested PF type %s",type);
395 pf->ops->destroy = NULL;
396 pf->ops->view = NULL;
397 pf->ops->apply = NULL;
398 pf->ops->applyvec = NULL;
399
400 /* Call the PFCreateXXX routine for this particular function */
401 ierr = (*r)(pf,ctx);CHKERRQ(ierr);
402
403 ierr = PetscObjectChangeTypeName((PetscObject)pf,type);CHKERRQ(ierr);
404 PetscFunctionReturn(0);
405 }
406
407 /*@
408 PFSetFromOptions - Sets PF options from the options database.
409
410 Collective on PF
411
412 Input Parameters:
413 . pf - the mathematical function context
414
415 Options Database Keys:
416
417 Notes:
418 To see all options, run your program with the -help option
419 or consult the users manual.
420
421 Level: intermediate
422
423 .seealso:
424 @*/
PFSetFromOptions(PF pf)425 PetscErrorCode PFSetFromOptions(PF pf)
426 {
427 PetscErrorCode ierr;
428 char type[256];
429 PetscBool flg;
430
431 PetscFunctionBegin;
432 PetscValidHeaderSpecific(pf,PF_CLASSID,1);
433
434 ierr = PetscObjectOptionsBegin((PetscObject)pf);CHKERRQ(ierr);
435 ierr = PetscOptionsFList("-pf_type","Type of function","PFSetType",PFList,NULL,type,256,&flg);CHKERRQ(ierr);
436 if (flg) {
437 ierr = PFSetType(pf,type,NULL);CHKERRQ(ierr);
438 }
439 if (pf->ops->setfromoptions) {
440 ierr = (*pf->ops->setfromoptions)(PetscOptionsObject,pf);CHKERRQ(ierr);
441 }
442
443 /* process any options handlers added with PetscObjectAddOptionsHandler() */
444 ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)pf);CHKERRQ(ierr);
445 ierr = PetscOptionsEnd();CHKERRQ(ierr);
446 PetscFunctionReturn(0);
447 }
448
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().
453
454 Level: developer
455
456 .seealso: PetscFinalize()
457 @*/
PFFinalizePackage(void)458 PetscErrorCode PFFinalizePackage(void)
459 {
460 PetscErrorCode ierr;
461
462 PetscFunctionBegin;
463 ierr = PetscFunctionListDestroy(&PFList);CHKERRQ(ierr);
464 PFPackageInitialized = PETSC_FALSE;
465 PFRegisterAllCalled = PETSC_FALSE;
466 PetscFunctionReturn(0);
467 }
468
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.
473
474 Level: developer
475
476 .seealso: PetscInitialize()
477 @*/
PFInitializePackage(void)478 PetscErrorCode PFInitializePackage(void)
479 {
480 char logList[256];
481 PetscBool opt,pkg;
482 PetscErrorCode ierr;
483
484 PetscFunctionBegin;
485 if (PFPackageInitialized) PetscFunctionReturn(0);
486 PFPackageInitialized = PETSC_TRUE;
487 /* Register Classes */
488 ierr = PetscClassIdRegister("PointFunction",&PF_CLASSID);CHKERRQ(ierr);
489 /* Register Constructors */
490 ierr = PFRegisterAll();CHKERRQ(ierr);
491 /* Process Info */
492 {
493 PetscClassId classids[1];
494
495 classids[0] = PF_CLASSID;
496 ierr = PetscInfoProcessClass("pf", 1, classids);CHKERRQ(ierr);
497 }
498 /* Process summary exclusions */
499 ierr = PetscOptionsGetString(NULL,NULL,"-log_exclude",logList,sizeof(logList),&opt);CHKERRQ(ierr);
500 if (opt) {
501 ierr = PetscStrInList("pf",logList,',',&pkg);CHKERRQ(ierr);
502 if (pkg) {ierr = PetscLogEventExcludeClass(PF_CLASSID);CHKERRQ(ierr);}
503 }
504 /* Register package finalizer */
505 ierr = PetscRegisterFinalize(PFFinalizePackage);CHKERRQ(ierr);
506 PetscFunctionReturn(0);
507 }
508
509
510
511
512
513
514
515
516
517