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 DS routines
12 : */
13 :
14 : #include <slepc/private/dsimpl.h> /*I "slepcds.h" I*/
15 :
16 : PetscFunctionList DSList = NULL;
17 : PetscBool DSRegisterAllCalled = PETSC_FALSE;
18 : PetscClassId DS_CLASSID = 0;
19 : PetscLogEvent DS_Solve = 0,DS_Vectors = 0,DS_Synchronize = 0,DS_Other = 0;
20 : static PetscBool DSPackageInitialized = PETSC_FALSE;
21 :
22 : const char *DSStateTypes[] = {"RAW","INTERMEDIATE","CONDENSED","TRUNCATED","DSStateType","DS_STATE_",NULL};
23 : const char *DSParallelTypes[] = {"REDUNDANT","SYNCHRONIZED","DISTRIBUTED","DSParallelType","DS_PARALLEL_",NULL};
24 : const char *DSMatName[DS_NUM_MAT] = {"A","B","C","T","D","Q","Z","X","Y","U","V","W","E0","E1","E2","E3","E4","E5","E6","E7","E8","E9"};
25 : DSMatType DSMatExtra[DS_NUM_EXTRA] = {DS_MAT_E0,DS_MAT_E1,DS_MAT_E2,DS_MAT_E3,DS_MAT_E4,DS_MAT_E5,DS_MAT_E6,DS_MAT_E7,DS_MAT_E8,DS_MAT_E9};
26 :
27 : /*@C
28 : DSFinalizePackage - This function destroys everything in the SLEPc interface
29 : to the DS package. It is called from SlepcFinalize().
30 :
31 : Level: developer
32 :
33 : .seealso: SlepcFinalize()
34 : @*/
35 966 : PetscErrorCode DSFinalizePackage(void)
36 : {
37 966 : PetscFunctionBegin;
38 966 : PetscCall(PetscFunctionListDestroy(&DSList));
39 966 : DSPackageInitialized = PETSC_FALSE;
40 966 : DSRegisterAllCalled = PETSC_FALSE;
41 966 : PetscFunctionReturn(PETSC_SUCCESS);
42 : }
43 :
44 : /*@C
45 : DSInitializePackage - This function initializes everything in the DS package.
46 : It is called from PetscDLLibraryRegister() when using dynamic libraries, and
47 : on the first call to DSCreate() when using static libraries.
48 :
49 : Level: developer
50 :
51 : .seealso: SlepcInitialize()
52 : @*/
53 11784 : PetscErrorCode DSInitializePackage(void)
54 : {
55 11784 : char logList[256];
56 11784 : PetscBool opt,pkg;
57 11784 : PetscClassId classids[1];
58 :
59 11784 : PetscFunctionBegin;
60 11784 : if (DSPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS);
61 966 : DSPackageInitialized = PETSC_TRUE;
62 : /* Register Classes */
63 966 : PetscCall(PetscClassIdRegister("Direct Solver",&DS_CLASSID));
64 : /* Register Constructors */
65 966 : PetscCall(DSRegisterAll());
66 : /* Register Events */
67 966 : PetscCall(PetscLogEventRegister("DSSolve",DS_CLASSID,&DS_Solve));
68 966 : PetscCall(PetscLogEventRegister("DSVectors",DS_CLASSID,&DS_Vectors));
69 966 : PetscCall(PetscLogEventRegister("DSSynchronize",DS_CLASSID,&DS_Synchronize));
70 966 : PetscCall(PetscLogEventRegister("DSOther",DS_CLASSID,&DS_Other));
71 : /* Process Info */
72 966 : classids[0] = DS_CLASSID;
73 966 : PetscCall(PetscInfoProcessClass("ds",1,&classids[0]));
74 : /* Process summary exclusions */
75 966 : PetscCall(PetscOptionsGetString(NULL,NULL,"-log_exclude",logList,sizeof(logList),&opt));
76 966 : if (opt) {
77 8 : PetscCall(PetscStrInList("ds",logList,',',&pkg));
78 8 : if (pkg) PetscCall(PetscLogEventDeactivateClass(DS_CLASSID));
79 : }
80 : /* Register package finalizer */
81 966 : PetscCall(PetscRegisterFinalize(DSFinalizePackage));
82 966 : PetscFunctionReturn(PETSC_SUCCESS);
83 : }
84 :
85 : /*@
86 : DSCreate - Creates a DS context.
87 :
88 : Collective
89 :
90 : Input Parameter:
91 : . comm - MPI communicator
92 :
93 : Output Parameter:
94 : . newds - location to put the DS context
95 :
96 : Level: beginner
97 :
98 : Note:
99 : DS objects are not intended for normal users but only for
100 : advanced user that for instance implement their own solvers.
101 :
102 : .seealso: DSDestroy(), DS
103 : @*/
104 1157 : PetscErrorCode DSCreate(MPI_Comm comm,DS *newds)
105 : {
106 1157 : DS ds;
107 1157 : PetscInt i;
108 :
109 1157 : PetscFunctionBegin;
110 1157 : PetscAssertPointer(newds,2);
111 1157 : *newds = NULL;
112 1157 : PetscCall(DSInitializePackage());
113 1157 : PetscCall(SlepcHeaderCreate(ds,DS_CLASSID,"DS","Direct Solver (or Dense System)","DS",comm,DSDestroy,DSView));
114 :
115 1157 : ds->state = DS_STATE_RAW;
116 1157 : ds->method = 0;
117 1157 : ds->compact = PETSC_FALSE;
118 1157 : ds->refined = PETSC_FALSE;
119 1157 : ds->extrarow = PETSC_FALSE;
120 1157 : ds->ld = 0;
121 1157 : ds->l = 0;
122 1157 : ds->n = 0;
123 1157 : ds->k = 0;
124 1157 : ds->t = 0;
125 1157 : ds->bs = 1;
126 1157 : ds->sc = NULL;
127 1157 : ds->pmode = DS_PARALLEL_REDUNDANT;
128 :
129 26611 : for (i=0;i<DS_NUM_MAT;i++) ds->omat[i] = NULL;
130 1157 : ds->perm = NULL;
131 1157 : ds->data = NULL;
132 1157 : ds->scset = PETSC_FALSE;
133 1157 : ds->work = NULL;
134 1157 : ds->rwork = NULL;
135 1157 : ds->iwork = NULL;
136 1157 : ds->lwork = 0;
137 1157 : ds->lrwork = 0;
138 1157 : ds->liwork = 0;
139 :
140 1157 : *newds = ds;
141 1157 : PetscFunctionReturn(PETSC_SUCCESS);
142 : }
143 :
144 : /*@C
145 : DSSetOptionsPrefix - Sets the prefix used for searching for all
146 : DS options in the database.
147 :
148 : Logically Collective
149 :
150 : Input Parameters:
151 : + ds - the direct solver context
152 : - prefix - the prefix string to prepend to all DS option requests
153 :
154 : Notes:
155 : A hyphen (-) must NOT be given at the beginning of the prefix name.
156 : The first character of all runtime options is AUTOMATICALLY the
157 : hyphen.
158 :
159 : Level: advanced
160 :
161 : .seealso: DSAppendOptionsPrefix()
162 : @*/
163 214 : PetscErrorCode DSSetOptionsPrefix(DS ds,const char *prefix)
164 : {
165 214 : PetscFunctionBegin;
166 214 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
167 214 : PetscCall(PetscObjectSetOptionsPrefix((PetscObject)ds,prefix));
168 214 : PetscFunctionReturn(PETSC_SUCCESS);
169 : }
170 :
171 : /*@C
172 : DSAppendOptionsPrefix - Appends to the prefix used for searching for all
173 : DS options in the database.
174 :
175 : Logically Collective
176 :
177 : Input Parameters:
178 : + ds - the direct solver context
179 : - prefix - the prefix string to prepend to all DS option requests
180 :
181 : Notes:
182 : A hyphen (-) must NOT be given at the beginning of the prefix name.
183 : The first character of all runtime options is AUTOMATICALLY the hyphen.
184 :
185 : Level: advanced
186 :
187 : .seealso: DSSetOptionsPrefix()
188 : @*/
189 178 : PetscErrorCode DSAppendOptionsPrefix(DS ds,const char *prefix)
190 : {
191 178 : PetscFunctionBegin;
192 178 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
193 178 : PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)ds,prefix));
194 178 : PetscFunctionReturn(PETSC_SUCCESS);
195 : }
196 :
197 : /*@C
198 : DSGetOptionsPrefix - Gets the prefix used for searching for all
199 : DS options in the database.
200 :
201 : Not Collective
202 :
203 : Input Parameters:
204 : . ds - the direct solver context
205 :
206 : Output Parameters:
207 : . prefix - pointer to the prefix string used is returned
208 :
209 : Note:
210 : On the Fortran side, the user should pass in a string 'prefix' of
211 : sufficient length to hold the prefix.
212 :
213 : Level: advanced
214 :
215 : .seealso: DSSetOptionsPrefix(), DSAppendOptionsPrefix()
216 : @*/
217 0 : PetscErrorCode DSGetOptionsPrefix(DS ds,const char *prefix[])
218 : {
219 0 : PetscFunctionBegin;
220 0 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
221 0 : PetscAssertPointer(prefix,2);
222 0 : PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ds,prefix));
223 0 : PetscFunctionReturn(PETSC_SUCCESS);
224 : }
225 :
226 : /*@C
227 : DSSetType - Selects the type for the DS object.
228 :
229 : Logically Collective
230 :
231 : Input Parameters:
232 : + ds - the direct solver context
233 : - type - a known type
234 :
235 : Level: intermediate
236 :
237 : .seealso: DSGetType()
238 : @*/
239 2334 : PetscErrorCode DSSetType(DS ds,DSType type)
240 : {
241 2334 : PetscErrorCode (*r)(DS);
242 2334 : PetscBool match;
243 :
244 2334 : PetscFunctionBegin;
245 2334 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
246 2334 : PetscAssertPointer(type,2);
247 :
248 2334 : PetscCall(PetscObjectTypeCompare((PetscObject)ds,type,&match));
249 2334 : if (match) PetscFunctionReturn(PETSC_SUCCESS);
250 :
251 1505 : PetscCall(PetscFunctionListFind(DSList,type,&r));
252 1505 : PetscCheck(r,PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested DS type %s",type);
253 :
254 1505 : PetscTryTypeMethod(ds,destroy);
255 1505 : PetscCall(PetscMemzero(ds->ops,sizeof(struct _DSOps)));
256 :
257 1505 : PetscCall(PetscObjectChangeTypeName((PetscObject)ds,type));
258 1505 : PetscCall((*r)(ds));
259 1505 : PetscFunctionReturn(PETSC_SUCCESS);
260 : }
261 :
262 : /*@C
263 : DSGetType - Gets the DS type name (as a string) from the DS context.
264 :
265 : Not Collective
266 :
267 : Input Parameter:
268 : . ds - the direct solver context
269 :
270 : Output Parameter:
271 : . type - name of the direct solver
272 :
273 : Level: intermediate
274 :
275 : .seealso: DSSetType()
276 : @*/
277 2 : PetscErrorCode DSGetType(DS ds,DSType *type)
278 : {
279 2 : PetscFunctionBegin;
280 2 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
281 2 : PetscAssertPointer(type,2);
282 2 : *type = ((PetscObject)ds)->type_name;
283 2 : PetscFunctionReturn(PETSC_SUCCESS);
284 : }
285 :
286 : /*@
287 : DSDuplicate - Creates a new direct solver object with the same options as
288 : an existing one.
289 :
290 : Collective
291 :
292 : Input Parameter:
293 : . ds - direct solver context
294 :
295 : Output Parameter:
296 : . dsnew - location to put the new DS
297 :
298 : Notes:
299 : DSDuplicate() DOES NOT COPY the matrices, and the new DS does not even have
300 : internal arrays allocated. Use DSAllocate() to use the new DS.
301 :
302 : The sorting criterion options are not copied, see DSSetSlepcSC().
303 :
304 : Level: intermediate
305 :
306 : .seealso: DSCreate(), DSAllocate(), DSSetSlepcSC()
307 : @*/
308 0 : PetscErrorCode DSDuplicate(DS ds,DS *dsnew)
309 : {
310 0 : PetscFunctionBegin;
311 0 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
312 0 : PetscAssertPointer(dsnew,2);
313 0 : PetscCall(DSCreate(PetscObjectComm((PetscObject)ds),dsnew));
314 0 : if (((PetscObject)ds)->type_name) PetscCall(DSSetType(*dsnew,((PetscObject)ds)->type_name));
315 0 : (*dsnew)->method = ds->method;
316 0 : (*dsnew)->compact = ds->compact;
317 0 : (*dsnew)->refined = ds->refined;
318 0 : (*dsnew)->extrarow = ds->extrarow;
319 0 : (*dsnew)->bs = ds->bs;
320 0 : (*dsnew)->pmode = ds->pmode;
321 0 : PetscFunctionReturn(PETSC_SUCCESS);
322 : }
323 :
324 : /*@
325 : DSSetMethod - Selects the method to be used to solve the problem.
326 :
327 : Logically Collective
328 :
329 : Input Parameters:
330 : + ds - the direct solver context
331 : - meth - an index identifying the method
332 :
333 : Options Database Key:
334 : . -ds_method <meth> - Sets the method
335 :
336 : Level: intermediate
337 :
338 : .seealso: DSGetMethod()
339 : @*/
340 69 : PetscErrorCode DSSetMethod(DS ds,PetscInt meth)
341 : {
342 69 : PetscFunctionBegin;
343 69 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
344 276 : PetscValidLogicalCollectiveInt(ds,meth,2);
345 69 : PetscCheck(meth>=0,PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_OUTOFRANGE,"The method must be a non-negative integer");
346 69 : PetscCheck(meth<=DS_MAX_SOLVE,PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_OUTOFRANGE,"Too large value for the method");
347 69 : ds->method = meth;
348 69 : PetscFunctionReturn(PETSC_SUCCESS);
349 : }
350 :
351 : /*@
352 : DSGetMethod - Gets the method currently used in the DS.
353 :
354 : Not Collective
355 :
356 : Input Parameter:
357 : . ds - the direct solver context
358 :
359 : Output Parameter:
360 : . meth - identifier of the method
361 :
362 : Level: intermediate
363 :
364 : .seealso: DSSetMethod()
365 : @*/
366 21 : PetscErrorCode DSGetMethod(DS ds,PetscInt *meth)
367 : {
368 21 : PetscFunctionBegin;
369 21 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
370 21 : PetscAssertPointer(meth,2);
371 21 : *meth = ds->method;
372 21 : PetscFunctionReturn(PETSC_SUCCESS);
373 : }
374 :
375 : /*@
376 : DSSetParallel - Selects the mode of operation in parallel runs.
377 :
378 : Logically Collective
379 :
380 : Input Parameters:
381 : + ds - the direct solver context
382 : - pmode - the parallel mode
383 :
384 : Options Database Key:
385 : . -ds_parallel <mode> - Sets the parallel mode, 'redundant', 'synchronized'
386 : or 'distributed'
387 :
388 : Notes:
389 : In the 'redundant' parallel mode, all processes will make the computation
390 : redundantly, starting from the same data, and producing the same result.
391 : This result may be slightly different in the different processes if using a
392 : multithreaded BLAS library, which may cause issues in ill-conditioned problems.
393 :
394 : In the 'synchronized' parallel mode, only the first MPI process performs the
395 : computation and then the computed quantities are broadcast to the other
396 : processes in the communicator. This communication is not done automatically,
397 : an explicit call to DSSynchronize() is required.
398 :
399 : The 'distributed' parallel mode can be used in some DS types only, such
400 : as the contour integral method of DSNEP. In this case, every MPI process
401 : will be in charge of part of the computation.
402 :
403 : Level: advanced
404 :
405 : .seealso: DSSynchronize(), DSGetParallel()
406 : @*/
407 84 : PetscErrorCode DSSetParallel(DS ds,DSParallelType pmode)
408 : {
409 84 : PetscFunctionBegin;
410 84 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
411 336 : PetscValidLogicalCollectiveEnum(ds,pmode,2);
412 84 : ds->pmode = pmode;
413 84 : PetscFunctionReturn(PETSC_SUCCESS);
414 : }
415 :
416 : /*@
417 : DSGetParallel - Gets the mode of operation in parallel runs.
418 :
419 : Not Collective
420 :
421 : Input Parameter:
422 : . ds - the direct solver context
423 :
424 : Output Parameter:
425 : . pmode - the parallel mode
426 :
427 : Level: advanced
428 :
429 : .seealso: DSSetParallel()
430 : @*/
431 18 : PetscErrorCode DSGetParallel(DS ds,DSParallelType *pmode)
432 : {
433 18 : PetscFunctionBegin;
434 18 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
435 18 : PetscAssertPointer(pmode,2);
436 18 : *pmode = ds->pmode;
437 18 : PetscFunctionReturn(PETSC_SUCCESS);
438 : }
439 :
440 : /*@
441 : DSSetCompact - Switch to compact storage of matrices.
442 :
443 : Logically Collective
444 :
445 : Input Parameters:
446 : + ds - the direct solver context
447 : - comp - a boolean flag
448 :
449 : Notes:
450 : Compact storage is used in some DS types such as DSHEP when the matrix
451 : is tridiagonal. This flag can be used to indicate whether the user
452 : provides the matrix entries via the compact form (the tridiagonal DS_MAT_T)
453 : or the non-compact one (DS_MAT_A).
454 :
455 : The default is PETSC_FALSE.
456 :
457 : Level: advanced
458 :
459 : .seealso: DSGetCompact()
460 : @*/
461 452 : PetscErrorCode DSSetCompact(DS ds,PetscBool comp)
462 : {
463 452 : PetscFunctionBegin;
464 452 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
465 1808 : PetscValidLogicalCollectiveBool(ds,comp,2);
466 452 : ds->compact = comp;
467 452 : PetscFunctionReturn(PETSC_SUCCESS);
468 : }
469 :
470 : /*@
471 : DSGetCompact - Gets the compact storage flag.
472 :
473 : Not Collective
474 :
475 : Input Parameter:
476 : . ds - the direct solver context
477 :
478 : Output Parameter:
479 : . comp - the flag
480 :
481 : Level: advanced
482 :
483 : .seealso: DSSetCompact()
484 : @*/
485 10 : PetscErrorCode DSGetCompact(DS ds,PetscBool *comp)
486 : {
487 10 : PetscFunctionBegin;
488 10 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
489 10 : PetscAssertPointer(comp,2);
490 10 : *comp = ds->compact;
491 10 : PetscFunctionReturn(PETSC_SUCCESS);
492 : }
493 :
494 : /*@
495 : DSSetExtraRow - Sets a flag to indicate that the matrix has one extra
496 : row.
497 :
498 : Logically Collective
499 :
500 : Input Parameters:
501 : + ds - the direct solver context
502 : - ext - a boolean flag
503 :
504 : Notes:
505 : In Krylov methods it is useful that the matrix representing the direct solver
506 : has one extra row, i.e., has dimension (n+1) x n. If this flag is activated, all
507 : transformations applied to the right of the matrix also affect this additional
508 : row. In that case, (n+1) must be less or equal than the leading dimension.
509 :
510 : The default is PETSC_FALSE.
511 :
512 : Level: advanced
513 :
514 : .seealso: DSSolve(), DSAllocate(), DSGetExtraRow()
515 : @*/
516 784 : PetscErrorCode DSSetExtraRow(DS ds,PetscBool ext)
517 : {
518 784 : PetscFunctionBegin;
519 784 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
520 3136 : PetscValidLogicalCollectiveBool(ds,ext,2);
521 784 : PetscCheck(!ext || ds->n==0 || ds->n!=ds->ld,PetscObjectComm((PetscObject)ds),PETSC_ERR_ORDER,"Cannot set extra row after setting n=ld");
522 784 : ds->extrarow = ext;
523 784 : PetscFunctionReturn(PETSC_SUCCESS);
524 : }
525 :
526 : /*@
527 : DSGetExtraRow - Gets the extra row flag.
528 :
529 : Not Collective
530 :
531 : Input Parameter:
532 : . ds - the direct solver context
533 :
534 : Output Parameter:
535 : . ext - the flag
536 :
537 : Level: advanced
538 :
539 : .seealso: DSSetExtraRow()
540 : @*/
541 1689 : PetscErrorCode DSGetExtraRow(DS ds,PetscBool *ext)
542 : {
543 1689 : PetscFunctionBegin;
544 1689 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
545 1689 : PetscAssertPointer(ext,2);
546 1689 : *ext = ds->extrarow;
547 1689 : PetscFunctionReturn(PETSC_SUCCESS);
548 : }
549 :
550 : /*@
551 : DSSetRefined - Sets a flag to indicate that refined vectors must be
552 : computed.
553 :
554 : Logically Collective
555 :
556 : Input Parameters:
557 : + ds - the direct solver context
558 : - ref - a boolean flag
559 :
560 : Notes:
561 : Normally the vectors returned in DS_MAT_X are eigenvectors of the
562 : projected matrix. With this flag activated, DSVectors() will return
563 : the right singular vector of the smallest singular value of matrix
564 : \tilde{A}-theta*I, where \tilde{A} is the extended (n+1)xn matrix
565 : and theta is the Ritz value. This is used in the refined Ritz
566 : approximation.
567 :
568 : The default is PETSC_FALSE.
569 :
570 : Level: advanced
571 :
572 : .seealso: DSVectors(), DSGetRefined()
573 : @*/
574 1 : PetscErrorCode DSSetRefined(DS ds,PetscBool ref)
575 : {
576 1 : PetscFunctionBegin;
577 1 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
578 4 : PetscValidLogicalCollectiveBool(ds,ref,2);
579 1 : ds->refined = ref;
580 1 : PetscFunctionReturn(PETSC_SUCCESS);
581 : }
582 :
583 : /*@
584 : DSGetRefined - Gets the refined vectors flag.
585 :
586 : Not Collective
587 :
588 : Input Parameter:
589 : . ds - the direct solver context
590 :
591 : Output Parameter:
592 : . ref - the flag
593 :
594 : Level: advanced
595 :
596 : .seealso: DSSetRefined()
597 : @*/
598 3212 : PetscErrorCode DSGetRefined(DS ds,PetscBool *ref)
599 : {
600 3212 : PetscFunctionBegin;
601 3212 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
602 3212 : PetscAssertPointer(ref,2);
603 3212 : *ref = ds->refined;
604 3212 : PetscFunctionReturn(PETSC_SUCCESS);
605 : }
606 :
607 : /*@
608 : DSSetBlockSize - Sets the block size.
609 :
610 : Logically Collective
611 :
612 : Input Parameters:
613 : + ds - the direct solver context
614 : - bs - the block size
615 :
616 : Options Database Key:
617 : . -ds_block_size <bs> - Sets the block size
618 :
619 : Level: intermediate
620 :
621 : .seealso: DSGetBlockSize()
622 : @*/
623 0 : PetscErrorCode DSSetBlockSize(DS ds,PetscInt bs)
624 : {
625 0 : PetscFunctionBegin;
626 0 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
627 0 : PetscValidLogicalCollectiveInt(ds,bs,2);
628 0 : PetscCheck(bs>0,PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_OUTOFRANGE,"The block size must be at least one");
629 0 : ds->bs = bs;
630 0 : PetscFunctionReturn(PETSC_SUCCESS);
631 : }
632 :
633 : /*@
634 : DSGetBlockSize - Gets the block size.
635 :
636 : Not Collective
637 :
638 : Input Parameter:
639 : . ds - the direct solver context
640 :
641 : Output Parameter:
642 : . bs - block size
643 :
644 : Level: intermediate
645 :
646 : .seealso: DSSetBlockSize()
647 : @*/
648 0 : PetscErrorCode DSGetBlockSize(DS ds,PetscInt *bs)
649 : {
650 0 : PetscFunctionBegin;
651 0 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
652 0 : PetscAssertPointer(bs,2);
653 0 : *bs = ds->bs;
654 0 : PetscFunctionReturn(PETSC_SUCCESS);
655 : }
656 :
657 : /*@C
658 : DSSetSlepcSC - Sets the sorting criterion context.
659 :
660 : Logically Collective
661 :
662 : Input Parameters:
663 : + ds - the direct solver context
664 : - sc - a pointer to the sorting criterion context
665 :
666 : Level: developer
667 :
668 : .seealso: DSGetSlepcSC(), DSSort()
669 : @*/
670 1 : PetscErrorCode DSSetSlepcSC(DS ds,SlepcSC sc)
671 : {
672 1 : PetscFunctionBegin;
673 1 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
674 1 : PetscAssertPointer(sc,2);
675 1 : if (ds->sc && !ds->scset) PetscCall(PetscFree(ds->sc));
676 1 : ds->sc = sc;
677 1 : ds->scset = PETSC_TRUE;
678 1 : PetscFunctionReturn(PETSC_SUCCESS);
679 : }
680 :
681 : /*@C
682 : DSGetSlepcSC - Gets the sorting criterion context.
683 :
684 : Not Collective
685 :
686 : Input Parameter:
687 : . ds - the direct solver context
688 :
689 : Output Parameters:
690 : . sc - a pointer to the sorting criterion context
691 :
692 : Level: developer
693 :
694 : .seealso: DSSetSlepcSC(), DSSort()
695 : @*/
696 1554 : PetscErrorCode DSGetSlepcSC(DS ds,SlepcSC *sc)
697 : {
698 1554 : PetscFunctionBegin;
699 1554 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
700 1554 : PetscAssertPointer(sc,2);
701 1554 : if (!ds->sc) PetscCall(PetscNew(&ds->sc));
702 1554 : *sc = ds->sc;
703 1554 : PetscFunctionReturn(PETSC_SUCCESS);
704 : }
705 :
706 : /*@
707 : DSSetFromOptions - Sets DS options from the options database.
708 :
709 : Collective
710 :
711 : Input Parameters:
712 : . ds - the direct solver context
713 :
714 : Notes:
715 : To see all options, run your program with the -help option.
716 :
717 : Level: beginner
718 :
719 : .seealso: DSSetOptionsPrefix()
720 : @*/
721 1083 : PetscErrorCode DSSetFromOptions(DS ds)
722 : {
723 1083 : PetscInt bs,meth;
724 1083 : PetscBool flag;
725 1083 : DSParallelType pmode;
726 :
727 1083 : PetscFunctionBegin;
728 1083 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
729 1083 : PetscCall(DSRegisterAll());
730 : /* Set default type (we do not allow changing it with -ds_type) */
731 1083 : if (!((PetscObject)ds)->type_name) PetscCall(DSSetType(ds,DSNHEP));
732 3249 : PetscObjectOptionsBegin((PetscObject)ds);
733 :
734 1083 : PetscCall(PetscOptionsInt("-ds_block_size","Block size for the dense system solver","DSSetBlockSize",ds->bs,&bs,&flag));
735 1083 : if (flag) PetscCall(DSSetBlockSize(ds,bs));
736 :
737 1083 : PetscCall(PetscOptionsInt("-ds_method","Method to be used for the dense system","DSSetMethod",ds->method,&meth,&flag));
738 1083 : if (flag) PetscCall(DSSetMethod(ds,meth));
739 :
740 1083 : PetscCall(PetscOptionsEnum("-ds_parallel","Operation mode in parallel runs","DSSetParallel",DSParallelTypes,(PetscEnum)ds->pmode,(PetscEnum*)&pmode,&flag));
741 1083 : if (flag) PetscCall(DSSetParallel(ds,pmode));
742 :
743 1083 : PetscTryTypeMethod(ds,setfromoptions,PetscOptionsObject);
744 1083 : PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)ds,PetscOptionsObject));
745 1083 : PetscOptionsEnd();
746 1083 : PetscFunctionReturn(PETSC_SUCCESS);
747 : }
748 :
749 : /*@C
750 : DSView - Prints the DS data structure.
751 :
752 : Collective
753 :
754 : Input Parameters:
755 : + ds - the direct solver context
756 : - viewer - optional visualization context
757 :
758 : Note:
759 : The available visualization contexts include
760 : + PETSC_VIEWER_STDOUT_SELF - standard output (default)
761 : - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
762 : output where only the first processor opens
763 : the file. All other processors send their
764 : data to the first processor to print.
765 :
766 : The user can open an alternative visualization context with
767 : PetscViewerASCIIOpen() - output to a specified file.
768 :
769 : Level: beginner
770 :
771 : .seealso: DSViewMat()
772 : @*/
773 112 : PetscErrorCode DSView(DS ds,PetscViewer viewer)
774 : {
775 112 : PetscBool isascii;
776 112 : PetscViewerFormat format;
777 112 : PetscMPIInt size;
778 :
779 112 : PetscFunctionBegin;
780 112 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
781 112 : if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ds),&viewer));
782 112 : PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
783 112 : PetscCheckSameComm(ds,1,viewer,2);
784 112 : PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
785 112 : if (isascii) {
786 112 : PetscCall(PetscViewerGetFormat(viewer,&format));
787 112 : PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)ds,viewer));
788 112 : PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)ds),&size));
789 112 : if (size>1) PetscCall(PetscViewerASCIIPrintf(viewer," parallel operation mode: %s\n",DSParallelTypes[ds->pmode]));
790 112 : if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
791 60 : PetscCall(PetscViewerASCIIPrintf(viewer," current state: %s\n",DSStateTypes[ds->state]));
792 60 : PetscCall(PetscViewerASCIIPrintf(viewer," dimensions: ld=%" PetscInt_FMT ", n=%" PetscInt_FMT ", l=%" PetscInt_FMT ", k=%" PetscInt_FMT,ds->ld,ds->n,ds->l,ds->k));
793 60 : if (ds->state==DS_STATE_TRUNCATED) PetscCall(PetscViewerASCIIPrintf(viewer,", t=%" PetscInt_FMT "\n",ds->t));
794 60 : else PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
795 200 : PetscCall(PetscViewerASCIIPrintf(viewer," flags:%s%s%s\n",ds->compact?" compact":"",ds->extrarow?" extrarow":"",ds->refined?" refined":""));
796 : }
797 112 : PetscCall(PetscViewerASCIIPushTab(viewer));
798 112 : PetscTryTypeMethod(ds,view,viewer);
799 112 : PetscCall(PetscViewerASCIIPopTab(viewer));
800 : }
801 112 : PetscFunctionReturn(PETSC_SUCCESS);
802 : }
803 :
804 : /*@C
805 : DSViewFromOptions - View from options
806 :
807 : Collective
808 :
809 : Input Parameters:
810 : + ds - the direct solver context
811 : . obj - optional object
812 : - name - command line option
813 :
814 : Level: intermediate
815 :
816 : .seealso: DSView(), DSCreate()
817 : @*/
818 2 : PetscErrorCode DSViewFromOptions(DS ds,PetscObject obj,const char name[])
819 : {
820 2 : PetscFunctionBegin;
821 2 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
822 2 : PetscCall(PetscObjectViewFromOptions((PetscObject)ds,obj,name));
823 2 : PetscFunctionReturn(PETSC_SUCCESS);
824 : }
825 :
826 : /*@
827 : DSAllocate - Allocates memory for internal storage or matrices in DS.
828 :
829 : Logically Collective
830 :
831 : Input Parameters:
832 : + ds - the direct solver context
833 : - ld - leading dimension (maximum allowed dimension for the matrices, including
834 : the extra row if present)
835 :
836 : Note:
837 : If the leading dimension is different from a previously set value, then
838 : all matrices are destroyed with DSReset().
839 :
840 : Level: intermediate
841 :
842 : .seealso: DSGetLeadingDimension(), DSSetDimensions(), DSSetExtraRow(), DSReset()
843 : @*/
844 1375 : PetscErrorCode DSAllocate(DS ds,PetscInt ld)
845 : {
846 1375 : PetscFunctionBegin;
847 1375 : PetscValidHeaderSpecific(ds,DS_CLASSID,1);
848 5500 : PetscValidLogicalCollectiveInt(ds,ld,2);
849 1375 : PetscValidType(ds,1);
850 1375 : PetscCheck(ld>0,PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_OUTOFRANGE,"Leading dimension should be at least one");
851 1375 : if (ld!=ds->ld) {
852 1064 : PetscCall(PetscInfo(ds,"Allocating memory with leading dimension=%" PetscInt_FMT "\n",ld));
853 1064 : PetscCall(DSReset(ds));
854 1064 : ds->ld = ld;
855 1064 : PetscUseTypeMethod(ds,allocate,ld);
856 : }
857 1375 : PetscFunctionReturn(PETSC_SUCCESS);
858 : }
859 :
860 : /*@
861 : DSReset - Resets the DS context to the initial state.
862 :
863 : Collective
864 :
865 : Input Parameter:
866 : . ds - the direct solver context
867 :
868 : Note:
869 : All data structures with size depending on the leading dimension
870 : of DSAllocate() are released.
871 :
872 : Level: advanced
873 :
874 : .seealso: DSDestroy(), DSAllocate()
875 : @*/
876 2244 : PetscErrorCode DSReset(DS ds)
877 : {
878 2244 : PetscInt i;
879 :
880 2244 : PetscFunctionBegin;
881 2244 : if (ds) PetscValidHeaderSpecific(ds,DS_CLASSID,1);
882 0 : if (!ds) PetscFunctionReturn(PETSC_SUCCESS);
883 2244 : ds->state = DS_STATE_RAW;
884 2244 : ds->ld = 0;
885 2244 : ds->l = 0;
886 2244 : ds->n = 0;
887 2244 : ds->k = 0;
888 51612 : for (i=0;i<DS_NUM_MAT;i++) PetscCall(MatDestroy(&ds->omat[i]));
889 2244 : PetscCall(PetscFree(ds->perm));
890 2244 : PetscFunctionReturn(PETSC_SUCCESS);
891 : }
892 :
893 : /*@C
894 : DSDestroy - Destroys DS context that was created with DSCreate().
895 :
896 : Collective
897 :
898 : Input Parameter:
899 : . ds - the direct solver context
900 :
901 : Level: beginner
902 :
903 : .seealso: DSCreate()
904 : @*/
905 1220 : PetscErrorCode DSDestroy(DS *ds)
906 : {
907 1220 : PetscFunctionBegin;
908 1220 : if (!*ds) PetscFunctionReturn(PETSC_SUCCESS);
909 1157 : PetscValidHeaderSpecific(*ds,DS_CLASSID,1);
910 1157 : if (--((PetscObject)*ds)->refct > 0) { *ds = NULL; PetscFunctionReturn(PETSC_SUCCESS); }
911 1157 : PetscCall(DSReset(*ds));
912 1157 : PetscTryTypeMethod(*ds,destroy);
913 1157 : PetscCall(PetscFree((*ds)->work));
914 1157 : PetscCall(PetscFree((*ds)->rwork));
915 1157 : PetscCall(PetscFree((*ds)->iwork));
916 1157 : if (!(*ds)->scset) PetscCall(PetscFree((*ds)->sc));
917 1157 : PetscCall(PetscHeaderDestroy(ds));
918 1157 : PetscFunctionReturn(PETSC_SUCCESS);
919 : }
920 :
921 : /*@C
922 : DSRegister - Adds a direct solver to the DS package.
923 :
924 : Not Collective
925 :
926 : Input Parameters:
927 : + name - name of a new user-defined DS
928 : - function - routine to create context
929 :
930 : Notes:
931 : DSRegister() may be called multiple times to add several user-defined
932 : direct solvers.
933 :
934 : Level: advanced
935 :
936 : .seealso: DSRegisterAll()
937 : @*/
938 10626 : PetscErrorCode DSRegister(const char *name,PetscErrorCode (*function)(DS))
939 : {
940 10626 : PetscFunctionBegin;
941 10626 : PetscCall(DSInitializePackage());
942 10626 : PetscCall(PetscFunctionListAdd(&DSList,name,function));
943 10626 : PetscFunctionReturn(PETSC_SUCCESS);
944 : }
945 :
946 : SLEPC_EXTERN PetscErrorCode DSCreate_HEP(DS);
947 : SLEPC_EXTERN PetscErrorCode DSCreate_NHEP(DS);
948 : SLEPC_EXTERN PetscErrorCode DSCreate_GHEP(DS);
949 : SLEPC_EXTERN PetscErrorCode DSCreate_GHIEP(DS);
950 : SLEPC_EXTERN PetscErrorCode DSCreate_GNHEP(DS);
951 : SLEPC_EXTERN PetscErrorCode DSCreate_NHEPTS(DS);
952 : SLEPC_EXTERN PetscErrorCode DSCreate_SVD(DS);
953 : SLEPC_EXTERN PetscErrorCode DSCreate_HSVD(DS);
954 : SLEPC_EXTERN PetscErrorCode DSCreate_GSVD(DS);
955 : SLEPC_EXTERN PetscErrorCode DSCreate_PEP(DS);
956 : SLEPC_EXTERN PetscErrorCode DSCreate_NEP(DS);
957 :
958 : /*@C
959 : DSRegisterAll - Registers all of the direct solvers in the DS package.
960 :
961 : Not Collective
962 :
963 : Level: advanced
964 :
965 : .seealso: DSRegister()
966 : @*/
967 2049 : PetscErrorCode DSRegisterAll(void)
968 : {
969 2049 : PetscFunctionBegin;
970 2049 : if (DSRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS);
971 966 : DSRegisterAllCalled = PETSC_TRUE;
972 966 : PetscCall(DSRegister(DSHEP,DSCreate_HEP));
973 966 : PetscCall(DSRegister(DSNHEP,DSCreate_NHEP));
974 966 : PetscCall(DSRegister(DSGHEP,DSCreate_GHEP));
975 966 : PetscCall(DSRegister(DSGHIEP,DSCreate_GHIEP));
976 966 : PetscCall(DSRegister(DSGNHEP,DSCreate_GNHEP));
977 966 : PetscCall(DSRegister(DSNHEPTS,DSCreate_NHEPTS));
978 966 : PetscCall(DSRegister(DSSVD,DSCreate_SVD));
979 966 : PetscCall(DSRegister(DSHSVD,DSCreate_HSVD));
980 966 : PetscCall(DSRegister(DSGSVD,DSCreate_GSVD));
981 966 : PetscCall(DSRegister(DSPEP,DSCreate_PEP));
982 966 : PetscCall(DSRegister(DSNEP,DSCreate_NEP));
983 966 : PetscFunctionReturn(PETSC_SUCCESS);
984 : }
|