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/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: /*@C
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,_p_RG,struct _RGOps,RG_CLASSID,"RG","Region","RG",comm,RGDestroy,RGView);
124: rg->complement = PETSC_FALSE;
125: rg->data = NULL;
127: *newrg = rg;
128: return(0);
129: }
133: /*@C
134: RGSetOptionsPrefix - Sets the prefix used for searching for all
135: RG options in the database.
137: Logically Collective on RG
139: Input Parameters:
140: + rg - the region context
141: - prefix - the prefix string to prepend to all RG option requests
143: Notes:
144: A hyphen (-) must NOT be given at the beginning of the prefix name.
145: The first character of all runtime options is AUTOMATICALLY the
146: hyphen.
148: Level: advanced
150: .seealso: RGAppendOptionsPrefix()
151: @*/
152: PetscErrorCode RGSetOptionsPrefix(RG rg,const char *prefix)153: {
158: PetscObjectSetOptionsPrefix((PetscObject)rg,prefix);
159: return(0);
160: }
164: /*@C
165: RGAppendOptionsPrefix - Appends to the prefix used for searching for all
166: RG options in the database.
168: Logically Collective on RG
170: Input Parameters:
171: + rg - the region context
172: - prefix - the prefix string to prepend to all RG option requests
174: Notes:
175: A hyphen (-) must NOT be given at the beginning of the prefix name.
176: The first character of all runtime options is AUTOMATICALLY the hyphen.
178: Level: advanced
180: .seealso: RGSetOptionsPrefix()
181: @*/
182: PetscErrorCode RGAppendOptionsPrefix(RG rg,const char *prefix)183: {
188: PetscObjectAppendOptionsPrefix((PetscObject)rg,prefix);
189: return(0);
190: }
194: /*@C
195: RGGetOptionsPrefix - Gets the prefix used for searching for all
196: RG options in the database.
198: Not Collective
200: Input Parameters:
201: . rg - the region context
203: Output Parameters:
204: . prefix - pointer to the prefix string used is returned
206: Notes: On the fortran side, the user should pass in a string 'prefix' of
207: sufficient length to hold the prefix.
209: Level: advanced
211: .seealso: RGSetOptionsPrefix(), RGAppendOptionsPrefix()
212: @*/
213: PetscErrorCode RGGetOptionsPrefix(RG rg,const char *prefix[])214: {
220: PetscObjectGetOptionsPrefix((PetscObject)rg,prefix);
221: return(0);
222: }
226: /*@C
227: RGSetType - Selects the type for the RG object.
229: Logically Collective on RG
231: Input Parameter:
232: + rg - the region context
233: - type - a known type
235: Level: intermediate
237: .seealso: RGGetType()
238: @*/
239: PetscErrorCode RGSetType(RG rg,RGType type)240: {
241: PetscErrorCode ierr,(*r)(RG);
242: PetscBool match;
248: PetscObjectTypeCompare((PetscObject)rg,type,&match);
249: if (match) return(0);
251: PetscFunctionListFind(RGList,type,&r);
252: if (!r) SETERRQ1(PetscObjectComm((PetscObject)rg),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested RG type %s",type);
254: if (rg->ops->destroy) { (*rg->ops->destroy)(rg); }
255: PetscMemzero(rg->ops,sizeof(struct _RGOps));
257: PetscObjectChangeTypeName((PetscObject)rg,type);
258: (*r)(rg);
259: return(0);
260: }
264: /*@C
265: RGGetType - Gets the RG type name (as a string) from the RG context.
267: Not Collective
269: Input Parameter:
270: . rg - the region context
272: Output Parameter:
273: . name - name of the region
275: Level: intermediate
277: .seealso: RGSetType()
278: @*/
279: PetscErrorCode RGGetType(RG rg,RGType *type)280: {
284: *type = ((PetscObject)rg)->type_name;
285: return(0);
286: }
290: /*@
291: RGSetFromOptions - Sets RG options from the options database.
293: Collective on RG
295: Input Parameters:
296: . rg - the region context
298: Notes:
299: To see all options, run your program with the -help option.
301: Level: beginner
302: @*/
303: PetscErrorCode RGSetFromOptions(RG rg)304: {
306: char type[256];
307: PetscBool flg;
311: if (!RGRegisterAllCalled) { RGRegisterAll(); }
312: PetscObjectOptionsBegin((PetscObject)rg);
313: PetscOptionsFList("-rg_type","Region type","RGSetType",RGList,(char*)(((PetscObject)rg)->type_name?((PetscObject)rg)->type_name:RGINTERVAL),type,256,&flg);
314: if (flg) {
315: RGSetType(rg,type);
316: }
317: /*
318: Set the type if it was never set.
319: */
320: if (!((PetscObject)rg)->type_name) {
321: RGSetType(rg,RGINTERVAL);
322: }
324: PetscOptionsBool("-rg_complement","Whether region is complemented or not","RGSetComplement",rg->complement,&rg->complement,&flg);
326: if (rg->ops->setfromoptions) {
327: (*rg->ops->setfromoptions)(rg);
328: }
329: PetscObjectProcessOptionsHandlers((PetscObject)rg);
330: PetscOptionsEnd();
331: return(0);
332: }
336: /*@C
337: RGView - Prints the RG data structure.
339: Collective on RG
341: Input Parameters:
342: + rg - the region context
343: - viewer - optional visualization context
345: Note:
346: The available visualization contexts include
347: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
348: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
349: output where only the first processor opens
350: the file. All other processors send their
351: data to the first processor to print.
353: The user can open an alternative visualization context with
354: PetscViewerASCIIOpen() - output to a specified file.
356: Level: beginner
357: @*/
358: PetscErrorCode RGView(RG rg,PetscViewer viewer)359: {
360: PetscBool isascii;
365: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)rg));
368: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
369: if (isascii) {
370: PetscObjectPrintClassNamePrefixType((PetscObject)rg,viewer);
371: if (rg->ops->view) {
372: PetscViewerASCIIPushTab(viewer);
373: (*rg->ops->view)(rg,viewer);
374: PetscViewerASCIIPopTab(viewer);
375: }
376: if (rg->complement) {
377: PetscViewerASCIIPrintf(viewer," selected region is the complement of the specified one\n");
378: }
379: }
380: return(0);
381: }
385: /*@
386: RGIsTrivial - Whether it is the trivial region (whole complex plane).
388: Not Collective
390: Input Parameter:
391: . rg - the region context
393: Output Parameter:
394: . trivial - true if the region is equal to the whole complex plane, e.g.,
395: an interval region with all four endpoints unbounded or an
396: ellipse with infinite radius.
398: Level: basic
399: @*/
400: PetscErrorCode RGIsTrivial(RG rg,PetscBool *trivial)401: {
408: if (*rg->ops->istrivial) {
409: (*rg->ops->istrivial)(rg,trivial);
410: } else *trivial = PETSC_FALSE;
411: return(0);
412: }
416: /*@
417: RGCheckInside - Determines if a set of given points are inside the region or not.
419: Not Collective
421: Input Parameters:
422: + rg - the region context
423: . n - number of points to check
424: . ar - array of real parts
425: - ai - array of imaginary parts
427: Output Parameter:
428: . inside - array of results (1=inside, 0=on the contour, -1=outside)
430: Note:
431: The point a is expressed as a couple of PetscScalar variables ar,ai.
432: If built with complex scalars, the point is supposed to be stored in ar,
433: otherwise ar,ai contain the real and imaginary parts, respectively.
435: Level: intermediate
436: @*/
437: PetscErrorCode RGCheckInside(RG rg,PetscInt n,PetscScalar *ar,PetscScalar *ai,PetscInt *inside)438: {
440: PetscInt i;
446: #if defined(PETSC_USE_COMPLEX)
448: #endif
450: (*rg->ops->checkinside)(rg,n,ar,ai,inside);
451: if (rg->complement) {
452: for (i=0;i<n;i++) inside[i] = -inside[i];
453: }
454: return(0);
455: }
459: /*@
460: RGComputeContour - Computes the coordinates of several points lying in the
461: contour of the region.
463: Not Collective
465: Input Parameters:
466: + rg - the region context
467: - n - number of points to compute
469: Output Parameter:
470: + cr - location to store real parts
471: - ci - location to store imaginary parts
473: Level: intermediate
474: @*/
475: PetscErrorCode RGComputeContour(RG rg,PetscInt n,PetscScalar *cr,PetscScalar *ci)476: {
483: #if defined(PETSC_USE_COMPLEX)
485: #endif
486: (*rg->ops->computecontour)(rg,n,cr,ci);
487: return(0);
488: }
492: /*@
493: RGSetComplement - Sets a flag to indicate that the region is the complement
494: of the specified one.
496: Logically Collective on RG
498: Input Parameters:
499: + rg - the region context
500: - flg - the boolean flag
502: Options Database Key:
503: . -rg_complement <bool> - Activate/deactivate the complementation of the region.
505: Level: intermediate
507: .seealso: RGGetComplement()
508: @*/
509: PetscErrorCode RGSetComplement(RG rg,PetscBool flg)510: {
514: rg->complement = flg;
515: return(0);
516: }
520: /*@
521: RGGetComplement - Gets a flag that that indicates whether the region
522: is complemented or not.
524: Not Collective
526: Input Parameter:
527: . rg - the region context
529: Output Parameter:
530: . flg - the flag
532: Level: intermediate
534: .seealso: RGSetComplement()
535: @*/
536: PetscErrorCode RGGetComplement(RG rg,PetscBool *flg)537: {
541: *flg = rg->complement;
542: return(0);
543: }
547: /*@C
548: RGDestroy - Destroys RG context that was created with RGCreate().
550: Collective on RG
552: Input Parameter:
553: . rg - the region context
555: Level: beginner
557: .seealso: RGCreate()
558: @*/
559: PetscErrorCode RGDestroy(RG *rg)560: {
564: if (!*rg) return(0);
566: if (--((PetscObject)(*rg))->refct > 0) { *rg = 0; return(0); }
567: if ((*rg)->ops->destroy) { (*(*rg)->ops->destroy)(*rg); }
568: PetscHeaderDestroy(rg);
569: return(0);
570: }
574: /*@C
575: RGRegister - See Adds a mathematical function to the RG package.
577: Not collective
579: Input Parameters:
580: + name - name of a new user-defined RG
581: - function - routine to create context
583: Notes:
584: RGRegister() may be called multiple times to add several user-defined inner products.
586: Level: advanced
588: .seealso: RGRegisterAll()
589: @*/
590: PetscErrorCode RGRegister(const char *name,PetscErrorCode (*function)(RG))591: {
595: PetscFunctionListAdd(&RGList,name,function);
596: return(0);
597: }
599: PETSC_EXTERN PetscErrorCode RGCreate_Interval(RG);
600: PETSC_EXTERN PetscErrorCode RGCreate_Ellipse(RG);
604: /*@C
605: RGRegisterAll - Registers all of the regions in the RG package.
607: Not Collective
609: Level: advanced
610: @*/
611: PetscErrorCode RGRegisterAll(void)612: {
616: RGRegisterAllCalled = PETSC_TRUE;
617: RGRegister(RGINTERVAL,RGCreate_Interval);
618: RGRegister(RGELLIPSE,RGCreate_Ellipse);
619: return(0);
620: }