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(), RG113: @*/
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 RG140: 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 RG171: 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 RG232: 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 RG296: 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 RG342: 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 RG519: 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 RG574: 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 RG628: 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 RG657: - 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: }