Actual source code: rgbasic.c

slepc-3.6.1 2015-09-03
Report Typos and Errors
  1: /*
  2:    Basic routines

  4:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  5:    SLEPc - Scalable Library for Eigenvalue Problem Computations
  6:    Copyright (c) 2002-2015, 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/rgimpl.h>      /*I "slepcrg.h" I*/

 26: PetscFunctionList RGList = 0;
 27: PetscBool         RGRegisterAllCalled = PETSC_FALSE;
 28: PetscClassId      RG_CLASSID = 0;
 29: static PetscBool  RGPackageInitialized = PETSC_FALSE;

 33: /*@C
 34:    RGFinalizePackage - This function destroys everything in the Slepc interface
 35:    to the RG package. It is called from SlepcFinalize().

 37:    Level: developer

 39: .seealso: SlepcFinalize()
 40: @*/
 41: PetscErrorCode RGFinalizePackage(void)
 42: {

 46:   PetscFunctionListDestroy(&RGList);
 47:   RGPackageInitialized = PETSC_FALSE;
 48:   RGRegisterAllCalled  = PETSC_FALSE;
 49:   return(0);
 50: }

 54: /*@C
 55:   RGInitializePackage - This function initializes everything in the RG package.
 56:   It is called from PetscDLLibraryRegister() when using dynamic libraries, and
 57:   on the first call to RGCreate() when using static libraries.

 59:   Level: developer

 61: .seealso: SlepcInitialize()
 62: @*/
 63: PetscErrorCode RGInitializePackage(void)
 64: {
 65:   char             logList[256];
 66:   char             *className;
 67:   PetscBool        opt;
 68:   PetscErrorCode   ierr;

 71:   if (RGPackageInitialized) return(0);
 72:   RGPackageInitialized = PETSC_TRUE;
 73:   /* Register Classes */
 74:   PetscClassIdRegister("Region",&RG_CLASSID);
 75:   /* Register Constructors */
 76:   RGRegisterAll();
 77:   /* Process info exclusions */
 78:   PetscOptionsGetString(NULL,"-info_exclude",logList,256,&opt);
 79:   if (opt) {
 80:     PetscStrstr(logList,"rg",&className);
 81:     if (className) {
 82:       PetscInfoDeactivateClass(RG_CLASSID);
 83:     }
 84:   }
 85:   /* Process summary exclusions */
 86:   PetscOptionsGetString(NULL,"-log_summary_exclude",logList,256,&opt);
 87:   if (opt) {
 88:     PetscStrstr(logList,"rg",&className);
 89:     if (className) {
 90:       PetscLogEventDeactivateClass(RG_CLASSID);
 91:     }
 92:   }
 93:   PetscRegisterFinalize(RGFinalizePackage);
 94:   return(0);
 95: }

 99: /*@
100:    RGCreate - Creates an RG context.

102:    Collective on MPI_Comm

104:    Input Parameter:
105: .  comm - MPI communicator

107:    Output Parameter:
108: .  newrg - location to put the RG context

110:    Level: beginner

112: .seealso: RGDestroy(), RG
113: @*/
114: PetscErrorCode RGCreate(MPI_Comm comm,RG *newrg)
115: {
116:   RG             rg;

121:   *newrg = 0;
122:   RGInitializePackage();
123:   SlepcHeaderCreate(rg,RG_CLASSID,"RG","Region","RG",comm,RGDestroy,RGView);
124:   rg->complement = PETSC_FALSE;
125:   rg->sfactor    = 1.0;
126:   rg->data       = NULL;

128:   *newrg = rg;
129:   return(0);
130: }

134: /*@C
135:    RGSetOptionsPrefix - Sets the prefix used for searching for all
136:    RG options in the database.

138:    Logically Collective on RG

140:    Input Parameters:
141: +  rg     - the region context
142: -  prefix - the prefix string to prepend to all RG option requests

144:    Notes:
145:    A hyphen (-) must NOT be given at the beginning of the prefix name.
146:    The first character of all runtime options is AUTOMATICALLY the
147:    hyphen.

149:    Level: advanced

151: .seealso: RGAppendOptionsPrefix()
152: @*/
153: PetscErrorCode RGSetOptionsPrefix(RG rg,const char *prefix)
154: {

159:   PetscObjectSetOptionsPrefix((PetscObject)rg,prefix);
160:   return(0);
161: }

165: /*@C
166:    RGAppendOptionsPrefix - Appends to the prefix used for searching for all
167:    RG options in the database.

169:    Logically Collective on RG

171:    Input Parameters:
172: +  rg     - the region context
173: -  prefix - the prefix string to prepend to all RG option requests

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

179:    Level: advanced

181: .seealso: RGSetOptionsPrefix()
182: @*/
183: PetscErrorCode RGAppendOptionsPrefix(RG rg,const char *prefix)
184: {

189:   PetscObjectAppendOptionsPrefix((PetscObject)rg,prefix);
190:   return(0);
191: }

195: /*@C
196:    RGGetOptionsPrefix - Gets the prefix used for searching for all
197:    RG options in the database.

199:    Not Collective

201:    Input Parameters:
202: .  rg - the region context

204:    Output Parameters:
205: .  prefix - pointer to the prefix string used is returned

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

210:    Level: advanced

212: .seealso: RGSetOptionsPrefix(), RGAppendOptionsPrefix()
213: @*/
214: PetscErrorCode RGGetOptionsPrefix(RG rg,const char *prefix[])
215: {

221:   PetscObjectGetOptionsPrefix((PetscObject)rg,prefix);
222:   return(0);
223: }

227: /*@C
228:    RGSetType - Selects the type for the RG object.

230:    Logically Collective on RG

232:    Input Parameter:
233: +  rg   - the region context
234: -  type - a known type

236:    Level: intermediate

238: .seealso: RGGetType()
239: @*/
240: PetscErrorCode RGSetType(RG rg,RGType type)
241: {
242:   PetscErrorCode ierr,(*r)(RG);
243:   PetscBool      match;


249:   PetscObjectTypeCompare((PetscObject)rg,type,&match);
250:   if (match) return(0);

252:    PetscFunctionListFind(RGList,type,&r);
253:   if (!r) SETERRQ1(PetscObjectComm((PetscObject)rg),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested RG type %s",type);

255:   if (rg->ops->destroy) { (*rg->ops->destroy)(rg); }
256:   PetscMemzero(rg->ops,sizeof(struct _RGOps));

258:   PetscObjectChangeTypeName((PetscObject)rg,type);
259:   (*r)(rg);
260:   return(0);
261: }

265: /*@C
266:    RGGetType - Gets the RG type name (as a string) from the RG context.

268:    Not Collective

270:    Input Parameter:
271: .  rg - the region context

273:    Output Parameter:
274: .  name - name of the region

276:    Level: intermediate

278: .seealso: RGSetType()
279: @*/
280: PetscErrorCode RGGetType(RG rg,RGType *type)
281: {
285:   *type = ((PetscObject)rg)->type_name;
286:   return(0);
287: }

291: /*@
292:    RGSetFromOptions - Sets RG options from the options database.

294:    Collective on RG

296:    Input Parameters:
297: .  rg - the region context

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

302:    Level: beginner
303: @*/
304: PetscErrorCode RGSetFromOptions(RG rg)
305: {
307:   char           type[256];
308:   PetscBool      flg;

312:   RGRegisterAll();
313:   PetscObjectOptionsBegin((PetscObject)rg);
314:     PetscOptionsFList("-rg_type","Region type","RGSetType",RGList,(char*)(((PetscObject)rg)->type_name?((PetscObject)rg)->type_name:RGINTERVAL),type,256,&flg);
315:     if (flg) {
316:       RGSetType(rg,type);
317:     }
318:     /*
319:       Set the type if it was never set.
320:     */
321:     if (!((PetscObject)rg)->type_name) {
322:       RGSetType(rg,RGINTERVAL);
323:     }

325:     PetscOptionsBool("-rg_complement","Whether region is complemented or not","RGSetComplement",rg->complement,&rg->complement,&flg);

327:     if (rg->ops->setfromoptions) {
328:       (*rg->ops->setfromoptions)(PetscOptionsObject,rg);
329:     }
330:     PetscObjectProcessOptionsHandlers((PetscObject)rg);
331:   PetscOptionsEnd();
332:   return(0);
333: }

337: /*@C
338:    RGView - Prints the RG data structure.

340:    Collective on RG

342:    Input Parameters:
343: +  rg - the region context
344: -  viewer - optional visualization context

346:    Note:
347:    The available visualization contexts include
348: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
349: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
350:          output where only the first processor opens
351:          the file.  All other processors send their
352:          data to the first processor to print.

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

357:    Level: beginner
358: @*/
359: PetscErrorCode RGView(RG rg,PetscViewer viewer)
360: {
361:   PetscBool      isascii;

366:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)rg));
369:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
370:   if (isascii) {
371:     PetscObjectPrintClassNamePrefixType((PetscObject)rg,viewer);
372:     if (rg->ops->view) {
373:       PetscViewerASCIIPushTab(viewer);
374:       (*rg->ops->view)(rg,viewer);
375:       PetscViewerASCIIPopTab(viewer);
376:     }
377:     if (rg->complement) {
378:       PetscViewerASCIIPrintf(viewer,"  selected region is the complement of the specified one\n");
379:     }
380:     if (rg->sfactor!=1.0) {
381:       PetscViewerASCIIPrintf(viewer,"  scaling factor = %g\n",(double)rg->sfactor);
382:     }
383:   }
384:   return(0);
385: }

389: /*@
390:    RGIsTrivial - Whether it is the trivial region (whole complex plane).

392:    Not Collective

394:    Input Parameter:
395: .  rg - the region context

397:    Output Parameter:
398: .  trivial - true if the region is equal to the whole complex plane, e.g.,
399:              an interval region with all four endpoints unbounded or an
400:              ellipse with infinite radius.

402:    Level: basic
403: @*/
404: PetscErrorCode RGIsTrivial(RG rg,PetscBool *trivial)
405: {

412:   if (*rg->ops->istrivial) {
413:     (*rg->ops->istrivial)(rg,trivial);
414:   } else *trivial = PETSC_FALSE;
415:   return(0);
416: }

420: /*@
421:    RGCheckInside - Determines if a set of given points are inside the region or not.

423:    Not Collective

425:    Input Parameters:
426: +  rg - the region context
427: .  n  - number of points to check
428: .  ar - array of real parts
429: -  ai - array of imaginary parts

431:    Output Parameter:
432: .  inside - array of results (1=inside, 0=on the contour, -1=outside)

434:    Note:
435:    The point a is expressed as a couple of PetscScalar variables ar,ai.
436:    If built with complex scalars, the point is supposed to be stored in ar,
437:    otherwise ar,ai contain the real and imaginary parts, respectively.

439:    If a scaling factor was set, the points are scaled before checking.

441:    Level: intermediate

443: .seealso: RGSetScale(), RGSetComplement()
444: @*/
445: PetscErrorCode RGCheckInside(RG rg,PetscInt n,PetscScalar *ar,PetscScalar *ai,PetscInt *inside)
446: {
448:   PetscReal      px,py;
449:   PetscInt       i;

455: #if defined(PETSC_USE_COMPLEX)
457: #endif

460:   for (i=0;i<n;i++) {
461: #if defined(PETSC_USE_COMPLEX)
462:     px = PetscRealPart(ar[i]);
463:     py = PetscImaginaryPart(ar[i]);
464: #else
465:     px = ar[i];
466:     py = ai[i];
467: #endif
468:     if (rg->sfactor != 1.0) {
469:       px *= rg->sfactor;
470:       py *= rg->sfactor;
471:     }
472:     (*rg->ops->checkinside)(rg,px,py,inside+i);
473:     if (rg->complement) inside[i] = -inside[i];
474:   }
475:   return(0);
476: }

480: /*@
481:    RGComputeContour - Computes the coordinates of several points lying in the
482:    contour of the region.

484:    Not Collective

486:    Input Parameters:
487: +  rg - the region context
488: -  n  - number of points to compute

490:    Output Parameter:
491: +  cr - location to store real parts
492: -  ci - location to store imaginary parts

494:    Level: intermediate
495: @*/
496: PetscErrorCode RGComputeContour(RG rg,PetscInt n,PetscScalar *cr,PetscScalar *ci)
497: {

504: #if !defined(PETSC_USE_COMPLEX)
506: #endif
507:   (*rg->ops->computecontour)(rg,n,cr,ci);
508:   return(0);
509: }

513: /*@
514:    RGSetComplement - Sets a flag to indicate that the region is the complement
515:    of the specified one.

517:    Logically Collective on RG

519:    Input Parameters:
520: +  rg  - the region context
521: -  flg - the boolean flag

523:    Options Database Key:
524: .  -rg_complement <bool> - Activate/deactivate the complementation of the region.

526:    Level: intermediate

528: .seealso: RGGetComplement()
529: @*/
530: PetscErrorCode RGSetComplement(RG rg,PetscBool flg)
531: {
535:   rg->complement = flg;
536:   return(0);
537: }

541: /*@
542:    RGGetComplement - Gets a flag that that indicates whether the region
543:    is complemented or not.

545:    Not Collective

547:    Input Parameter:
548: .  rg - the region context

550:    Output Parameter:
551: .  flg - the flag

553:    Level: intermediate

555: .seealso: RGSetComplement()
556: @*/
557: PetscErrorCode RGGetComplement(RG rg,PetscBool *flg)
558: {
562:   *flg = rg->complement;
563:   return(0);
564: }

568: /*@
569:    RGSetScale - Sets the scaling factor to be used when checking that a
570:    point is inside the region.

572:    Logically Collective on RG

574:    Input Parameters:
575: +  rg      - the region context
576: -  sfactor - the scaling factor

578:    Level: developer

580: .seealso: RGGetScale(), RGCheckInside()
581: @*/
582: PetscErrorCode RGSetScale(RG rg,PetscReal sfactor)
583: {
587:   if (sfactor == PETSC_DEFAULT || sfactor == PETSC_DECIDE) rg->sfactor = 1.0;
588:   else {
589:     if (sfactor<=0.0) SETERRQ(PetscObjectComm((PetscObject)rg),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of scaling factor. Must be > 0");
590:     rg->sfactor = sfactor;
591:   }
592:   return(0);
593: }

597: /*@
598:    RGGetScale - Gets the scaling factor.

600:    Not Collective

602:    Input Parameter:
603: .  rg - the region context

605:    Output Parameter:
606: .  flg - the flag

608:    Level: developer

610: .seealso: RGSetScale()
611: @*/
612: PetscErrorCode RGGetScale(RG rg,PetscReal *sfactor)
613: {
617:   *sfactor = rg->sfactor;
618:   return(0);
619: }

623: /*@
624:    RGDestroy - Destroys RG context that was created with RGCreate().

626:    Collective on RG

628:    Input Parameter:
629: .  rg - the region context

631:    Level: beginner

633: .seealso: RGCreate()
634: @*/
635: PetscErrorCode RGDestroy(RG *rg)
636: {

640:   if (!*rg) return(0);
642:   if (--((PetscObject)(*rg))->refct > 0) { *rg = 0; return(0); }
643:   if ((*rg)->ops->destroy) { (*(*rg)->ops->destroy)(*rg); }
644:   PetscHeaderDestroy(rg);
645:   return(0);
646: }

650: /*@C
651:    RGRegister - See Adds a mathematical function to the RG package.

653:    Not collective

655:    Input Parameters:
656: +  name - name of a new user-defined RG
657: -  function - routine to create context

659:    Notes:
660:    RGRegister() may be called multiple times to add several user-defined inner products.

662:    Level: advanced

664: .seealso: RGRegisterAll()
665: @*/
666: PetscErrorCode RGRegister(const char *name,PetscErrorCode (*function)(RG))
667: {

671:   PetscFunctionListAdd(&RGList,name,function);
672:   return(0);
673: }