1: /*
2: Basic routines
4: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5: SLEPc - Scalable Library for Eigenvalue Problem Computations
6: Copyright (c) 2002-2014, Universitat Politecnica de Valencia, Spain
8: This file is part of SLEPc.
10: SLEPc is free software: you can redistribute it and/or modify it under the
11: terms of version 3 of the GNU Lesser General Public License as published by
12: the Free Software Foundation.
14: SLEPc is distributed in the hope that it will be useful, but WITHOUT ANY
15: WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16: FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
17: more details.
19: You should have received a copy of the GNU Lesser General Public License
20: along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
21: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
22: */
24: #include <slepc-private/fnimpl.h> /*I "slepcfn.h" I*/
26: PetscFunctionList FNList = 0;
27: PetscBool FNRegisterAllCalled = PETSC_FALSE;
28: PetscClassId FN_CLASSID = 0;
29: static PetscBool FNPackageInitialized = PETSC_FALSE;
33: /*@C
34: FNFinalizePackage - This function destroys everything in the Slepc interface
35: to the FN package. It is called from SlepcFinalize().
37: Level: developer
39: .seealso: SlepcFinalize()
40: @*/
41: PetscErrorCode FNFinalizePackage(void) 42: {
46: PetscFunctionListDestroy(&FNList);
47: FNPackageInitialized = PETSC_FALSE;
48: FNRegisterAllCalled = PETSC_FALSE;
49: return(0);
50: }
54: /*@C
55: FNInitializePackage - This function initializes everything in the FN package.
56: It is called from PetscDLLibraryRegister() when using dynamic libraries, and
57: on the first call to FNCreate() when using static libraries.
59: Level: developer
61: .seealso: SlepcInitialize()
62: @*/
63: PetscErrorCode FNInitializePackage(void) 64: {
65: char logList[256];
66: char *className;
67: PetscBool opt;
68: PetscErrorCode ierr;
71: if (FNPackageInitialized) return(0);
72: FNPackageInitialized = PETSC_TRUE;
73: /* Register Classes */
74: PetscClassIdRegister("Math function",&FN_CLASSID);
75: /* Register Constructors */
76: FNRegisterAll();
77: /* Process info exclusions */
78: PetscOptionsGetString(NULL,"-info_exclude",logList,256,&opt);
79: if (opt) {
80: PetscStrstr(logList,"fn",&className);
81: if (className) {
82: PetscInfoDeactivateClass(FN_CLASSID);
83: }
84: }
85: /* Process summary exclusions */
86: PetscOptionsGetString(NULL,"-log_summary_exclude",logList,256,&opt);
87: if (opt) {
88: PetscStrstr(logList,"fn",&className);
89: if (className) {
90: PetscLogEventDeactivateClass(FN_CLASSID);
91: }
92: }
93: PetscRegisterFinalize(FNFinalizePackage);
94: return(0);
95: }
99: /*@C
100: FNCreate - Creates an FN context.
102: Collective on MPI_Comm
104: Input Parameter:
105: . comm - MPI communicator
107: Output Parameter:
108: . newfn - location to put the FN context
110: Level: beginner
112: .seealso: FNDestroy(), FN113: @*/
114: PetscErrorCode FNCreate(MPI_Comm comm,FN *newfn)115: {
116: FN fn;
121: *newfn = 0;
122: FNInitializePackage();
123: SlepcHeaderCreate(fn,_p_FN,struct _FNOps,FN_CLASSID,"FN","Math Function","FN",comm,FNDestroy,FNView);
124: fn->na = 0;
125: fn->alpha = NULL;
126: fn->nb = 0;
127: fn->beta = NULL;
129: *newfn = fn;
130: return(0);
131: }
135: /*@C
136: FNSetOptionsPrefix - Sets the prefix used for searching for all
137: FN options in the database.
139: Logically Collective on FN141: Input Parameters:
142: + fn - the math function context
143: - prefix - the prefix string to prepend to all FN option requests
145: Notes:
146: A hyphen (-) must NOT be given at the beginning of the prefix name.
147: The first character of all runtime options is AUTOMATICALLY the
148: hyphen.
150: Level: advanced
152: .seealso: FNAppendOptionsPrefix()
153: @*/
154: PetscErrorCode FNSetOptionsPrefix(FN fn,const char *prefix)155: {
160: PetscObjectSetOptionsPrefix((PetscObject)fn,prefix);
161: return(0);
162: }
166: /*@C
167: FNAppendOptionsPrefix - Appends to the prefix used for searching for all
168: FN options in the database.
170: Logically Collective on FN172: Input Parameters:
173: + fn - the math function context
174: - prefix - the prefix string to prepend to all FN option requests
176: Notes:
177: A hyphen (-) must NOT be given at the beginning of the prefix name.
178: The first character of all runtime options is AUTOMATICALLY the hyphen.
180: Level: advanced
182: .seealso: FNSetOptionsPrefix()
183: @*/
184: PetscErrorCode FNAppendOptionsPrefix(FN fn,const char *prefix)185: {
190: PetscObjectAppendOptionsPrefix((PetscObject)fn,prefix);
191: return(0);
192: }
196: /*@C
197: FNGetOptionsPrefix - Gets the prefix used for searching for all
198: FN options in the database.
200: Not Collective
202: Input Parameters:
203: . fn - the math function context
205: Output Parameters:
206: . prefix - pointer to the prefix string used is returned
208: Notes: On the fortran side, the user should pass in a string 'prefix' of
209: sufficient length to hold the prefix.
211: Level: advanced
213: .seealso: FNSetOptionsPrefix(), FNAppendOptionsPrefix()
214: @*/
215: PetscErrorCode FNGetOptionsPrefix(FN fn,const char *prefix[])216: {
222: PetscObjectGetOptionsPrefix((PetscObject)fn,prefix);
223: return(0);
224: }
228: /*@C
229: FNSetType - Selects the type for the FN object.
231: Logically Collective on FN233: Input Parameter:
234: + fn - the math function context
235: - type - a known type
237: Notes:
238: The default is FNRATIONAL, which includes polynomials as a particular
239: case as well as simple functions such as f(x)=x and f(x)=constant.
241: Level: intermediate
243: .seealso: FNGetType()
244: @*/
245: PetscErrorCode FNSetType(FN fn,FNType type)246: {
247: PetscErrorCode ierr,(*r)(FN);
248: PetscBool match;
254: PetscObjectTypeCompare((PetscObject)fn,type,&match);
255: if (match) return(0);
257: PetscFunctionListFind(FNList,type,&r);
258: if (!r) SETERRQ1(PetscObjectComm((PetscObject)fn),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested FN type %s",type);
260: PetscMemzero(fn->ops,sizeof(struct _FNOps));
262: PetscObjectChangeTypeName((PetscObject)fn,type);
263: (*r)(fn);
264: return(0);
265: }
269: /*@C
270: FNGetType - Gets the FN type name (as a string) from the FN context.
272: Not Collective
274: Input Parameter:
275: . fn - the math function context
277: Output Parameter:
278: . name - name of the math function
280: Level: intermediate
282: .seealso: FNSetType()
283: @*/
284: PetscErrorCode FNGetType(FN fn,FNType *type)285: {
289: *type = ((PetscObject)fn)->type_name;
290: return(0);
291: }
295: /*@
296: FNSetParameters - Sets the parameters that define the matematical function.
298: Logically Collective on FN300: Input Parameters:
301: + fn - the math function context
302: . na - number of parameters in the first group
303: . alpha - first group of parameters (array of scalar values)
304: . nb - number of parameters in the second group
305: - beta - second group of parameters (array of scalar values)
307: Notes:
308: In a rational function r(x) = p(x)/q(x), where p(x) and q(x) are polynomials,
309: the parameters alpha and beta represent the coefficients of p(x) and q(x),
310: respectively. Hence, p(x) is of degree na-1 and q(x) of degree nb-1.
311: If nb is zero, then the function is assumed to be polynomial, r(x) = p(x).
313: In other functions the parameters have other meanings.
315: In polynomials, high order coefficients are stored in the first positions
316: of the array, e.g. to represent x^2-3 use {1,0,-3}.
318: Level: intermediate
320: .seealso: FNGetParameters()
321: @*/
322: PetscErrorCode FNSetParameters(FN fn,PetscInt na,PetscScalar *alpha,PetscInt nb,PetscScalar *beta)323: {
325: PetscInt i;
330: if (na<0) SETERRQ(PetscObjectComm((PetscObject)fn),PETSC_ERR_ARG_OUTOFRANGE,"Argument na cannot be negative");
333: if (nb<0) SETERRQ(PetscObjectComm((PetscObject)fn),PETSC_ERR_ARG_OUTOFRANGE,"Argument nb cannot be negative");
335: fn->na = na;
336: PetscFree(fn->alpha);
337: if (na) {
338: PetscMalloc1(na,&fn->alpha);
339: PetscLogObjectMemory((PetscObject)fn,na*sizeof(PetscScalar));
340: for (i=0;i<na;i++) fn->alpha[i] = alpha[i];
341: }
342: fn->nb = nb;
343: PetscFree(fn->beta);
344: if (nb) {
345: PetscMalloc1(nb,&fn->beta);
346: PetscLogObjectMemory((PetscObject)fn,nb*sizeof(PetscScalar));
347: for (i=0;i<nb;i++) fn->beta[i] = beta[i];
348: }
349: return(0);
350: }
354: /*@
355: FNGetParameters - Returns the parameters that define the matematical function.
357: Not Collective
359: Input Parameter:
360: . fn - the math function context
362: Output Parameters:
363: + na - number of parameters in the first group
364: . alpha - first group of parameters (array of scalar values)
365: . nb - number of parameters in the second group
366: - beta - second group of parameters (array of scalar values)
368: Level: intermediate
370: .seealso: FNSetParameters()
371: @*/
372: PetscErrorCode FNGetParameters(FN fn,PetscInt *na,PetscScalar *alpha[],PetscInt *nb,PetscScalar *beta[])373: {
376: if (na) *na = fn->na;
377: if (alpha) *alpha = fn->alpha;
378: if (nb) *nb = fn->nb;
379: if (beta) *beta = fn->beta;
380: return(0);
381: }
385: /*@
386: FNEvaluateFunction - Computes the value of the function f(x) for a given x.
388: Logically Collective on FN390: Input Parameters:
391: + fn - the math function context
392: - x - the value where the function must be evaluated
394: Output Parameter:
395: . y - the result of f(x)
397: Level: intermediate
399: .seealso: FNEvaluateDerivative()
400: @*/
401: PetscErrorCode FNEvaluateFunction(FN fn,PetscScalar x,PetscScalar *y)402: {
409: if (!((PetscObject)fn)->type_name) {
410: FNSetType(fn,FNRATIONAL);
411: }
412: (*fn->ops->evaluatefunction)(fn,x,y);
413: return(0);
414: }
418: /*@
419: FNEvaluateDerivative - Computes the value of the derivative f'(x) for a given x.
421: Logically Collective on FN423: Input Parameters:
424: + fn - the math function context
425: - x - the value where the derivative must be evaluated
427: Output Parameter:
428: . y - the result of f'(x)
430: Level: intermediate
432: .seealso: FNEvaluateFunction()
433: @*/
434: PetscErrorCode FNEvaluateDerivative(FN fn,PetscScalar x,PetscScalar *y)435: {
442: if (!((PetscObject)fn)->type_name) {
443: FNSetType(fn,FNRATIONAL);
444: }
445: (*fn->ops->evaluatederivative)(fn,x,y);
446: return(0);
447: }
451: /*@
452: FNSetFromOptions - Sets FN options from the options database.
454: Collective on FN456: Input Parameters:
457: . fn - the math function context
459: Notes:
460: To see all options, run your program with the -help option.
462: Level: beginner
463: @*/
464: PetscErrorCode FNSetFromOptions(FN fn)465: {
470: if (!FNRegisterAllCalled) { FNRegisterAll(); }
471: /* Set default type (we do not allow changing it with -fn_type) */
472: if (!((PetscObject)fn)->type_name) {
473: FNSetType(fn,FNRATIONAL);
474: }
475: PetscObjectOptionsBegin((PetscObject)fn);
476: PetscObjectProcessOptionsHandlers((PetscObject)fn);
477: PetscOptionsEnd();
478: return(0);
479: }
483: /*@C
484: FNView - Prints the FN data structure.
486: Collective on FN488: Input Parameters:
489: + fn - the math function context
490: - viewer - optional visualization context
492: Note:
493: The available visualization contexts include
494: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
495: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
496: output where only the first processor opens
497: the file. All other processors send their
498: data to the first processor to print.
500: The user can open an alternative visualization context with
501: PetscViewerASCIIOpen() - output to a specified file.
503: Level: beginner
504: @*/
505: PetscErrorCode FNView(FN fn,PetscViewer viewer)506: {
507: PetscBool isascii;
512: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)fn));
515: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
516: if (isascii) {
517: PetscObjectPrintClassNamePrefixType((PetscObject)fn,viewer);
518: if (fn->ops->view) {
519: PetscViewerASCIIPushTab(viewer);
520: (*fn->ops->view)(fn,viewer);
521: PetscViewerASCIIPopTab(viewer);
522: }
523: }
524: return(0);
525: }
529: /*@C
530: FNDestroy - Destroys FN context that was created with FNCreate().
532: Collective on FN534: Input Parameter:
535: . fn - the math function context
537: Level: beginner
539: .seealso: FNCreate()
540: @*/
541: PetscErrorCode FNDestroy(FN *fn)542: {
546: if (!*fn) return(0);
548: if (--((PetscObject)(*fn))->refct > 0) { *fn = 0; return(0); }
549: PetscFree((*fn)->alpha);
550: PetscFree((*fn)->beta);
551: PetscHeaderDestroy(fn);
552: return(0);
553: }
557: /*@C
558: FNRegister - See Adds a mathematical function to the FN package.
560: Not collective
562: Input Parameters:
563: + name - name of a new user-defined FN564: - function - routine to create context
566: Notes:
567: FNRegister() may be called multiple times to add several user-defined inner products.
569: Level: advanced
571: .seealso: FNRegisterAll()
572: @*/
573: PetscErrorCode FNRegister(const char *name,PetscErrorCode (*function)(FN))574: {
578: PetscFunctionListAdd(&FNList,name,function);
579: return(0);
580: }
582: PETSC_EXTERN PetscErrorCode FNCreate_Rational(FN);
583: PETSC_EXTERN PetscErrorCode FNCreate_Exp(FN);
587: /*@C
588: FNRegisterAll - Registers all of the math functions in the FN package.
590: Not Collective
592: Level: advanced
593: @*/
594: PetscErrorCode FNRegisterAll(void)595: {
599: FNRegisterAllCalled = PETSC_TRUE;
600: FNRegister(FNRATIONAL,FNCreate_Rational);
601: FNRegister(FNEXP,FNCreate_Exp);
602: return(0);
603: }