Actual source code: bvfunc.c
slepc-main 2024-11-09
1: /*
2: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3: SLEPc - Scalable Library for Eigenvalue Problem Computations
4: Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain
6: This file is part of SLEPc.
7: SLEPc is distributed under a 2-clause BSD license (see LICENSE).
8: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9: */
10: /*
11: BV (basis vectors) interface routines, callable by users
12: */
14: #include <slepc/private/bvimpl.h>
16: PetscClassId BV_CLASSID = 0;
17: PetscLogEvent BV_Create = 0,BV_Copy = 0,BV_Mult = 0,BV_MultVec = 0,BV_MultInPlace = 0,BV_Dot = 0,BV_DotVec = 0,BV_Orthogonalize = 0,BV_OrthogonalizeVec = 0,BV_Scale = 0,BV_Norm = 0,BV_NormVec = 0,BV_Normalize = 0,BV_SetRandom = 0,BV_MatMult = 0,BV_MatMultVec = 0,BV_MatProject = 0,BV_SVDAndRank = 0;
18: static PetscBool BVPackageInitialized = PETSC_FALSE;
19: MPI_Op MPIU_TSQR = 0,MPIU_LAPY2;
21: const char *BVOrthogTypes[] = {"CGS","MGS","BVOrthogType","BV_ORTHOG_",NULL};
22: const char *BVOrthogRefineTypes[] = {"IFNEEDED","NEVER","ALWAYS","BVOrthogRefineType","BV_ORTHOG_REFINE_",NULL};
23: const char *BVOrthogBlockTypes[] = {"GS","CHOL","TSQR","TSQRCHOL","SVQB","BVOrthogBlockType","BV_ORTHOG_BLOCK_",NULL};
24: const char *BVMatMultTypes[] = {"VECS","MAT","MAT_SAVE","BVMatMultType","BV_MATMULT_",NULL};
25: const char *BVSVDMethods[] = {"REFINE","QR","QR_CAA","BVSVDMethod","BV_SVD_METHOD_",NULL};
27: /*@C
28: BVFinalizePackage - This function destroys everything in the Slepc interface
29: to the BV package. It is called from SlepcFinalize().
31: Level: developer
33: .seealso: SlepcFinalize()
34: @*/
35: PetscErrorCode BVFinalizePackage(void)
36: {
37: PetscFunctionBegin;
38: PetscCall(PetscFunctionListDestroy(&BVList));
39: PetscCallMPI(MPI_Op_free(&MPIU_TSQR));
40: PetscCallMPI(MPI_Op_free(&MPIU_LAPY2));
41: BVPackageInitialized = PETSC_FALSE;
42: BVRegisterAllCalled = PETSC_FALSE;
43: PetscFunctionReturn(PETSC_SUCCESS);
44: }
46: /*@C
47: BVInitializePackage - This function initializes everything in the BV package.
48: It is called from PetscDLLibraryRegister() when using dynamic libraries, and
49: on the first call to BVCreate() when using static libraries.
51: Level: developer
53: .seealso: SlepcInitialize()
54: @*/
55: PetscErrorCode BVInitializePackage(void)
56: {
57: char logList[256];
58: PetscBool opt,pkg;
59: PetscClassId classids[1];
61: PetscFunctionBegin;
62: if (BVPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS);
63: BVPackageInitialized = PETSC_TRUE;
64: /* Register Classes */
65: PetscCall(PetscClassIdRegister("Basis Vectors",&BV_CLASSID));
66: /* Register Constructors */
67: PetscCall(BVRegisterAll());
68: /* Register Events */
69: PetscCall(PetscLogEventRegister("BVCreate",BV_CLASSID,&BV_Create));
70: PetscCall(PetscLogEventRegister("BVCopy",BV_CLASSID,&BV_Copy));
71: PetscCall(PetscLogEventRegister("BVMult",BV_CLASSID,&BV_Mult));
72: PetscCall(PetscLogEventRegister("BVMultVec",BV_CLASSID,&BV_MultVec));
73: PetscCall(PetscLogEventRegister("BVMultInPlace",BV_CLASSID,&BV_MultInPlace));
74: PetscCall(PetscLogEventRegister("BVDot",BV_CLASSID,&BV_Dot));
75: PetscCall(PetscLogEventRegister("BVDotVec",BV_CLASSID,&BV_DotVec));
76: PetscCall(PetscLogEventRegister("BVOrthogonalize",BV_CLASSID,&BV_Orthogonalize));
77: PetscCall(PetscLogEventRegister("BVOrthogonalizeV",BV_CLASSID,&BV_OrthogonalizeVec));
78: PetscCall(PetscLogEventRegister("BVScale",BV_CLASSID,&BV_Scale));
79: PetscCall(PetscLogEventRegister("BVNorm",BV_CLASSID,&BV_Norm));
80: PetscCall(PetscLogEventRegister("BVNormVec",BV_CLASSID,&BV_NormVec));
81: PetscCall(PetscLogEventRegister("BVNormalize",BV_CLASSID,&BV_Normalize));
82: PetscCall(PetscLogEventRegister("BVSetRandom",BV_CLASSID,&BV_SetRandom));
83: PetscCall(PetscLogEventRegister("BVMatMult",BV_CLASSID,&BV_MatMult));
84: PetscCall(PetscLogEventRegister("BVMatMultVec",BV_CLASSID,&BV_MatMultVec));
85: PetscCall(PetscLogEventRegister("BVMatProject",BV_CLASSID,&BV_MatProject));
86: PetscCall(PetscLogEventRegister("BVSVDAndRank",BV_CLASSID,&BV_SVDAndRank));
87: /* MPI reduction operation used in BVOrthogonalize */
88: PetscCallMPI(MPI_Op_create(SlepcGivensPacked,PETSC_FALSE,&MPIU_TSQR));
89: PetscCallMPI(MPI_Op_create(SlepcPythag,PETSC_TRUE,&MPIU_LAPY2));
90: /* Process Info */
91: classids[0] = BV_CLASSID;
92: PetscCall(PetscInfoProcessClass("bv",1,&classids[0]));
93: /* Process summary exclusions */
94: PetscCall(PetscOptionsGetString(NULL,NULL,"-log_exclude",logList,sizeof(logList),&opt));
95: if (opt) {
96: PetscCall(PetscStrInList("bv",logList,',',&pkg));
97: if (pkg) PetscCall(PetscLogEventDeactivateClass(BV_CLASSID));
98: }
99: /* Register package finalizer */
100: PetscCall(PetscRegisterFinalize(BVFinalizePackage));
101: PetscFunctionReturn(PETSC_SUCCESS);
102: }
104: /*@
105: BVDestroy - Destroys BV context that was created with BVCreate().
107: Collective
109: Input Parameter:
110: . bv - the basis vectors context
112: Level: beginner
114: .seealso: BVCreate()
115: @*/
116: PetscErrorCode BVDestroy(BV *bv)
117: {
118: PetscFunctionBegin;
119: if (!*bv) PetscFunctionReturn(PETSC_SUCCESS);
121: PetscCheck(!(*bv)->lsplit,PetscObjectComm((PetscObject)*bv),PETSC_ERR_ARG_WRONGSTATE,"Must call BVRestoreSplit before destroying the BV");
122: if (--((PetscObject)*bv)->refct > 0) { *bv = NULL; PetscFunctionReturn(PETSC_SUCCESS); }
123: PetscTryTypeMethod(*bv,destroy);
124: PetscCall(PetscLayoutDestroy(&(*bv)->map));
125: PetscCall(PetscFree((*bv)->vtype));
126: PetscCall(MatDestroy(&(*bv)->matrix));
127: PetscCall(VecDestroy(&(*bv)->Bx));
128: PetscCall(VecDestroy(&(*bv)->buffer));
129: PetscCall(BVDestroy(&(*bv)->cached));
130: PetscCall(BVDestroy(&(*bv)->L));
131: PetscCall(BVDestroy(&(*bv)->R));
132: PetscCall(PetscFree((*bv)->work));
133: PetscCall(PetscFree2((*bv)->h,(*bv)->c));
134: PetscCall(VecDestroy(&(*bv)->omega));
135: PetscCall(MatDestroy(&(*bv)->Acreate));
136: PetscCall(MatDestroy(&(*bv)->Aget));
137: PetscCall(MatDestroy(&(*bv)->Abuffer));
138: PetscCall(PetscRandomDestroy(&(*bv)->rand));
139: PetscCall(PetscHeaderDestroy(bv));
140: PetscFunctionReturn(PETSC_SUCCESS);
141: }
143: /*@
144: BVCreate - Creates a basis vectors context.
146: Collective
148: Input Parameter:
149: . comm - MPI communicator
151: Output Parameter:
152: . newbv - location to put the basis vectors context
154: Level: beginner
156: .seealso: BVSetUp(), BVDestroy(), BV
157: @*/
158: PetscErrorCode BVCreate(MPI_Comm comm,BV *newbv)
159: {
160: BV bv;
162: PetscFunctionBegin;
163: PetscAssertPointer(newbv,2);
164: PetscCall(BVInitializePackage());
165: PetscCall(SlepcHeaderCreate(bv,BV_CLASSID,"BV","Basis Vectors","BV",comm,BVDestroy,BVView));
167: bv->map = NULL;
168: bv->vtype = NULL;
169: bv->n = -1;
170: bv->N = -1;
171: bv->m = 0;
172: bv->l = 0;
173: bv->k = 0;
174: bv->nc = 0;
175: bv->ld = 0;
176: bv->orthog_type = BV_ORTHOG_CGS;
177: bv->orthog_ref = BV_ORTHOG_REFINE_IFNEEDED;
178: bv->orthog_eta = 0.7071;
179: bv->orthog_block = BV_ORTHOG_BLOCK_GS;
180: bv->matrix = NULL;
181: bv->indef = PETSC_FALSE;
182: bv->vmm = BV_MATMULT_MAT;
183: bv->rrandom = PETSC_FALSE;
184: bv->deftol = 10*PETSC_MACHINE_EPSILON;
186: bv->buffer = NULL;
187: bv->Abuffer = NULL;
188: bv->Bx = NULL;
189: bv->xid = 0;
190: bv->xstate = 0;
191: bv->cv[0] = NULL;
192: bv->cv[1] = NULL;
193: bv->ci[0] = -1;
194: bv->ci[1] = -1;
195: bv->st[0] = -1;
196: bv->st[1] = -1;
197: bv->id[0] = 0;
198: bv->id[1] = 0;
199: bv->h = NULL;
200: bv->c = NULL;
201: bv->omega = NULL;
202: bv->defersfo = PETSC_FALSE;
203: bv->cached = NULL;
204: bv->bvstate = 0;
205: bv->L = NULL;
206: bv->R = NULL;
207: bv->lstate = 0;
208: bv->rstate = 0;
209: bv->lsplit = 0;
210: bv->issplit = 0;
211: bv->splitparent = NULL;
212: bv->rand = NULL;
213: bv->Acreate = NULL;
214: bv->Aget = NULL;
215: bv->cuda = PETSC_FALSE;
216: bv->hip = PETSC_FALSE;
217: bv->sfocalled = PETSC_FALSE;
218: bv->work = NULL;
219: bv->lwork = 0;
220: bv->data = NULL;
222: *newbv = bv;
223: PetscFunctionReturn(PETSC_SUCCESS);
224: }
226: /*@
227: BVCreateFromMat - Creates a basis vectors object from a dense Mat object.
229: Collective
231: Input Parameter:
232: . A - a dense tall-skinny matrix
234: Output Parameter:
235: . bv - the new basis vectors context
237: Notes:
238: The matrix values are copied to the BV data storage, memory is not shared.
240: The communicator of the BV object will be the same as A, and so will be
241: the dimensions.
243: Level: intermediate
245: .seealso: BVCreate(), BVDestroy(), BVCreateMat()
246: @*/
247: PetscErrorCode BVCreateFromMat(Mat A,BV *bv)
248: {
249: PetscInt n,N,k;
250: VecType vtype;
252: PetscFunctionBegin;
255: PetscCall(MatGetSize(A,&N,&k));
256: PetscCall(MatGetLocalSize(A,&n,NULL));
257: PetscCall(MatGetVecType(A,&vtype));
258: PetscCall(BVCreate(PetscObjectComm((PetscObject)A),bv));
259: PetscCall(BVSetSizes(*bv,n,N,k));
260: PetscCall(BVSetVecType(*bv,vtype));
262: (*bv)->Acreate = A;
263: PetscCall(PetscObjectReference((PetscObject)A));
264: PetscFunctionReturn(PETSC_SUCCESS);
265: }
267: /*@
268: BVInsertVec - Insert a vector into the specified column.
270: Logically Collective
272: Input Parameters:
273: + V - basis vectors
274: . j - the column of V to be overwritten
275: - w - the vector to be copied
277: Level: intermediate
279: .seealso: BVInsertVecs()
280: @*/
281: PetscErrorCode BVInsertVec(BV V,PetscInt j,Vec w)
282: {
283: PetscInt n,N;
284: Vec v;
286: PetscFunctionBegin;
291: BVCheckSizes(V,1);
292: PetscCheckSameComm(V,1,w,3);
294: PetscCall(VecGetSize(w,&N));
295: PetscCall(VecGetLocalSize(w,&n));
296: PetscCheck(N==V->N && n==V->n,PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_INCOMP,"Vec sizes (global %" PetscInt_FMT ", local %" PetscInt_FMT ") do not match BV sizes (global %" PetscInt_FMT ", local %" PetscInt_FMT ")",N,n,V->N,V->n);
297: PetscCheck(j>=-V->nc && j<V->m,PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_OUTOFRANGE,"Argument j has wrong value %" PetscInt_FMT ", should be between %" PetscInt_FMT " and %" PetscInt_FMT,j,-V->nc,V->m-1);
299: PetscCall(BVGetColumn(V,j,&v));
300: PetscCall(VecCopy(w,v));
301: PetscCall(BVRestoreColumn(V,j,&v));
302: PetscCall(PetscObjectStateIncrease((PetscObject)V));
303: PetscFunctionReturn(PETSC_SUCCESS);
304: }
306: /*@
307: BVInsertVecs - Insert a set of vectors into the specified columns.
309: Collective
311: Input Parameters:
312: + V - basis vectors
313: . s - first column of V to be overwritten
314: . W - set of vectors to be copied
315: - orth - flag indicating if the vectors must be orthogonalized
317: Input/Output Parameter:
318: . m - number of input vectors, on output the number of linearly independent
319: vectors
321: Notes:
322: Copies the contents of vectors W to V(:,s:s+n). If the orthogonalization
323: flag is set, then the vectors are copied one by one and then orthogonalized
324: against the previous ones. If any of them is linearly dependent then it
325: is discarded and the value of m is decreased.
327: Level: intermediate
329: .seealso: BVInsertVec(), BVOrthogonalizeColumn()
330: @*/
331: PetscErrorCode BVInsertVecs(BV V,PetscInt s,PetscInt *m,Vec *W,PetscBool orth)
332: {
333: PetscInt n,N,i,ndep;
334: PetscBool lindep;
335: PetscReal norm;
336: Vec v;
338: PetscFunctionBegin;
341: PetscAssertPointer(m,3);
343: if (!*m) PetscFunctionReturn(PETSC_SUCCESS);
344: PetscCheck(*m>0,PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %" PetscInt_FMT ") cannot be negative",*m);
345: PetscAssertPointer(W,4);
349: BVCheckSizes(V,1);
350: PetscCheckSameComm(V,1,*W,4);
352: PetscCall(VecGetSize(*W,&N));
353: PetscCall(VecGetLocalSize(*W,&n));
354: PetscCheck(N==V->N && n==V->n,PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_INCOMP,"Vec sizes (global %" PetscInt_FMT ", local %" PetscInt_FMT ") do not match BV sizes (global %" PetscInt_FMT ", local %" PetscInt_FMT ")",N,n,V->N,V->n);
355: PetscCheck(s>=0 && s<V->m,PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_OUTOFRANGE,"Argument s has wrong value %" PetscInt_FMT ", should be between 0 and %" PetscInt_FMT,s,V->m-1);
356: PetscCheck(s+(*m)<=V->m,PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_OUTOFRANGE,"Too many vectors provided, there is only room for %" PetscInt_FMT,V->m);
358: ndep = 0;
359: for (i=0;i<*m;i++) {
360: PetscCall(BVGetColumn(V,s+i-ndep,&v));
361: PetscCall(VecCopy(W[i],v));
362: PetscCall(BVRestoreColumn(V,s+i-ndep,&v));
363: if (orth) {
364: PetscCall(BVOrthogonalizeColumn(V,s+i-ndep,NULL,&norm,&lindep));
365: if (norm==0.0 || lindep) {
366: PetscCall(PetscInfo(V,"Removing linearly dependent vector %" PetscInt_FMT "\n",i));
367: ndep++;
368: } else PetscCall(BVScaleColumn(V,s+i-ndep,1.0/norm));
369: }
370: }
371: *m -= ndep;
372: PetscCall(PetscObjectStateIncrease((PetscObject)V));
373: PetscFunctionReturn(PETSC_SUCCESS);
374: }
376: /*@
377: BVInsertConstraints - Insert a set of vectors as constraints.
379: Collective
381: Input Parameters:
382: + V - basis vectors
383: - C - set of vectors to be inserted as constraints
385: Input/Output Parameter:
386: . nc - number of input vectors, on output the number of linearly independent
387: vectors
389: Notes:
390: The constraints are relevant only during orthogonalization. Constraint
391: vectors span a subspace that is deflated in every orthogonalization
392: operation, so they are intended for removing those directions from the
393: orthogonal basis computed in regular BV columns.
395: Constraints are not stored in regular BV columns, but in a special part of
396: the storage. They can be accessed with negative indices in BVGetColumn().
398: This operation is DESTRUCTIVE, meaning that all data contained in the
399: columns of V is lost. This is typically invoked just after creating the BV.
400: Once a set of constraints has been set, it is not allowed to call this
401: function again.
403: The vectors are copied one by one and then orthogonalized against the
404: previous ones. If any of them is linearly dependent then it is discarded
405: and the value of nc is decreased. The behaviour is similar to BVInsertVecs().
407: Level: advanced
409: .seealso: BVInsertVecs(), BVOrthogonalizeColumn(), BVGetColumn(), BVGetNumConstraints()
410: @*/
411: PetscErrorCode BVInsertConstraints(BV V,PetscInt *nc,Vec *C)
412: {
413: PetscInt msave;
415: PetscFunctionBegin;
417: PetscAssertPointer(nc,2);
419: if (!*nc) PetscFunctionReturn(PETSC_SUCCESS);
420: PetscCheck(*nc>0,PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_OUTOFRANGE,"Number of constraints (given %" PetscInt_FMT ") cannot be negative",*nc);
421: PetscAssertPointer(C,3);
424: BVCheckSizes(V,1);
425: PetscCheckSameComm(V,1,*C,3);
426: PetscCheck(!V->issplit,PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_WRONGSTATE,"Operation not permitted for a BV obtained from BVGetSplit");
427: PetscCheck(!V->nc,PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_WRONGSTATE,"Constraints already present in this BV object");
428: PetscCheck(V->ci[0]==-1 && V->ci[1]==-1,PetscObjectComm((PetscObject)V),PETSC_ERR_SUP,"Cannot call BVInsertConstraints after BVGetColumn");
430: msave = V->m;
431: PetscCall(BVResize(V,*nc+V->m,PETSC_FALSE));
432: PetscCall(BVInsertVecs(V,0,nc,C,PETSC_TRUE));
433: V->nc = *nc;
434: V->m = msave;
435: V->ci[0] = -V->nc-1;
436: V->ci[1] = -V->nc-1;
437: PetscCall(PetscObjectStateIncrease((PetscObject)V));
438: PetscFunctionReturn(PETSC_SUCCESS);
439: }
441: /*@
442: BVSetOptionsPrefix - Sets the prefix used for searching for all
443: BV options in the database.
445: Logically Collective
447: Input Parameters:
448: + bv - the basis vectors context
449: - prefix - the prefix string to prepend to all BV option requests
451: Notes:
452: A hyphen (-) must NOT be given at the beginning of the prefix name.
453: The first character of all runtime options is AUTOMATICALLY the
454: hyphen.
456: Level: advanced
458: .seealso: BVAppendOptionsPrefix(), BVGetOptionsPrefix()
459: @*/
460: PetscErrorCode BVSetOptionsPrefix(BV bv,const char *prefix)
461: {
462: PetscFunctionBegin;
464: PetscCall(PetscObjectSetOptionsPrefix((PetscObject)bv,prefix));
465: PetscFunctionReturn(PETSC_SUCCESS);
466: }
468: /*@
469: BVAppendOptionsPrefix - Appends to the prefix used for searching for all
470: BV options in the database.
472: Logically Collective
474: Input Parameters:
475: + bv - the basis vectors context
476: - prefix - the prefix string to prepend to all BV option requests
478: Notes:
479: A hyphen (-) must NOT be given at the beginning of the prefix name.
480: The first character of all runtime options is AUTOMATICALLY the
481: hyphen.
483: Level: advanced
485: .seealso: BVSetOptionsPrefix(), BVGetOptionsPrefix()
486: @*/
487: PetscErrorCode BVAppendOptionsPrefix(BV bv,const char *prefix)
488: {
489: PetscFunctionBegin;
491: PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)bv,prefix));
492: PetscFunctionReturn(PETSC_SUCCESS);
493: }
495: /*@
496: BVGetOptionsPrefix - Gets the prefix used for searching for all
497: BV options in the database.
499: Not Collective
501: Input Parameters:
502: . bv - the basis vectors context
504: Output Parameters:
505: . prefix - pointer to the prefix string used, is returned
507: Note:
508: On the Fortran side, the user should pass in a string 'prefix' of
509: sufficient length to hold the prefix.
511: Level: advanced
513: .seealso: BVSetOptionsPrefix(), BVAppendOptionsPrefix()
514: @*/
515: PetscErrorCode BVGetOptionsPrefix(BV bv,const char *prefix[])
516: {
517: PetscFunctionBegin;
519: PetscAssertPointer(prefix,2);
520: PetscCall(PetscObjectGetOptionsPrefix((PetscObject)bv,prefix));
521: PetscFunctionReturn(PETSC_SUCCESS);
522: }
524: /*@
525: BVView - Prints the BV data structure.
527: Collective
529: Input Parameters:
530: + bv - the BV context
531: - viewer - optional visualization context
533: Note:
534: The available visualization contexts include
535: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
536: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
537: output where only the first processor opens
538: the file. All other processors send their
539: data to the first processor to print.
541: The user can open an alternative visualization contexts with
542: PetscViewerASCIIOpen() (output to a specified file).
544: Level: beginner
546: .seealso: BVCreate()
547: @*/
548: PetscErrorCode BVView(BV bv,PetscViewer viewer)
549: {
550: PetscBool isascii;
551: PetscViewerFormat format;
552: const char *orthname[2] = {"classical","modified"};
553: const char *refname[3] = {"if needed","never","always"};
555: PetscFunctionBegin;
557: if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)bv),&viewer));
560: PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
561: if (isascii) {
562: PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)bv,viewer));
563: PetscCall(PetscViewerGetFormat(viewer,&format));
564: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
565: PetscCall(PetscViewerASCIIPrintf(viewer," %" PetscInt_FMT " columns of global length %" PetscInt_FMT "%s\n",bv->m,bv->N,bv->cuda?" (CUDA)":bv->hip?" (HIP)":""));
566: if (bv->nc>0) PetscCall(PetscViewerASCIIPrintf(viewer," number of constraints: %" PetscInt_FMT "\n",bv->nc));
567: PetscCall(PetscViewerASCIIPrintf(viewer," vector orthogonalization method: %s Gram-Schmidt\n",orthname[bv->orthog_type]));
568: switch (bv->orthog_ref) {
569: case BV_ORTHOG_REFINE_IFNEEDED:
570: PetscCall(PetscViewerASCIIPrintf(viewer," orthogonalization refinement: %s (eta: %g)\n",refname[bv->orthog_ref],(double)bv->orthog_eta));
571: break;
572: case BV_ORTHOG_REFINE_NEVER:
573: case BV_ORTHOG_REFINE_ALWAYS:
574: PetscCall(PetscViewerASCIIPrintf(viewer," orthogonalization refinement: %s\n",refname[bv->orthog_ref]));
575: break;
576: }
577: PetscCall(PetscViewerASCIIPrintf(viewer," block orthogonalization method: %s\n",BVOrthogBlockTypes[bv->orthog_block]));
578: if (bv->matrix) {
579: if (bv->indef) PetscCall(PetscViewerASCIIPrintf(viewer," indefinite inner product\n"));
580: else PetscCall(PetscViewerASCIIPrintf(viewer," non-standard inner product\n"));
581: PetscCall(PetscViewerASCIIPrintf(viewer," tolerance for definite inner product: %g\n",(double)bv->deftol));
582: PetscCall(PetscViewerASCIIPrintf(viewer," inner product matrix:\n"));
583: PetscCall(PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO));
584: PetscCall(PetscViewerASCIIPushTab(viewer));
585: PetscCall(MatView(bv->matrix,viewer));
586: PetscCall(PetscViewerASCIIPopTab(viewer));
587: PetscCall(PetscViewerPopFormat(viewer));
588: }
589: switch (bv->vmm) {
590: case BV_MATMULT_VECS:
591: PetscCall(PetscViewerASCIIPrintf(viewer," doing matmult as matrix-vector products\n"));
592: break;
593: case BV_MATMULT_MAT:
594: PetscCall(PetscViewerASCIIPrintf(viewer," doing matmult as a single matrix-matrix product\n"));
595: break;
596: case BV_MATMULT_MAT_SAVE:
597: PetscCall(PetscViewerASCIIPrintf(viewer," mat_save is deprecated, use mat\n"));
598: break;
599: }
600: if (bv->rrandom) PetscCall(PetscViewerASCIIPrintf(viewer," generating random vectors independent of the number of processes\n"));
601: }
602: }
603: PetscTryTypeMethod(bv,view,viewer);
604: PetscFunctionReturn(PETSC_SUCCESS);
605: }
607: /*@
608: BVViewFromOptions - View from options
610: Collective
612: Input Parameters:
613: + bv - the basis vectors context
614: . obj - optional object
615: - name - command line option
617: Level: intermediate
619: .seealso: BVView(), BVCreate()
620: @*/
621: PetscErrorCode BVViewFromOptions(BV bv,PetscObject obj,const char name[])
622: {
623: PetscFunctionBegin;
625: PetscCall(PetscObjectViewFromOptions((PetscObject)bv,obj,name));
626: PetscFunctionReturn(PETSC_SUCCESS);
627: }
629: /*@C
630: BVRegister - Adds a new storage format to the BV package.
632: Not Collective
634: Input Parameters:
635: + name - name of a new user-defined BV
636: - function - routine to create context
638: Notes:
639: BVRegister() may be called multiple times to add several user-defined
640: basis vectors.
642: Level: advanced
644: .seealso: BVRegisterAll()
645: @*/
646: PetscErrorCode BVRegister(const char *name,PetscErrorCode (*function)(BV))
647: {
648: PetscFunctionBegin;
649: PetscCall(BVInitializePackage());
650: PetscCall(PetscFunctionListAdd(&BVList,name,function));
651: PetscFunctionReturn(PETSC_SUCCESS);
652: }
654: PetscErrorCode BVAllocateWork_Private(BV bv,PetscInt s)
655: {
656: PetscFunctionBegin;
657: if (s>bv->lwork) {
658: PetscCall(PetscFree(bv->work));
659: PetscCall(PetscMalloc1(s,&bv->work));
660: bv->lwork = s;
661: }
662: PetscFunctionReturn(PETSC_SUCCESS);
663: }
665: #if defined(PETSC_USE_DEBUG) && !defined(PETSC_CLANG_STATIC_ANALYZER)
666: /*
667: SlepcDebugBVView - partially view a BV object, to be used from within a debugger.
669: ini, end: columns to be viewed
670: s: name of Matlab variable
671: filename: optionally write output to a file
672: */
673: PETSC_UNUSED PetscErrorCode SlepcDebugBVView(BV bv,PetscInt ini,PetscInt end,const char *s,const char *filename)
674: {
675: PetscInt N,m;
676: PetscScalar *array;
678: PetscFunctionBegin;
679: PetscCall(BVGetArray(bv,&array));
680: PetscCall(BVGetSizes(bv,NULL,&N,&m));
681: PetscCall(SlepcDebugViewMatrix(N,end-ini+1,array+ini*N,NULL,bv->ld,s,filename));
682: PetscCall(BVRestoreArray(bv,&array));
683: PetscFunctionReturn(PETSC_SUCCESS);
684: }
685: #endif