Actual source code: fnbasic.c

  1: /*
  2:      Basic routines

  4:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  5:    SLEPc - Scalable Library for Eigenvalue Problem Computations
  6:    Copyright (c) 2002-2013, 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. It is called
 56:   from PetscDLLibraryRegister() when using dynamic libraries, and on the first call to FNCreate()
 57:   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(), FN
113: @*/
114: PetscErrorCode FNCreate(MPI_Comm comm,FN *newfn)
115: {
116:   FN             fn;

121:   *newfn = 0;
122: #if !defined(PETSC_USE_DYNAMIC_LIBRARIES)
123:   FNInitializePackage();
124: #endif

126:   SlepcHeaderCreate(fn,_p_FN,struct _FNOps,FN_CLASSID,"FN","Math Function","FN",comm,FNDestroy,FNView);
127:   fn->na       = 0;
128:   fn->alpha    = NULL;
129:   fn->nb       = 0;
130:   fn->beta     = NULL;

132:   *newfn = fn;
133:   return(0);
134: }

138: /*@C
139:    FNSetOptionsPrefix - Sets the prefix used for searching for all
140:    FN options in the database.

142:    Logically Collective on FN

144:    Input Parameters:
145: +  fn - the math function context
146: -  prefix - the prefix string to prepend to all FN option requests

148:    Notes:
149:    A hyphen (-) must NOT be given at the beginning of the prefix name.
150:    The first character of all runtime options is AUTOMATICALLY the
151:    hyphen.

153:    Level: advanced

155: .seealso: FNAppendOptionsPrefix()
156: @*/
157: PetscErrorCode FNSetOptionsPrefix(FN fn,const char *prefix)
158: {

163:   PetscObjectSetOptionsPrefix((PetscObject)fn,prefix);
164:   return(0);
165: }

169: /*@C
170:    FNAppendOptionsPrefix - Appends to the prefix used for searching for all
171:    FN options in the database.

173:    Logically Collective on FN

175:    Input Parameters:
176: +  fn - the math function context
177: -  prefix - the prefix string to prepend to all FN option requests

179:    Notes:
180:    A hyphen (-) must NOT be given at the beginning of the prefix name.
181:    The first character of all runtime options is AUTOMATICALLY the hyphen.

183:    Level: advanced

185: .seealso: FNSetOptionsPrefix()
186: @*/
187: PetscErrorCode FNAppendOptionsPrefix(FN fn,const char *prefix)
188: {

193:   PetscObjectAppendOptionsPrefix((PetscObject)fn,prefix);
194:   return(0);
195: }

199: /*@C
200:    FNGetOptionsPrefix - Gets the prefix used for searching for all
201:    FN options in the database.

203:    Not Collective

205:    Input Parameters:
206: .  fn - the math function context

208:    Output Parameters:
209: .  prefix - pointer to the prefix string used is returned

211:    Notes: On the fortran side, the user should pass in a string 'prefix' of
212:    sufficient length to hold the prefix.

214:    Level: advanced

216: .seealso: FNSetOptionsPrefix(), FNAppendOptionsPrefix()
217: @*/
218: PetscErrorCode FNGetOptionsPrefix(FN fn,const char *prefix[])
219: {

225:   PetscObjectGetOptionsPrefix((PetscObject)fn,prefix);
226:   return(0);
227: }

231: /*@C
232:    FNSetType - Selects the type for the FN object.

234:    Logically Collective on FN

236:    Input Parameter:
237: +  fn   - the math function context
238: -  type - a known type

240:    Notes:
241:    The default is FNRATIONAL, which includes polynomials as a particular
242:    case as well as simple functions such as f(x)=x and f(x)=constant.

244:    Level: intermediate

246: .seealso: FNGetType()
247: @*/
248: PetscErrorCode FNSetType(FN fn,FNType type)
249: {
250:   PetscErrorCode ierr,(*r)(FN);
251:   PetscBool      match;


257:   PetscObjectTypeCompare((PetscObject)fn,type,&match);
258:   if (match) return(0);

260:    PetscFunctionListFind(FNList,type,&r);
261:   if (!r) SETERRQ1(PetscObjectComm((PetscObject)fn),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested FN type %s",type);

263:   PetscMemzero(fn->ops,sizeof(struct _FNOps));

265:   PetscObjectChangeTypeName((PetscObject)fn,type);
266:   (*r)(fn);
267:   return(0);
268: }

272: /*@C
273:    FNGetType - Gets the FN type name (as a string) from the FN context.

275:    Not Collective

277:    Input Parameter:
278: .  fn - the math function context

280:    Output Parameter:
281: .  name - name of the math function

283:    Level: intermediate

285: .seealso: FNSetType()
286: @*/
287: PetscErrorCode FNGetType(FN fn,FNType *type)
288: {
292:   *type = ((PetscObject)fn)->type_name;
293:   return(0);
294: }

298: /*@
299:    FNSetParameters - Sets the parameters that define the matematical function.

301:    Logically Collective on FN

303:    Input Parameters:
304: +  fn    - the math function context
305: .  na    - number of parameters in the first group
306: .  alpha - first group of parameters (array of scalar values)
307: .  nb    - number of parameters in the second group
308: -  beta  - second group of parameters (array of scalar values)

310:    Notes:
311:    In a rational function r(x) = p(x)/q(x), where p(x) and q(x) are polynomials,
312:    the parameters alpha and beta represent the coefficients of p(x) and q(x),
313:    respectively. Hence, p(x) is of degree na-1 and q(x) of degree nb-1.
314:    If nb is zero, then the function is assumed to be polynomial, r(x) = p(x).

316:    In other functions the parameters have other meanings.

318:    In polynomials, high order coefficients are stored in the first positions
319:    of the array, e.g. to represent x^2-3 use {1,0,-3}.

321:    Level: intermediate

323: .seealso: FNGetParameters()
324: @*/
325: PetscErrorCode FNSetParameters(FN fn,PetscInt na,PetscScalar *alpha,PetscInt nb,PetscScalar *beta)
326: {
328:   PetscInt       i;

333:   if (na<0) SETERRQ(PetscObjectComm((PetscObject)fn),PETSC_ERR_ARG_OUTOFRANGE,"Argument na cannot be negative");
336:   if (nb<0) SETERRQ(PetscObjectComm((PetscObject)fn),PETSC_ERR_ARG_OUTOFRANGE,"Argument nb cannot be negative");
338:   fn->na = na;
339:   PetscFree(fn->alpha);
340:   if (na) {
341:     PetscMalloc(na*sizeof(PetscScalar),&fn->alpha);
342:     PetscLogObjectMemory(fn,na*sizeof(PetscScalar));
343:     for (i=0;i<na;i++) fn->alpha[i] = alpha[i];
344:   }
345:   fn->nb = nb;
346:   PetscFree(fn->beta);
347:   if (nb) {
348:     PetscMalloc(nb*sizeof(PetscScalar),&fn->beta);
349:     PetscLogObjectMemory(fn,nb*sizeof(PetscScalar));
350:     for (i=0;i<nb;i++) fn->beta[i] = beta[i];
351:   }
352:   return(0);
353: }

357: /*@
358:    FNGetParameters - Returns the parameters that define the matematical function.

360:    Not Collective

362:    Input Parameter:
363: .  fn    - the math function context

365:    Output Parameters:
366: +  na    - number of parameters in the first group
367: .  alpha - first group of parameters (array of scalar values)
368: .  nb    - number of parameters in the second group
369: -  beta  - second group of parameters (array of scalar values)

371:    Level: intermediate

373: .seealso: FNSetParameters()
374: @*/
375: PetscErrorCode FNGetParameters(FN fn,PetscInt *na,PetscScalar *alpha[],PetscInt *nb,PetscScalar *beta[])
376: {
379:   if (na)    *na = fn->na;
380:   if (alpha) *alpha = fn->alpha;
381:   if (nb)    *nb = fn->nb;
382:   if (beta)  *beta = fn->beta;
383:   return(0);
384: }

388: /*@
389:    FNEvaluateFunction - Computes the value of the function f(x) for a given x.

391:    Logically Collective on FN

393:    Input Parameters:
394: +  fn - the math function context
395: -  x  - the value where the function must be evaluated

397:    Output Parameter:
398: .  y  - the result of f(x)

400:    Level: intermediate

402: .seealso: FNEvaluateDerivative()
403: @*/
404: PetscErrorCode FNEvaluateFunction(FN fn,PetscScalar x,PetscScalar *y)
405: {

412:   if (!((PetscObject)fn)->type_name) {
413:     FNSetType(fn,FNRATIONAL);
414:   }
415:   (*fn->ops->evaluatefunction)(fn,x,y);
416:   return(0);
417: }

421: /*@
422:    FNEvaluateDerivative - Computes the value of the derivative f'(x) for a given x.

424:    Logically Collective on FN

426:    Input Parameters:
427: +  fn - the math function context
428: -  x  - the value where the derivative must be evaluated

430:    Output Parameter:
431: .  y  - the result of f'(x)

433:    Level: intermediate

435: .seealso: FNEvaluateFunction()
436: @*/
437: PetscErrorCode FNEvaluateDerivative(FN fn,PetscScalar x,PetscScalar *y)
438: {

445:   if (!((PetscObject)fn)->type_name) {
446:     FNSetType(fn,FNRATIONAL);
447:   }
448:   (*fn->ops->evaluatederivative)(fn,x,y);
449:   return(0);
450: }

454: /*@
455:    FNSetFromOptions - Sets FN options from the options database.

457:    Collective on FN

459:    Input Parameters:
460: .  fn - the math function context

462:    Notes:
463:    To see all options, run your program with the -help option.

465:    Level: beginner
466: @*/
467: PetscErrorCode FNSetFromOptions(FN fn)
468: {

473:   if (!FNRegisterAllCalled) { FNRegisterAll(); }
474:   /* Set default type (we do not allow changing it with -fn_type) */
475:   if (!((PetscObject)fn)->type_name) {
476:     FNSetType(fn,FNRATIONAL);
477:   }
478:   PetscObjectOptionsBegin((PetscObject)fn);
479:     PetscObjectProcessOptionsHandlers((PetscObject)fn);
480:   PetscOptionsEnd();
481:   return(0);
482: }

486: /*@C
487:    FNView - Prints the FN data structure.

489:    Collective on FN

491:    Input Parameters:
492: +  fn - the math function context
493: -  viewer - optional visualization context

495:    Note:
496:    The available visualization contexts include
497: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
498: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
499:          output where only the first processor opens
500:          the file.  All other processors send their
501:          data to the first processor to print.

503:    The user can open an alternative visualization context with
504:    PetscViewerASCIIOpen() - output to a specified file.

506:    Level: beginner
507: @*/
508: PetscErrorCode FNView(FN fn,PetscViewer viewer)
509: {
510:   PetscBool      isascii;

515:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)fn));
518:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
519:   if (isascii) {
520:     PetscObjectPrintClassNamePrefixType((PetscObject)fn,viewer,"FN Object");
521:     if (fn->ops->view) {
522:       PetscViewerASCIIPushTab(viewer);
523:       (*fn->ops->view)(fn,viewer);
524:       PetscViewerASCIIPopTab(viewer);
525:     }
526:   }
527:   return(0);
528: }

532: /*@C
533:    FNDestroy - Destroys FN context that was created with FNCreate().

535:    Collective on FN

537:    Input Parameter:
538: .  fn - the math function context

540:    Level: beginner

542: .seealso: FNCreate()
543: @*/
544: PetscErrorCode FNDestroy(FN *fn)
545: {

549:   if (!*fn) return(0);
551:   if (--((PetscObject)(*fn))->refct > 0) { *fn = 0; return(0); }
552:   PetscFree((*fn)->alpha);
553:   PetscFree((*fn)->beta);
554:   PetscHeaderDestroy(fn);
555:   return(0);
556: }

560: /*@C
561:    FNRegister - See Adds a mathematical function to the FN package.

563:    Not collective

565:    Input Parameters:
566: +  name - name of a new user-defined FN
567: -  function - routine to create context

569:    Notes:
570:    FNRegister() may be called multiple times to add several user-defined inner products.

572:    Level: advanced

574: .seealso: FNRegisterAll()
575: @*/
576: PetscErrorCode FNRegister(const char *name,PetscErrorCode (*function)(FN))
577: {

581:   PetscFunctionListAdd(&FNList,name,function);
582:   return(0);
583: }

585: PETSC_EXTERN PetscErrorCode FNCreate_Rational(FN);
586: PETSC_EXTERN PetscErrorCode FNCreate_Exp(FN);

590: /*@C
591:    FNRegisterAll - Registers all of the math functions in the FN package.

593:    Not Collective

595:    Level: advanced
596: @*/
597: PetscErrorCode FNRegisterAll(void)
598: {

602:   FNRegisterAllCalled = PETSC_TRUE;
603:   FNRegister(FNRATIONAL,FNCreate_Rational);
604:   FNRegister(FNEXP,FNCreate_Exp);
605:   return(0);
606: }