Line data Source code
1 : /*
2 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3 : SLEPc - Scalable Library for Eigenvalue Problem Computations
4 : Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain
5 :
6 : This file is part of SLEPc.
7 : SLEPc is distributed under a 2-clause BSD license (see LICENSE).
8 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9 : */
10 : /*
11 : Basic RG routines
12 : */
13 :
14 : #include <slepc/private/rgimpl.h> /*I "slepcrg.h" I*/
15 :
16 : PetscFunctionList RGList = NULL;
17 : PetscBool RGRegisterAllCalled = PETSC_FALSE;
18 : PetscClassId RG_CLASSID = 0;
19 : static PetscBool RGPackageInitialized = PETSC_FALSE;
20 :
21 : /*@C
22 : RGFinalizePackage - This function destroys everything in the Slepc interface
23 : to the RG package. It is called from SlepcFinalize().
24 :
25 : Level: developer
26 :
27 : .seealso: SlepcFinalize()
28 : @*/
29 814 : PetscErrorCode RGFinalizePackage(void)
30 : {
31 814 : PetscFunctionBegin;
32 814 : PetscCall(PetscFunctionListDestroy(&RGList));
33 814 : RGPackageInitialized = PETSC_FALSE;
34 814 : RGRegisterAllCalled = PETSC_FALSE;
35 814 : PetscFunctionReturn(PETSC_SUCCESS);
36 : }
37 :
38 : /*@C
39 : RGInitializePackage - This function initializes everything in the RG package.
40 : It is called from PetscDLLibraryRegister() when using dynamic libraries, and
41 : on the first call to RGCreate() when using static libraries.
42 :
43 : Level: developer
44 :
45 : .seealso: SlepcInitialize()
46 : @*/
47 4206 : PetscErrorCode RGInitializePackage(void)
48 : {
49 4206 : char logList[256];
50 4206 : PetscBool opt,pkg;
51 4206 : PetscClassId classids[1];
52 :
53 4206 : PetscFunctionBegin;
54 4206 : if (RGPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS);
55 814 : RGPackageInitialized = PETSC_TRUE;
56 : /* Register Classes */
57 814 : PetscCall(PetscClassIdRegister("Region",&RG_CLASSID));
58 : /* Register Constructors */
59 814 : PetscCall(RGRegisterAll());
60 : /* Process Info */
61 814 : classids[0] = RG_CLASSID;
62 814 : PetscCall(PetscInfoProcessClass("rg",1,&classids[0]));
63 : /* Process summary exclusions */
64 814 : PetscCall(PetscOptionsGetString(NULL,NULL,"-log_exclude",logList,sizeof(logList),&opt));
65 814 : if (opt) {
66 8 : PetscCall(PetscStrInList("rg",logList,',',&pkg));
67 8 : if (pkg) PetscCall(PetscLogEventDeactivateClass(RG_CLASSID));
68 : }
69 : /* Register package finalizer */
70 814 : PetscCall(PetscRegisterFinalize(RGFinalizePackage));
71 814 : PetscFunctionReturn(PETSC_SUCCESS);
72 : }
73 :
74 : /*@
75 : RGCreate - Creates an RG context.
76 :
77 : Collective
78 :
79 : Input Parameter:
80 : . comm - MPI communicator
81 :
82 : Output Parameter:
83 : . newrg - location to put the RG context
84 :
85 : Level: beginner
86 :
87 : .seealso: RGDestroy(), RG
88 : @*/
89 949 : PetscErrorCode RGCreate(MPI_Comm comm,RG *newrg)
90 : {
91 949 : RG rg;
92 :
93 949 : PetscFunctionBegin;
94 949 : PetscAssertPointer(newrg,2);
95 949 : PetscCall(RGInitializePackage());
96 949 : PetscCall(SlepcHeaderCreate(rg,RG_CLASSID,"RG","Region","RG",comm,RGDestroy,RGView));
97 949 : rg->complement = PETSC_FALSE;
98 949 : rg->sfactor = 1.0;
99 949 : rg->osfactor = 0.0;
100 949 : rg->data = NULL;
101 :
102 949 : *newrg = rg;
103 949 : PetscFunctionReturn(PETSC_SUCCESS);
104 : }
105 :
106 : /*@
107 : RGSetOptionsPrefix - Sets the prefix used for searching for all
108 : RG options in the database.
109 :
110 : Logically Collective
111 :
112 : Input Parameters:
113 : + rg - the region context
114 : - prefix - the prefix string to prepend to all RG option requests
115 :
116 : Notes:
117 : A hyphen (-) must NOT be given at the beginning of the prefix name.
118 : The first character of all runtime options is AUTOMATICALLY the
119 : hyphen.
120 :
121 : Level: advanced
122 :
123 : .seealso: RGAppendOptionsPrefix()
124 : @*/
125 210 : PetscErrorCode RGSetOptionsPrefix(RG rg,const char *prefix)
126 : {
127 210 : PetscFunctionBegin;
128 210 : PetscValidHeaderSpecific(rg,RG_CLASSID,1);
129 210 : PetscCall(PetscObjectSetOptionsPrefix((PetscObject)rg,prefix));
130 210 : PetscFunctionReturn(PETSC_SUCCESS);
131 : }
132 :
133 : /*@
134 : RGAppendOptionsPrefix - Appends to the prefix used for searching for all
135 : RG options in the database.
136 :
137 : Logically Collective
138 :
139 : Input Parameters:
140 : + rg - the region context
141 : - prefix - the prefix string to prepend to all RG option requests
142 :
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 hyphen.
146 :
147 : Level: advanced
148 :
149 : .seealso: RGSetOptionsPrefix()
150 : @*/
151 174 : PetscErrorCode RGAppendOptionsPrefix(RG rg,const char *prefix)
152 : {
153 174 : PetscFunctionBegin;
154 174 : PetscValidHeaderSpecific(rg,RG_CLASSID,1);
155 174 : PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)rg,prefix));
156 174 : PetscFunctionReturn(PETSC_SUCCESS);
157 : }
158 :
159 : /*@
160 : RGGetOptionsPrefix - Gets the prefix used for searching for all
161 : RG options in the database.
162 :
163 : Not Collective
164 :
165 : Input Parameters:
166 : . rg - the region context
167 :
168 : Output Parameters:
169 : . prefix - pointer to the prefix string used is returned
170 :
171 : Note:
172 : On the Fortran side, the user should pass in a string 'prefix' of
173 : sufficient length to hold the prefix.
174 :
175 : Level: advanced
176 :
177 : .seealso: RGSetOptionsPrefix(), RGAppendOptionsPrefix()
178 : @*/
179 0 : PetscErrorCode RGGetOptionsPrefix(RG rg,const char *prefix[])
180 : {
181 0 : PetscFunctionBegin;
182 0 : PetscValidHeaderSpecific(rg,RG_CLASSID,1);
183 0 : PetscAssertPointer(prefix,2);
184 0 : PetscCall(PetscObjectGetOptionsPrefix((PetscObject)rg,prefix));
185 0 : PetscFunctionReturn(PETSC_SUCCESS);
186 : }
187 :
188 : /*@
189 : RGSetType - Selects the type for the RG object.
190 :
191 : Logically Collective
192 :
193 : Input Parameters:
194 : + rg - the region context
195 : - type - a known type
196 :
197 : Level: intermediate
198 :
199 : .seealso: RGGetType()
200 : @*/
201 1056 : PetscErrorCode RGSetType(RG rg,RGType type)
202 : {
203 1056 : PetscErrorCode (*r)(RG);
204 1056 : PetscBool match;
205 :
206 1056 : PetscFunctionBegin;
207 1056 : PetscValidHeaderSpecific(rg,RG_CLASSID,1);
208 1056 : PetscAssertPointer(type,2);
209 :
210 1056 : PetscCall(PetscObjectTypeCompare((PetscObject)rg,type,&match));
211 1056 : if (match) PetscFunctionReturn(PETSC_SUCCESS);
212 :
213 969 : PetscCall(PetscFunctionListFind(RGList,type,&r));
214 969 : PetscCheck(r,PetscObjectComm((PetscObject)rg),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested RG type %s",type);
215 :
216 969 : PetscTryTypeMethod(rg,destroy);
217 969 : PetscCall(PetscMemzero(rg->ops,sizeof(struct _RGOps)));
218 :
219 969 : PetscCall(PetscObjectChangeTypeName((PetscObject)rg,type));
220 969 : PetscCall((*r)(rg));
221 969 : PetscFunctionReturn(PETSC_SUCCESS);
222 : }
223 :
224 : /*@
225 : RGGetType - Gets the RG type name (as a string) from the RG context.
226 :
227 : Not Collective
228 :
229 : Input Parameter:
230 : . rg - the region context
231 :
232 : Output Parameter:
233 : . type - name of the region
234 :
235 : Level: intermediate
236 :
237 : .seealso: RGSetType()
238 : @*/
239 5 : PetscErrorCode RGGetType(RG rg,RGType *type)
240 : {
241 5 : PetscFunctionBegin;
242 5 : PetscValidHeaderSpecific(rg,RG_CLASSID,1);
243 5 : PetscAssertPointer(type,2);
244 5 : *type = ((PetscObject)rg)->type_name;
245 5 : PetscFunctionReturn(PETSC_SUCCESS);
246 : }
247 :
248 : /*@
249 : RGSetFromOptions - Sets RG options from the options database.
250 :
251 : Collective
252 :
253 : Input Parameters:
254 : . rg - the region context
255 :
256 : Notes:
257 : To see all options, run your program with the -help option.
258 :
259 : Level: beginner
260 :
261 : .seealso: RGSetOptionsPrefix()
262 : @*/
263 986 : PetscErrorCode RGSetFromOptions(RG rg)
264 : {
265 986 : char type[256];
266 986 : PetscBool flg;
267 986 : PetscReal sfactor;
268 :
269 986 : PetscFunctionBegin;
270 986 : PetscValidHeaderSpecific(rg,RG_CLASSID,1);
271 986 : PetscCall(RGRegisterAll());
272 2958 : PetscObjectOptionsBegin((PetscObject)rg);
273 1143 : PetscCall(PetscOptionsFList("-rg_type","Region type","RGSetType",RGList,(char*)(((PetscObject)rg)->type_name?((PetscObject)rg)->type_name:RGINTERVAL),type,sizeof(type),&flg));
274 986 : if (flg) PetscCall(RGSetType(rg,type));
275 818 : else if (!((PetscObject)rg)->type_name) PetscCall(RGSetType(rg,RGINTERVAL));
276 :
277 986 : PetscCall(PetscOptionsBool("-rg_complement","Whether region is complemented or not","RGSetComplement",rg->complement,&rg->complement,NULL));
278 :
279 986 : PetscCall(PetscOptionsReal("-rg_scale","Scaling factor","RGSetScale",1.0,&sfactor,&flg));
280 986 : if (flg) PetscCall(RGSetScale(rg,sfactor));
281 :
282 986 : PetscTryTypeMethod(rg,setfromoptions,PetscOptionsObject);
283 986 : PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)rg,PetscOptionsObject));
284 986 : PetscOptionsEnd();
285 986 : PetscFunctionReturn(PETSC_SUCCESS);
286 : }
287 :
288 : /*@
289 : RGView - Prints the RG data structure.
290 :
291 : Collective
292 :
293 : Input Parameters:
294 : + rg - the region context
295 : - viewer - optional visualization context
296 :
297 : Note:
298 : The available visualization contexts include
299 : + PETSC_VIEWER_STDOUT_SELF - standard output (default)
300 : - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
301 : output where only the first processor opens
302 : the file. All other processors send their
303 : data to the first processor to print.
304 :
305 : The user can open an alternative visualization context with
306 : PetscViewerASCIIOpen() - output to a specified file.
307 :
308 : Level: beginner
309 :
310 : .seealso: RGCreate()
311 : @*/
312 20 : PetscErrorCode RGView(RG rg,PetscViewer viewer)
313 : {
314 20 : PetscBool isdraw,isascii;
315 :
316 20 : PetscFunctionBegin;
317 20 : PetscValidHeaderSpecific(rg,RG_CLASSID,1);
318 20 : if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)rg),&viewer));
319 20 : PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
320 20 : PetscCheckSameComm(rg,1,viewer,2);
321 20 : PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw));
322 20 : PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
323 20 : if (isascii) {
324 16 : PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)rg,viewer));
325 16 : PetscCall(PetscViewerASCIIPushTab(viewer));
326 16 : PetscTryTypeMethod(rg,view,viewer);
327 16 : PetscCall(PetscViewerASCIIPopTab(viewer));
328 16 : if (rg->complement) PetscCall(PetscViewerASCIIPrintf(viewer," selected region is the complement of the specified one\n"));
329 16 : if (rg->sfactor!=1.0) PetscCall(PetscViewerASCIIPrintf(viewer," scaling factor = %g\n",(double)rg->sfactor));
330 4 : } else if (isdraw) PetscTryTypeMethod(rg,view,viewer);
331 20 : PetscFunctionReturn(PETSC_SUCCESS);
332 : }
333 :
334 : /*@
335 : RGViewFromOptions - View from options
336 :
337 : Collective
338 :
339 : Input Parameters:
340 : + rg - the region context
341 : . obj - optional object
342 : - name - command line option
343 :
344 : Level: intermediate
345 :
346 : .seealso: RGView(), RGCreate()
347 : @*/
348 1203 : PetscErrorCode RGViewFromOptions(RG rg,PetscObject obj,const char name[])
349 : {
350 1203 : PetscFunctionBegin;
351 1203 : PetscValidHeaderSpecific(rg,RG_CLASSID,1);
352 1203 : PetscCall(PetscObjectViewFromOptions((PetscObject)rg,obj,name));
353 1203 : PetscFunctionReturn(PETSC_SUCCESS);
354 : }
355 :
356 : /*@
357 : RGIsTrivial - Whether it is the trivial region (whole complex plane).
358 :
359 : Not Collective
360 :
361 : Input Parameter:
362 : . rg - the region context
363 :
364 : Output Parameter:
365 : . trivial - true if the region is equal to the whole complex plane, e.g.,
366 : an interval region with all four endpoints unbounded or an
367 : ellipse with infinite radius.
368 :
369 : Level: beginner
370 :
371 : .seealso: RGCheckInside()
372 : @*/
373 6087 : PetscErrorCode RGIsTrivial(RG rg,PetscBool *trivial)
374 : {
375 6087 : PetscFunctionBegin;
376 6087 : PetscValidHeaderSpecific(rg,RG_CLASSID,1);
377 6087 : PetscValidType(rg,1);
378 6087 : PetscAssertPointer(trivial,2);
379 6087 : *trivial = PETSC_FALSE;
380 6087 : PetscTryTypeMethod(rg,istrivial,trivial);
381 6087 : PetscFunctionReturn(PETSC_SUCCESS);
382 : }
383 :
384 : /*@
385 : RGCheckInside - Determines if a set of given points are inside the region or not.
386 :
387 : Not Collective
388 :
389 : Input Parameters:
390 : + rg - the region context
391 : . n - number of points to check
392 : . ar - array of real parts
393 : - ai - array of imaginary parts
394 :
395 : Output Parameter:
396 : . inside - array of results (1=inside, 0=on the contour, -1=outside)
397 :
398 : Note:
399 : The point a is expressed as a couple of PetscScalar variables ar,ai.
400 : If built with complex scalars, the point is supposed to be stored in ar,
401 : otherwise ar,ai contain the real and imaginary parts, respectively.
402 :
403 : If a scaling factor was set, the points are scaled before checking.
404 :
405 : Level: intermediate
406 :
407 : .seealso: RGSetScale(), RGSetComplement()
408 : @*/
409 114530 : PetscErrorCode RGCheckInside(RG rg,PetscInt n,PetscScalar *ar,PetscScalar *ai,PetscInt *inside)
410 : {
411 114530 : PetscReal px,py;
412 114530 : PetscInt i;
413 :
414 114530 : PetscFunctionBegin;
415 114530 : PetscValidHeaderSpecific(rg,RG_CLASSID,1);
416 114530 : PetscValidType(rg,1);
417 114530 : PetscAssertPointer(ar,3);
418 : #if !defined(PETSC_USE_COMPLEX)
419 : PetscAssertPointer(ai,4);
420 : #endif
421 114530 : PetscAssertPointer(inside,5);
422 :
423 345433 : for (i=0;i<n;i++) {
424 : #if defined(PETSC_USE_COMPLEX)
425 230903 : px = PetscRealPart(ar[i]);
426 230903 : py = PetscImaginaryPart(ar[i]);
427 : #else
428 : px = ar[i];
429 : py = ai[i];
430 : #endif
431 230903 : if (PetscUnlikely(rg->sfactor != 1.0)) {
432 2 : px /= rg->sfactor;
433 2 : py /= rg->sfactor;
434 : }
435 230903 : PetscUseTypeMethod(rg,checkinside,px,py,inside+i);
436 230903 : if (PetscUnlikely(rg->complement)) inside[i] = -inside[i];
437 : }
438 114530 : PetscFunctionReturn(PETSC_SUCCESS);
439 : }
440 :
441 : /*@
442 : RGIsAxisymmetric - Determines if the region is symmetric with respect
443 : to the real or imaginary axis.
444 :
445 : Not Collective
446 :
447 : Input Parameters:
448 : + rg - the region context
449 : - vertical - true if symmetry must be checked against the vertical axis
450 :
451 : Output Parameter:
452 : . symm - true if the region is axisymmetric
453 :
454 : Note:
455 : If the vertical argument is true, symmetry is checked with respect to
456 : the vertical axis, otherwise with respect to the horizontal axis.
457 :
458 : Level: intermediate
459 :
460 : .seealso: RGCanUseConjugates()
461 : @*/
462 42 : PetscErrorCode RGIsAxisymmetric(RG rg,PetscBool vertical,PetscBool *symm)
463 : {
464 42 : PetscFunctionBegin;
465 42 : PetscValidHeaderSpecific(rg,RG_CLASSID,1);
466 42 : PetscValidType(rg,1);
467 42 : PetscAssertPointer(symm,3);
468 42 : *symm = PETSC_FALSE;
469 42 : PetscTryTypeMethod(rg,isaxisymmetric,vertical,symm);
470 42 : PetscFunctionReturn(PETSC_SUCCESS);
471 : }
472 :
473 : /*@
474 : RGCanUseConjugates - Used in contour integral methods to determine whether
475 : half of integration points can be avoided (use their conjugates).
476 :
477 : Not Collective
478 :
479 : Input Parameters:
480 : + rg - the region context
481 : - realmats - true if the problem matrices are real
482 :
483 : Output Parameter:
484 : . useconj - whether it is possible to use conjugates
485 :
486 : Notes:
487 : If some integration points are the conjugates of other points, then the
488 : associated computational cost can be saved. This depends on the problem
489 : matrices being real and also the region being symmetric with respect to
490 : the horizontal axis. The result is false if using real arithmetic or
491 : in the case of a flat region (height equal to zero).
492 :
493 : Level: developer
494 :
495 : .seealso: RGIsAxisymmetric()
496 : @*/
497 90 : PetscErrorCode RGCanUseConjugates(RG rg,PetscBool realmats,PetscBool *useconj)
498 : {
499 : #if defined(PETSC_USE_COMPLEX)
500 90 : PetscReal c,d;
501 90 : PetscBool isaxisymm;
502 : #endif
503 :
504 90 : PetscFunctionBegin;
505 90 : PetscValidHeaderSpecific(rg,RG_CLASSID,1);
506 90 : PetscValidType(rg,1);
507 90 : PetscAssertPointer(useconj,3);
508 90 : *useconj = PETSC_FALSE;
509 : #if defined(PETSC_USE_COMPLEX)
510 90 : if (realmats) {
511 28 : PetscCall(RGIsAxisymmetric(rg,PETSC_FALSE,&isaxisymm));
512 28 : if (isaxisymm) {
513 27 : PetscCall(RGComputeBoundingBox(rg,NULL,NULL,&c,&d));
514 27 : if (c!=d) *useconj = PETSC_TRUE;
515 : }
516 : }
517 : #endif
518 90 : PetscFunctionReturn(PETSC_SUCCESS);
519 : }
520 :
521 : /*@
522 : RGComputeContour - Computes the coordinates of several points lying on the
523 : contour of the region.
524 :
525 : Not Collective
526 :
527 : Input Parameters:
528 : + rg - the region context
529 : - n - number of points to compute
530 :
531 : Output Parameters:
532 : + cr - location to store real parts
533 : - ci - location to store imaginary parts
534 :
535 : Notes:
536 : In real scalars, either cr or ci can be NULL (but not both). In complex
537 : scalars, the coordinates are stored in cr, which cannot be NULL (ci is
538 : not referenced).
539 :
540 : Level: intermediate
541 :
542 : .seealso: RGComputeBoundingBox()
543 : @*/
544 151 : PetscErrorCode RGComputeContour(RG rg,PetscInt n,PetscScalar cr[],PetscScalar ci[])
545 : {
546 151 : PetscInt i;
547 :
548 151 : PetscFunctionBegin;
549 151 : PetscValidHeaderSpecific(rg,RG_CLASSID,1);
550 151 : PetscValidType(rg,1);
551 : #if defined(PETSC_USE_COMPLEX)
552 151 : PetscAssertPointer(cr,3);
553 : #else
554 : PetscCheck(cr || ci,PetscObjectComm((PetscObject)rg),PETSC_ERR_SUP,"cr and ci cannot be NULL simultaneously");
555 : #endif
556 151 : PetscCheck(!rg->complement,PetscObjectComm((PetscObject)rg),PETSC_ERR_SUP,"Cannot compute contour of region with complement flag set");
557 151 : PetscUseTypeMethod(rg,computecontour,n,cr,ci);
558 155866 : for (i=0;i<n;i++) {
559 155715 : if (cr) cr[i] *= rg->sfactor;
560 155715 : if (ci) ci[i] *= rg->sfactor;
561 : }
562 151 : PetscFunctionReturn(PETSC_SUCCESS);
563 : }
564 :
565 : /*@
566 : RGComputeBoundingBox - Determines the endpoints of a rectangle in the complex plane that
567 : contains the region.
568 :
569 : Not Collective
570 :
571 : Input Parameter:
572 : . rg - the region context
573 :
574 : Output Parameters:
575 : + a - left endpoint of the bounding box in the real axis
576 : . b - right endpoint of the bounding box in the real axis
577 : . c - bottom endpoint of the bounding box in the imaginary axis
578 : - d - top endpoint of the bounding box in the imaginary axis
579 :
580 : Notes:
581 : The bounding box is defined as [a,b]x[c,d]. In regions that are not bounded (e.g. an
582 : open interval) or with the complement flag set, it makes no sense to compute a bounding
583 : box, so the return values are infinite.
584 :
585 : Level: intermediate
586 :
587 : .seealso: RGComputeContour()
588 : @*/
589 38 : PetscErrorCode RGComputeBoundingBox(RG rg,PetscReal *a,PetscReal *b,PetscReal *c,PetscReal *d)
590 : {
591 38 : PetscFunctionBegin;
592 38 : PetscValidHeaderSpecific(rg,RG_CLASSID,1);
593 38 : PetscValidType(rg,1);
594 :
595 38 : if (rg->complement) { /* cannot compute bounding box */
596 0 : if (a) *a = -PETSC_MAX_REAL;
597 0 : if (b) *b = PETSC_MAX_REAL;
598 0 : if (c) *c = -PETSC_MAX_REAL;
599 0 : if (d) *d = PETSC_MAX_REAL;
600 : } else {
601 38 : PetscUseTypeMethod(rg,computebbox,a,b,c,d);
602 38 : if (a && *a!=-PETSC_MAX_REAL) *a *= rg->sfactor;
603 38 : if (b && *b!= PETSC_MAX_REAL) *b *= rg->sfactor;
604 38 : if (c && *c!=-PETSC_MAX_REAL) *c *= rg->sfactor;
605 38 : if (d && *d!= PETSC_MAX_REAL) *d *= rg->sfactor;
606 : }
607 38 : PetscFunctionReturn(PETSC_SUCCESS);
608 : }
609 :
610 : /*@
611 : RGComputeQuadrature - Computes the values of the parameters used in a
612 : quadrature rule for a contour integral around the boundary of the region.
613 :
614 : Not Collective
615 :
616 : Input Parameters:
617 : + rg - the region context
618 : . quad - the type of quadrature
619 : - n - number of quadrature points to compute
620 :
621 : Output Parameters:
622 : + z - quadrature points
623 : . zn - normalized quadrature points
624 : - w - quadrature weights
625 :
626 : Notes:
627 : In complex scalars, the values returned in z are often the same as those
628 : computed by RGComputeContour(), but this is not the case in real scalars
629 : where all output arguments are real.
630 :
631 : The computed values change for different quadrature rules (trapezoidal
632 : or Chebyshev).
633 :
634 : Level: intermediate
635 :
636 : .seealso: RGComputeContour()
637 : @*/
638 113 : PetscErrorCode RGComputeQuadrature(RG rg,RGQuadRule quad,PetscInt n,PetscScalar z[],PetscScalar zn[],PetscScalar w[])
639 : {
640 113 : PetscFunctionBegin;
641 113 : PetscValidHeaderSpecific(rg,RG_CLASSID,1);
642 113 : PetscValidType(rg,1);
643 113 : PetscAssertPointer(z,4);
644 113 : PetscAssertPointer(zn,5);
645 113 : PetscAssertPointer(w,6);
646 :
647 113 : PetscCall(RGComputeContour(rg,n,z,NULL));
648 113 : PetscUseTypeMethod(rg,computequadrature,quad,n,z,zn,w);
649 113 : PetscFunctionReturn(PETSC_SUCCESS);
650 : }
651 :
652 : /*@
653 : RGSetComplement - Sets a flag to indicate that the region is the complement
654 : of the specified one.
655 :
656 : Logically Collective
657 :
658 : Input Parameters:
659 : + rg - the region context
660 : - flg - the boolean flag
661 :
662 : Options Database Key:
663 : . -rg_complement <bool> - Activate/deactivate the complementation of the region
664 :
665 : Level: intermediate
666 :
667 : .seealso: RGGetComplement()
668 : @*/
669 1 : PetscErrorCode RGSetComplement(RG rg,PetscBool flg)
670 : {
671 1 : PetscFunctionBegin;
672 1 : PetscValidHeaderSpecific(rg,RG_CLASSID,1);
673 3 : PetscValidLogicalCollectiveBool(rg,flg,2);
674 1 : rg->complement = flg;
675 1 : PetscFunctionReturn(PETSC_SUCCESS);
676 : }
677 :
678 : /*@
679 : RGGetComplement - Gets a flag that indicates whether the region
680 : is complemented or not.
681 :
682 : Not Collective
683 :
684 : Input Parameter:
685 : . rg - the region context
686 :
687 : Output Parameter:
688 : . flg - the flag
689 :
690 : Level: intermediate
691 :
692 : .seealso: RGSetComplement()
693 : @*/
694 86 : PetscErrorCode RGGetComplement(RG rg,PetscBool *flg)
695 : {
696 86 : PetscFunctionBegin;
697 86 : PetscValidHeaderSpecific(rg,RG_CLASSID,1);
698 86 : PetscAssertPointer(flg,2);
699 86 : *flg = rg->complement;
700 86 : PetscFunctionReturn(PETSC_SUCCESS);
701 : }
702 :
703 : /*@
704 : RGSetScale - Sets the scaling factor to be used when checking that a
705 : point is inside the region and when computing the contour.
706 :
707 : Logically Collective
708 :
709 : Input Parameters:
710 : + rg - the region context
711 : - sfactor - the scaling factor
712 :
713 : Options Database Key:
714 : . -rg_scale <real> - Sets the scaling factor
715 :
716 : Level: advanced
717 :
718 : .seealso: RGGetScale(), RGCheckInside()
719 : @*/
720 1 : PetscErrorCode RGSetScale(RG rg,PetscReal sfactor)
721 : {
722 1 : PetscFunctionBegin;
723 1 : PetscValidHeaderSpecific(rg,RG_CLASSID,1);
724 3 : PetscValidLogicalCollectiveReal(rg,sfactor,2);
725 1 : if (sfactor == (PetscReal)PETSC_DEFAULT || sfactor == (PetscReal)PETSC_DECIDE) sfactor = 1.0;
726 1 : PetscCheck(sfactor>0.0,PetscObjectComm((PetscObject)rg),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of scaling factor. Must be > 0");
727 1 : rg->sfactor = sfactor;
728 1 : PetscFunctionReturn(PETSC_SUCCESS);
729 : }
730 :
731 : /*@
732 : RGGetScale - Gets the scaling factor.
733 :
734 : Not Collective
735 :
736 : Input Parameter:
737 : . rg - the region context
738 :
739 : Output Parameter:
740 : . sfactor - the scaling factor
741 :
742 : Level: advanced
743 :
744 : .seealso: RGSetScale()
745 : @*/
746 150 : PetscErrorCode RGGetScale(RG rg,PetscReal *sfactor)
747 : {
748 150 : PetscFunctionBegin;
749 150 : PetscValidHeaderSpecific(rg,RG_CLASSID,1);
750 150 : PetscAssertPointer(sfactor,2);
751 150 : *sfactor = rg->sfactor;
752 150 : PetscFunctionReturn(PETSC_SUCCESS);
753 : }
754 :
755 : /*@
756 : RGPushScale - Sets an additional scaling factor, that will multiply the
757 : user-defined scaling factor.
758 :
759 : Logically Collective
760 :
761 : Input Parameters:
762 : + rg - the region context
763 : - sfactor - the scaling factor
764 :
765 : Notes:
766 : The current implementation does not allow pushing several scaling factors.
767 :
768 : This is intended for internal use, for instance in polynomial eigensolvers
769 : that use parameter scaling.
770 :
771 : Level: developer
772 :
773 : .seealso: RGPopScale(), RGSetScale()
774 : @*/
775 80 : PetscErrorCode RGPushScale(RG rg,PetscReal sfactor)
776 : {
777 80 : PetscFunctionBegin;
778 80 : PetscValidHeaderSpecific(rg,RG_CLASSID,1);
779 240 : PetscValidLogicalCollectiveReal(rg,sfactor,2);
780 80 : PetscCheck(sfactor>0.0,PetscObjectComm((PetscObject)rg),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of scaling factor. Must be > 0");
781 80 : PetscCheck(!rg->osfactor,PetscObjectComm((PetscObject)rg),PETSC_ERR_SUP,"Current implementation does not allow pushing several scaling factors");
782 80 : rg->osfactor = rg->sfactor;
783 80 : rg->sfactor *= sfactor;
784 80 : PetscFunctionReturn(PETSC_SUCCESS);
785 : }
786 :
787 : /*@
788 : RGPopScale - Pops the scaling factor set with RGPushScale().
789 :
790 : Logically Collective
791 :
792 : Input Parameter:
793 : . rg - the region context
794 :
795 : Level: developer
796 :
797 : .seealso: RGPushScale()
798 : @*/
799 80 : PetscErrorCode RGPopScale(RG rg)
800 : {
801 80 : PetscFunctionBegin;
802 80 : PetscValidHeaderSpecific(rg,RG_CLASSID,1);
803 80 : PetscCheck(rg->osfactor,PetscObjectComm((PetscObject)rg),PETSC_ERR_ORDER,"Must call RGPushScale first");
804 80 : rg->sfactor = rg->osfactor;
805 80 : rg->osfactor = 0.0;
806 80 : PetscFunctionReturn(PETSC_SUCCESS);
807 : }
808 :
809 : /*@
810 : RGDestroy - Destroys RG context that was created with RGCreate().
811 :
812 : Collective
813 :
814 : Input Parameter:
815 : . rg - the region context
816 :
817 : Level: beginner
818 :
819 : .seealso: RGCreate()
820 : @*/
821 1031 : PetscErrorCode RGDestroy(RG *rg)
822 : {
823 1031 : PetscFunctionBegin;
824 1031 : if (!*rg) PetscFunctionReturn(PETSC_SUCCESS);
825 985 : PetscValidHeaderSpecific(*rg,RG_CLASSID,1);
826 985 : if (--((PetscObject)*rg)->refct > 0) { *rg = NULL; PetscFunctionReturn(PETSC_SUCCESS); }
827 949 : PetscTryTypeMethod(*rg,destroy);
828 949 : PetscCall(PetscHeaderDestroy(rg));
829 949 : PetscFunctionReturn(PETSC_SUCCESS);
830 : }
831 :
832 : /*@C
833 : RGRegister - Adds a region to the RG package.
834 :
835 : Not Collective
836 :
837 : Input Parameters:
838 : + name - name of a new user-defined RG
839 : - function - routine to create context
840 :
841 : Notes:
842 : RGRegister() may be called multiple times to add several user-defined regions.
843 :
844 : Level: advanced
845 :
846 : .seealso: RGRegisterAll()
847 : @*/
848 3256 : PetscErrorCode RGRegister(const char *name,PetscErrorCode (*function)(RG))
849 : {
850 3256 : PetscFunctionBegin;
851 3256 : PetscCall(RGInitializePackage());
852 3256 : PetscCall(PetscFunctionListAdd(&RGList,name,function));
853 3256 : PetscFunctionReturn(PETSC_SUCCESS);
854 : }
|