Actual source code: bvbasic.c
slepc-3.20.1 2023-11-27
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: Basic BV routines
12: */
14: #include <slepc/private/bvimpl.h>
16: PetscBool BVRegisterAllCalled = PETSC_FALSE;
17: PetscFunctionList BVList = NULL;
19: /*@C
20: BVSetType - Selects the type for the BV object.
22: Logically Collective
24: Input Parameters:
25: + bv - the basis vectors context
26: - type - a known type
28: Options Database Key:
29: . -bv_type <type> - Sets BV type
31: Level: intermediate
33: .seealso: BVGetType()
34: @*/
35: PetscErrorCode BVSetType(BV bv,BVType type)
36: {
37: PetscErrorCode (*r)(BV);
38: PetscBool match;
40: PetscFunctionBegin;
42: PetscAssertPointer(type,2);
44: PetscCall(PetscObjectTypeCompare((PetscObject)bv,type,&match));
45: if (match) PetscFunctionReturn(PETSC_SUCCESS);
46: PetscCall(PetscStrcmp(type,BVTENSOR,&match));
47: PetscCheck(!match,PetscObjectComm((PetscObject)bv),PETSC_ERR_ORDER,"Use BVCreateTensor() to create a BV of type tensor");
49: PetscCall(PetscFunctionListFind(BVList,type,&r));
50: PetscCheck(r,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested BV type %s",type);
52: PetscTryTypeMethod(bv,destroy);
53: PetscCall(PetscMemzero(bv->ops,sizeof(struct _BVOps)));
55: PetscCall(PetscObjectChangeTypeName((PetscObject)bv,type));
56: if (bv->n < 0 && bv->N < 0) {
57: bv->ops->create = r;
58: } else {
59: PetscCall(PetscLogEventBegin(BV_Create,bv,0,0,0));
60: PetscCall((*r)(bv));
61: PetscCall(PetscLogEventEnd(BV_Create,bv,0,0,0));
62: }
63: PetscFunctionReturn(PETSC_SUCCESS);
64: }
66: /*@C
67: BVGetType - Gets the BV type name (as a string) from the BV context.
69: Not Collective
71: Input Parameter:
72: . bv - the basis vectors context
74: Output Parameter:
75: . type - name of the type of basis vectors
77: Level: intermediate
79: .seealso: BVSetType()
80: @*/
81: PetscErrorCode BVGetType(BV bv,BVType *type)
82: {
83: PetscFunctionBegin;
85: PetscAssertPointer(type,2);
86: *type = ((PetscObject)bv)->type_name;
87: PetscFunctionReturn(PETSC_SUCCESS);
88: }
90: /*@
91: BVSetSizes - Sets the local and global sizes, and the number of columns.
93: Collective
95: Input Parameters:
96: + bv - the basis vectors
97: . n - the local size (or PETSC_DECIDE to have it set)
98: . N - the global size (or PETSC_DECIDE)
99: - m - the number of columns
101: Notes:
102: n and N cannot be both PETSC_DECIDE.
103: If one processor calls this with N of PETSC_DECIDE then all processors must,
104: otherwise the program will hang.
106: Level: beginner
108: .seealso: BVSetSizesFromVec(), BVGetSizes(), BVResize()
109: @*/
110: PetscErrorCode BVSetSizes(BV bv,PetscInt n,PetscInt N,PetscInt m)
111: {
112: PetscInt ma;
114: PetscFunctionBegin;
118: PetscCheck(N<0 || n<=N,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_INCOMP,"Local size %" PetscInt_FMT " cannot be larger than global size %" PetscInt_FMT,n,N);
119: PetscCheck(m>0,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_INCOMP,"Number of columns %" PetscInt_FMT " must be positive",m);
120: PetscCheck((bv->n<0 && bv->N<0) || (bv->n==n && bv->N==N),PetscObjectComm((PetscObject)bv),PETSC_ERR_SUP,"Cannot change/reset vector sizes to %" PetscInt_FMT " local %" PetscInt_FMT " global after previously setting them to %" PetscInt_FMT " local %" PetscInt_FMT " global",n,N,bv->n,bv->N);
121: PetscCheck(bv->m<=0 || bv->m==m,PetscObjectComm((PetscObject)bv),PETSC_ERR_SUP,"Cannot change the number of columns to %" PetscInt_FMT " after previously setting it to %" PetscInt_FMT "; use BVResize()",m,bv->m);
122: bv->n = n;
123: bv->N = N;
124: bv->m = m;
125: bv->k = m;
126: if (!bv->t) { /* create template vector and get actual dimensions */
127: PetscCall(VecCreate(PetscObjectComm((PetscObject)bv),&bv->t));
128: PetscCall(VecSetSizes(bv->t,bv->n,bv->N));
129: PetscCall(VecSetFromOptions(bv->t));
130: PetscCall(VecGetSize(bv->t,&bv->N));
131: PetscCall(VecGetLocalSize(bv->t,&bv->n));
132: if (bv->matrix) { /* check compatible dimensions of user-provided matrix */
133: PetscCall(MatGetLocalSize(bv->matrix,&ma,NULL));
134: PetscCheck(bv->n==ma,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_INCOMP,"Local dimension %" PetscInt_FMT " does not match that of matrix given at BVSetMatrix %" PetscInt_FMT,bv->n,ma);
135: }
136: }
137: if (bv->ops->create) {
138: PetscCall(PetscLogEventBegin(BV_Create,bv,0,0,0));
139: PetscUseTypeMethod(bv,create);
140: PetscCall(PetscLogEventEnd(BV_Create,bv,0,0,0));
141: bv->ops->create = NULL;
142: bv->defersfo = PETSC_FALSE;
143: }
144: PetscFunctionReturn(PETSC_SUCCESS);
145: }
147: /*@
148: BVSetSizesFromVec - Sets the local and global sizes, and the number of columns.
149: Local and global sizes are specified indirectly by passing a template vector.
151: Collective
153: Input Parameters:
154: + bv - the basis vectors
155: . t - the template vector
156: - m - the number of columns
158: Level: beginner
160: .seealso: BVSetSizes(), BVGetSizes(), BVResize()
161: @*/
162: PetscErrorCode BVSetSizesFromVec(BV bv,Vec t,PetscInt m)
163: {
164: PetscInt ma;
166: PetscFunctionBegin;
169: PetscCheckSameComm(bv,1,t,2);
171: PetscCheck(m>0,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_INCOMP,"Number of columns %" PetscInt_FMT " must be positive",m);
172: PetscCheck(!bv->t,PetscObjectComm((PetscObject)bv),PETSC_ERR_SUP,"Template vector was already set by a previous call to BVSetSizes/FromVec");
173: PetscCall(VecGetSize(t,&bv->N));
174: PetscCall(VecGetLocalSize(t,&bv->n));
175: if (bv->matrix) { /* check compatible dimensions of user-provided matrix */
176: PetscCall(MatGetLocalSize(bv->matrix,&ma,NULL));
177: PetscCheck(bv->n==ma,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_INCOMP,"Local dimension %" PetscInt_FMT " does not match that of matrix given at BVSetMatrix %" PetscInt_FMT,bv->n,ma);
178: }
179: bv->m = m;
180: bv->k = m;
181: bv->t = t;
182: PetscCall(PetscObjectReference((PetscObject)t));
183: if (bv->ops->create) {
184: PetscUseTypeMethod(bv,create);
185: bv->ops->create = NULL;
186: bv->defersfo = PETSC_FALSE;
187: }
188: PetscFunctionReturn(PETSC_SUCCESS);
189: }
191: /*@
192: BVGetSizes - Returns the local and global sizes, and the number of columns.
194: Not Collective
196: Input Parameter:
197: . bv - the basis vectors
199: Output Parameters:
200: + n - the local size
201: . N - the global size
202: - m - the number of columns
204: Note:
205: Normal usage requires that bv has already been given its sizes, otherwise
206: the call fails. However, this function can also be used to determine if
207: a BV object has been initialized completely (sizes and type). For this,
208: call with n=NULL and N=NULL, then a return value of m=0 indicates that
209: the BV object is not ready for use yet.
211: Level: beginner
213: .seealso: BVSetSizes(), BVSetSizesFromVec()
214: @*/
215: PetscErrorCode BVGetSizes(BV bv,PetscInt *n,PetscInt *N,PetscInt *m)
216: {
217: PetscFunctionBegin;
218: if (!bv) {
219: if (m && !n && !N) *m = 0;
220: PetscFunctionReturn(PETSC_SUCCESS);
221: }
223: if (n || N) BVCheckSizes(bv,1);
224: if (n) *n = bv->n;
225: if (N) *N = bv->N;
226: if (m) *m = bv->m;
227: if (m && !n && !N && !((PetscObject)bv)->type_name) *m = 0;
228: PetscFunctionReturn(PETSC_SUCCESS);
229: }
231: /*@
232: BVSetNumConstraints - Set the number of constraints.
234: Logically Collective
236: Input Parameters:
237: + V - basis vectors
238: - nc - number of constraints
240: Notes:
241: This function sets the number of constraints to nc and marks all remaining
242: columns as regular. Normal user would call BVInsertConstraints() instead.
244: If nc is smaller than the previously set value, then some of the constraints
245: are discarded. In particular, using nc=0 removes all constraints preserving
246: the content of regular columns.
248: Level: developer
250: .seealso: BVInsertConstraints()
251: @*/
252: PetscErrorCode BVSetNumConstraints(BV V,PetscInt nc)
253: {
254: PetscInt total,diff,i;
255: Vec x,y;
257: PetscFunctionBegin;
260: PetscCheck(nc>=0,PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_OUTOFRANGE,"Number of constraints (given %" PetscInt_FMT ") cannot be negative",nc);
262: BVCheckSizes(V,1);
263: PetscCheck(V->ci[0]==-V->nc-1 && V->ci[1]==-V->nc-1,PetscObjectComm((PetscObject)V),PETSC_ERR_SUP,"Cannot call BVSetNumConstraints after BVGetColumn");
265: diff = nc-V->nc;
266: if (!diff) PetscFunctionReturn(PETSC_SUCCESS);
267: total = V->nc+V->m;
268: PetscCheck(total-nc>0,PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_OUTOFRANGE,"Not enough columns for the given nc value");
269: if (diff<0) { /* lessen constraints, shift contents of BV */
270: for (i=0;i<V->m;i++) {
271: PetscCall(BVGetColumn(V,i,&x));
272: PetscCall(BVGetColumn(V,i+diff,&y));
273: PetscCall(VecCopy(x,y));
274: PetscCall(BVRestoreColumn(V,i,&x));
275: PetscCall(BVRestoreColumn(V,i+diff,&y));
276: }
277: }
278: V->nc = nc;
279: V->ci[0] = -V->nc-1;
280: V->ci[1] = -V->nc-1;
281: V->m = total-nc;
282: V->l = PetscMin(V->l,V->m);
283: V->k = PetscMin(V->k,V->m);
284: PetscCall(PetscObjectStateIncrease((PetscObject)V));
285: PetscFunctionReturn(PETSC_SUCCESS);
286: }
288: /*@
289: BVGetNumConstraints - Returns the number of constraints.
291: Not Collective
293: Input Parameter:
294: . bv - the basis vectors
296: Output Parameters:
297: . nc - the number of constraints
299: Level: advanced
301: .seealso: BVGetSizes(), BVInsertConstraints()
302: @*/
303: PetscErrorCode BVGetNumConstraints(BV bv,PetscInt *nc)
304: {
305: PetscFunctionBegin;
307: PetscAssertPointer(nc,2);
308: *nc = bv->nc;
309: PetscFunctionReturn(PETSC_SUCCESS);
310: }
312: /*@
313: BVResize - Change the number of columns.
315: Collective
317: Input Parameters:
318: + bv - the basis vectors
319: . m - the new number of columns
320: - copy - a flag indicating whether current values should be kept
322: Note:
323: Internal storage is reallocated. If the copy flag is set to true, then
324: the contents are copied to the leading part of the new space.
326: Level: advanced
328: .seealso: BVSetSizes(), BVSetSizesFromVec()
329: @*/
330: PetscErrorCode BVResize(BV bv,PetscInt m,PetscBool copy)
331: {
332: PetscScalar *array;
333: const PetscScalar *omega;
334: Vec v;
336: PetscFunctionBegin;
341: PetscCheck(m>0,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_INCOMP,"Number of columns %" PetscInt_FMT " must be positive",m);
342: PetscCheck(!bv->nc || bv->issplit,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_WRONGSTATE,"Cannot resize a BV with constraints");
343: if (bv->m == m) PetscFunctionReturn(PETSC_SUCCESS);
344: BVCheckOp(bv,1,resize);
346: PetscCall(PetscLogEventBegin(BV_Create,bv,0,0,0));
347: PetscUseTypeMethod(bv,resize,m,copy);
348: PetscCall(VecDestroy(&bv->buffer));
349: PetscCall(BVDestroy(&bv->cached));
350: PetscCall(PetscFree2(bv->h,bv->c));
351: if (bv->omega) {
352: if (bv->cuda) {
353: #if defined(PETSC_HAVE_CUDA)
354: PetscCall(VecCreateSeqCUDA(PETSC_COMM_SELF,m,&v));
355: #else
356: SETERRQ(PetscObjectComm((PetscObject)bv),PETSC_ERR_PLIB,"Something wrong happened");
357: #endif
358: } else PetscCall(VecCreateSeq(PETSC_COMM_SELF,m,&v));
359: if (copy) {
360: PetscCall(VecGetArray(v,&array));
361: PetscCall(VecGetArrayRead(bv->omega,&omega));
362: PetscCall(PetscArraycpy(array,omega,PetscMin(m,bv->m)));
363: PetscCall(VecRestoreArrayRead(bv->omega,&omega));
364: PetscCall(VecRestoreArray(v,&array));
365: } else PetscCall(VecSet(v,1.0));
366: PetscCall(VecDestroy(&bv->omega));
367: bv->omega = v;
368: }
369: bv->m = m;
370: bv->k = PetscMin(bv->k,m);
371: bv->l = PetscMin(bv->l,m);
372: PetscCall(PetscLogEventEnd(BV_Create,bv,0,0,0));
373: PetscCall(PetscObjectStateIncrease((PetscObject)bv));
374: PetscFunctionReturn(PETSC_SUCCESS);
375: }
377: /*@
378: BVSetActiveColumns - Specify the columns that will be involved in operations.
380: Logically Collective
382: Input Parameters:
383: + bv - the basis vectors context
384: . l - number of leading columns
385: - k - number of active columns
387: Notes:
388: In operations such as BVMult() or BVDot(), only the first k columns are
389: considered. This is useful when the BV is filled from left to right, so
390: the last m-k columns do not have relevant information.
392: Also in operations such as BVMult() or BVDot(), the first l columns are
393: normally not included in the computation. See the manpage of each
394: operation.
396: In orthogonalization operations, the first l columns are treated
397: differently, they participate in the orthogonalization but the computed
398: coefficients are not stored.
400: Level: intermediate
402: .seealso: BVGetActiveColumns(), BVSetSizes()
403: @*/
404: PetscErrorCode BVSetActiveColumns(BV bv,PetscInt l,PetscInt k)
405: {
406: PetscFunctionBegin;
410: BVCheckSizes(bv,1);
411: if (PetscUnlikely(k==PETSC_DECIDE || k==PETSC_DEFAULT)) {
412: bv->k = bv->m;
413: } else {
414: PetscCheck(k>=0 && k<=bv->m,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of k (%" PetscInt_FMT "). Must be between 0 and m (%" PetscInt_FMT ")",k,bv->m);
415: bv->k = k;
416: }
417: if (PetscUnlikely(l==PETSC_DECIDE || l==PETSC_DEFAULT)) {
418: bv->l = 0;
419: } else {
420: PetscCheck(l>=0 && l<=bv->k,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of l (%" PetscInt_FMT "). Must be between 0 and k (%" PetscInt_FMT ")",l,bv->k);
421: bv->l = l;
422: }
423: PetscFunctionReturn(PETSC_SUCCESS);
424: }
426: /*@
427: BVGetActiveColumns - Returns the current active dimensions.
429: Not Collective
431: Input Parameter:
432: . bv - the basis vectors context
434: Output Parameters:
435: + l - number of leading columns
436: - k - number of active columns
438: Level: intermediate
440: .seealso: BVSetActiveColumns()
441: @*/
442: PetscErrorCode BVGetActiveColumns(BV bv,PetscInt *l,PetscInt *k)
443: {
444: PetscFunctionBegin;
446: if (l) *l = bv->l;
447: if (k) *k = bv->k;
448: PetscFunctionReturn(PETSC_SUCCESS);
449: }
451: /*@
452: BVSetMatrix - Specifies the inner product to be used in orthogonalization.
454: Collective
456: Input Parameters:
457: + bv - the basis vectors context
458: . B - a symmetric matrix (may be NULL)
459: - indef - a flag indicating if the matrix is indefinite
461: Notes:
462: This is used to specify a non-standard inner product, whose matrix
463: representation is given by B. Then, all inner products required during
464: orthogonalization are computed as (x,y)_B=y^H*B*x rather than the
465: standard form (x,y)=y^H*x.
467: Matrix B must be real symmetric (or complex Hermitian). A genuine inner
468: product requires that B is also positive (semi-)definite. However, we
469: also allow for an indefinite B (setting indef=PETSC_TRUE), in which
470: case the orthogonalization uses an indefinite inner product.
472: This affects operations BVDot(), BVNorm(), BVOrthogonalize(), and variants.
474: Setting B=NULL has the same effect as if the identity matrix was passed.
476: Level: advanced
478: .seealso: BVGetMatrix(), BVDot(), BVNorm(), BVOrthogonalize(), BVSetDefiniteTolerance()
479: @*/
480: PetscErrorCode BVSetMatrix(BV bv,Mat B,PetscBool indef)
481: {
482: PetscInt m,n;
484: PetscFunctionBegin;
487: if (B!=bv->matrix || (B && ((PetscObject)B)->id!=((PetscObject)bv->matrix)->id) || indef!=bv->indef) {
488: if (B) {
490: PetscCall(MatGetLocalSize(B,&m,&n));
491: PetscCheck(m==n,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_SIZ,"Matrix must be square");
492: PetscCheck(!bv->m || bv->n==n,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_INCOMP,"Mismatching local dimension BV %" PetscInt_FMT ", Mat %" PetscInt_FMT,bv->n,n);
493: }
494: if (B) PetscCall(PetscObjectReference((PetscObject)B));
495: PetscCall(MatDestroy(&bv->matrix));
496: bv->matrix = B;
497: bv->indef = indef;
498: PetscCall(PetscObjectStateIncrease((PetscObject)bv));
499: if (bv->Bx) PetscCall(PetscObjectStateIncrease((PetscObject)bv->Bx));
500: if (bv->cached) PetscCall(PetscObjectStateIncrease((PetscObject)bv->cached));
501: }
502: PetscFunctionReturn(PETSC_SUCCESS);
503: }
505: /*@
506: BVGetMatrix - Retrieves the matrix representation of the inner product.
508: Not Collective
510: Input Parameter:
511: . bv - the basis vectors context
513: Output Parameters:
514: + B - the matrix of the inner product (may be NULL)
515: - indef - the flag indicating if the matrix is indefinite
517: Level: advanced
519: .seealso: BVSetMatrix()
520: @*/
521: PetscErrorCode BVGetMatrix(BV bv,Mat *B,PetscBool *indef)
522: {
523: PetscFunctionBegin;
525: if (B) *B = bv->matrix;
526: if (indef) *indef = bv->indef;
527: PetscFunctionReturn(PETSC_SUCCESS);
528: }
530: /*@
531: BVApplyMatrix - Multiplies a vector by the matrix representation of the
532: inner product.
534: Neighbor-wise Collective
536: Input Parameters:
537: + bv - the basis vectors context
538: - x - the vector
540: Output Parameter:
541: . y - the result
543: Note:
544: If no matrix was specified this function copies the vector.
546: Level: advanced
548: .seealso: BVSetMatrix(), BVApplyMatrixBV()
549: @*/
550: PetscErrorCode BVApplyMatrix(BV bv,Vec x,Vec y)
551: {
552: PetscFunctionBegin;
556: if (bv->matrix) {
557: PetscCall(BV_IPMatMult(bv,x));
558: PetscCall(VecCopy(bv->Bx,y));
559: } else PetscCall(VecCopy(x,y));
560: PetscFunctionReturn(PETSC_SUCCESS);
561: }
563: /*@
564: BVApplyMatrixBV - Multiplies the BV vectors by the matrix representation
565: of the inner product.
567: Neighbor-wise Collective
569: Input Parameter:
570: . X - the basis vectors context
572: Output Parameter:
573: . Y - the basis vectors to store the result (optional)
575: Note:
576: This function computes Y = B*X, where B is the matrix given with
577: BVSetMatrix(). This operation is computed as in BVMatMult().
578: If no matrix was specified, then it just copies Y = X.
580: If no Y is given, the result is stored internally in the cached BV.
582: Level: developer
584: .seealso: BVSetMatrix(), BVApplyMatrix(), BVMatMult(), BVGetCachedBV()
585: @*/
586: PetscErrorCode BVApplyMatrixBV(BV X,BV Y)
587: {
588: PetscFunctionBegin;
590: if (Y) {
592: if (X->matrix) PetscCall(BVMatMult(X,X->matrix,Y));
593: else PetscCall(BVCopy(X,Y));
594: } else PetscCall(BV_IPMatMultBV(X));
595: PetscFunctionReturn(PETSC_SUCCESS);
596: }
598: /*@
599: BVSetSignature - Sets the signature matrix to be used in orthogonalization.
601: Logically Collective
603: Input Parameters:
604: + bv - the basis vectors context
605: - omega - a vector representing the diagonal of the signature matrix
607: Note:
608: The signature matrix Omega = V'*B*V is relevant only for an indefinite B.
610: Level: developer
612: .seealso: BVSetMatrix(), BVGetSignature()
613: @*/
614: PetscErrorCode BVSetSignature(BV bv,Vec omega)
615: {
616: PetscInt i,n;
617: const PetscScalar *pomega;
618: PetscScalar *intern;
620: PetscFunctionBegin;
622: BVCheckSizes(bv,1);
626: PetscCall(VecGetSize(omega,&n));
627: PetscCheck(n==bv->k,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_SIZ,"Vec argument has %" PetscInt_FMT " elements, should be %" PetscInt_FMT,n,bv->k);
628: PetscCall(BV_AllocateSignature(bv));
629: if (bv->indef) {
630: PetscCall(VecGetArrayRead(omega,&pomega));
631: PetscCall(VecGetArray(bv->omega,&intern));
632: for (i=0;i<n;i++) intern[bv->nc+i] = pomega[i];
633: PetscCall(VecRestoreArray(bv->omega,&intern));
634: PetscCall(VecRestoreArrayRead(omega,&pomega));
635: } else PetscCall(PetscInfo(bv,"Ignoring signature because BV is not indefinite\n"));
636: PetscCall(PetscObjectStateIncrease((PetscObject)bv));
637: PetscFunctionReturn(PETSC_SUCCESS);
638: }
640: /*@
641: BVGetSignature - Retrieves the signature matrix from last orthogonalization.
643: Not Collective
645: Input Parameter:
646: . bv - the basis vectors context
648: Output Parameter:
649: . omega - a vector representing the diagonal of the signature matrix
651: Note:
652: The signature matrix Omega = V'*B*V is relevant only for an indefinite B.
654: Level: developer
656: .seealso: BVSetMatrix(), BVSetSignature()
657: @*/
658: PetscErrorCode BVGetSignature(BV bv,Vec omega)
659: {
660: PetscInt i,n;
661: PetscScalar *pomega;
662: const PetscScalar *intern;
664: PetscFunctionBegin;
666: BVCheckSizes(bv,1);
670: PetscCall(VecGetSize(omega,&n));
671: PetscCheck(n==bv->k,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_SIZ,"Vec argument has %" PetscInt_FMT " elements, should be %" PetscInt_FMT,n,bv->k);
672: if (bv->indef && bv->omega) {
673: PetscCall(VecGetArray(omega,&pomega));
674: PetscCall(VecGetArrayRead(bv->omega,&intern));
675: for (i=0;i<n;i++) pomega[i] = intern[bv->nc+i];
676: PetscCall(VecRestoreArrayRead(bv->omega,&intern));
677: PetscCall(VecRestoreArray(omega,&pomega));
678: } else PetscCall(VecSet(omega,1.0));
679: PetscFunctionReturn(PETSC_SUCCESS);
680: }
682: /*@
683: BVSetBufferVec - Attach a vector object to be used as buffer space for
684: several operations.
686: Collective
688: Input Parameters:
689: + bv - the basis vectors context)
690: - buffer - the vector
692: Notes:
693: Use BVGetBufferVec() to retrieve the vector (for example, to free it
694: at the end of the computations).
696: The vector must be sequential of length (nc+m)*m, where m is the number
697: of columns of bv and nc is the number of constraints.
699: Level: developer
701: .seealso: BVGetBufferVec(), BVSetSizes(), BVGetNumConstraints()
702: @*/
703: PetscErrorCode BVSetBufferVec(BV bv,Vec buffer)
704: {
705: PetscInt ld,n;
706: PetscMPIInt size;
708: PetscFunctionBegin;
711: BVCheckSizes(bv,1);
712: PetscCall(VecGetSize(buffer,&n));
713: ld = bv->m+bv->nc;
714: PetscCheck(n==ld*bv->m,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_SIZ,"Buffer size must be %" PetscInt_FMT,ld*bv->m);
715: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)buffer),&size));
716: PetscCheck(size==1,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_WRONG,"Buffer must be a sequential vector");
718: PetscCall(PetscObjectReference((PetscObject)buffer));
719: PetscCall(VecDestroy(&bv->buffer));
720: bv->buffer = buffer;
721: PetscFunctionReturn(PETSC_SUCCESS);
722: }
724: /*@
725: BVGetBufferVec - Obtain the buffer vector associated with the BV object.
727: Collective
729: Input Parameters:
730: . bv - the basis vectors context
732: Output Parameter:
733: . buffer - vector
735: Notes:
736: The vector is created if not available previously. It is a sequential vector
737: of length (nc+m)*m, where m is the number of columns of bv and nc is the number
738: of constraints.
740: Developer Notes:
741: The buffer vector is viewed as a column-major matrix with leading dimension
742: ld=nc+m, and m columns at most. In the most common usage, it has the structure
743: .vb
744: | | C |
745: |s|---|
746: | | H |
747: .ve
748: where H is an upper Hessenberg matrix of order m x (m-1), C contains coefficients
749: related to orthogonalization against constraints (first nc rows), and s is the
750: first column that contains scratch values computed during Gram-Schmidt
751: orthogonalization. In particular, BVDotColumn() and BVMultColumn() use s to
752: store the coefficients.
754: Level: developer
756: .seealso: BVSetBufferVec(), BVSetSizes(), BVGetNumConstraints(), BVDotColumn(), BVMultColumn()
757: @*/
758: PetscErrorCode BVGetBufferVec(BV bv,Vec *buffer)
759: {
760: PetscInt ld;
762: PetscFunctionBegin;
764: PetscAssertPointer(buffer,2);
765: BVCheckSizes(bv,1);
766: if (!bv->buffer) {
767: ld = bv->m+bv->nc;
768: PetscCall(VecCreate(PETSC_COMM_SELF,&bv->buffer));
769: PetscCall(VecSetSizes(bv->buffer,PETSC_DECIDE,ld*bv->m));
770: PetscCall(VecSetType(bv->buffer,((PetscObject)bv->t)->type_name));
771: }
772: *buffer = bv->buffer;
773: PetscFunctionReturn(PETSC_SUCCESS);
774: }
776: /*@
777: BVSetRandomContext - Sets the PetscRandom object associated with the BV,
778: to be used in operations that need random numbers.
780: Collective
782: Input Parameters:
783: + bv - the basis vectors context
784: - rand - the random number generator context
786: Level: advanced
788: .seealso: BVGetRandomContext(), BVSetRandom(), BVSetRandomNormal(), BVSetRandomColumn(), BVSetRandomCond()
789: @*/
790: PetscErrorCode BVSetRandomContext(BV bv,PetscRandom rand)
791: {
792: PetscFunctionBegin;
795: PetscCheckSameComm(bv,1,rand,2);
796: PetscCall(PetscObjectReference((PetscObject)rand));
797: PetscCall(PetscRandomDestroy(&bv->rand));
798: bv->rand = rand;
799: PetscFunctionReturn(PETSC_SUCCESS);
800: }
802: /*@
803: BVGetRandomContext - Gets the PetscRandom object associated with the BV.
805: Collective
807: Input Parameter:
808: . bv - the basis vectors context
810: Output Parameter:
811: . rand - the random number generator context
813: Level: advanced
815: .seealso: BVSetRandomContext(), BVSetRandom(), BVSetRandomNormal(), BVSetRandomColumn(), BVSetRandomCond()
816: @*/
817: PetscErrorCode BVGetRandomContext(BV bv,PetscRandom* rand)
818: {
819: PetscFunctionBegin;
821: PetscAssertPointer(rand,2);
822: if (!bv->rand) {
823: PetscCall(PetscRandomCreate(PetscObjectComm((PetscObject)bv),&bv->rand));
824: if (bv->cuda) PetscCall(PetscRandomSetType(bv->rand,PETSCCURAND));
825: if (bv->sfocalled) PetscCall(PetscRandomSetFromOptions(bv->rand));
826: if (bv->rrandom) {
827: PetscCall(PetscRandomSetSeed(bv->rand,0x12345678));
828: PetscCall(PetscRandomSeed(bv->rand));
829: }
830: }
831: *rand = bv->rand;
832: PetscFunctionReturn(PETSC_SUCCESS);
833: }
835: /*@
836: BVSetFromOptions - Sets BV options from the options database.
838: Collective
840: Input Parameter:
841: . bv - the basis vectors context
843: Level: beginner
845: .seealso: BVSetOptionsPrefix()
846: @*/
847: PetscErrorCode BVSetFromOptions(BV bv)
848: {
849: char type[256];
850: PetscBool flg1,flg2,flg3,flg4;
851: PetscReal r;
852: BVOrthogType otype;
853: BVOrthogRefineType orefine;
854: BVOrthogBlockType oblock;
856: PetscFunctionBegin;
858: PetscCall(BVRegisterAll());
859: PetscObjectOptionsBegin((PetscObject)bv);
860: PetscCall(PetscOptionsFList("-bv_type","Basis Vectors type","BVSetType",BVList,(char*)(((PetscObject)bv)->type_name?((PetscObject)bv)->type_name:BVMAT),type,sizeof(type),&flg1));
861: if (flg1) PetscCall(BVSetType(bv,type));
862: else if (!((PetscObject)bv)->type_name) PetscCall(BVSetType(bv,BVMAT));
864: otype = bv->orthog_type;
865: PetscCall(PetscOptionsEnum("-bv_orthog_type","Orthogonalization method","BVSetOrthogonalization",BVOrthogTypes,(PetscEnum)otype,(PetscEnum*)&otype,&flg1));
866: orefine = bv->orthog_ref;
867: PetscCall(PetscOptionsEnum("-bv_orthog_refine","Iterative refinement mode during orthogonalization","BVSetOrthogonalization",BVOrthogRefineTypes,(PetscEnum)orefine,(PetscEnum*)&orefine,&flg2));
868: r = bv->orthog_eta;
869: PetscCall(PetscOptionsReal("-bv_orthog_eta","Parameter of iterative refinement during orthogonalization","BVSetOrthogonalization",r,&r,&flg3));
870: oblock = bv->orthog_block;
871: PetscCall(PetscOptionsEnum("-bv_orthog_block","Block orthogonalization method","BVSetOrthogonalization",BVOrthogBlockTypes,(PetscEnum)oblock,(PetscEnum*)&oblock,&flg4));
872: if (flg1 || flg2 || flg3 || flg4) PetscCall(BVSetOrthogonalization(bv,otype,orefine,r,oblock));
874: PetscCall(PetscOptionsEnum("-bv_matmult","Method for BVMatMult","BVSetMatMultMethod",BVMatMultTypes,(PetscEnum)bv->vmm,(PetscEnum*)&bv->vmm,NULL));
876: PetscCall(PetscOptionsReal("-bv_definite_tol","Tolerance for checking a definite inner product","BVSetDefiniteTolerance",r,&r,&flg1));
877: if (flg1) PetscCall(BVSetDefiniteTolerance(bv,r));
879: /* undocumented option to generate random vectors that are independent of the number of processes */
880: PetscCall(PetscOptionsGetBool(NULL,NULL,"-bv_reproducible_random",&bv->rrandom,NULL));
882: if (bv->ops->create) bv->defersfo = PETSC_TRUE; /* defer call to setfromoptions */
883: else PetscTryTypeMethod(bv,setfromoptions,PetscOptionsObject);
884: PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)bv,PetscOptionsObject));
885: PetscOptionsEnd();
886: bv->sfocalled = PETSC_TRUE;
887: PetscFunctionReturn(PETSC_SUCCESS);
888: }
890: /*@
891: BVSetOrthogonalization - Specifies the method used for the orthogonalization of
892: vectors (classical or modified Gram-Schmidt with or without refinement), and
893: for the block-orthogonalization (simultaneous orthogonalization of a set of
894: vectors).
896: Logically Collective
898: Input Parameters:
899: + bv - the basis vectors context
900: . type - the method of vector orthogonalization
901: . refine - type of refinement
902: . eta - parameter for selective refinement
903: - block - the method of block orthogonalization
905: Options Database Keys:
906: + -bv_orthog_type <type> - Where <type> is cgs for Classical Gram-Schmidt orthogonalization
907: (default) or mgs for Modified Gram-Schmidt orthogonalization
908: . -bv_orthog_refine <ref> - Where <ref> is one of never, ifneeded (default) or always
909: . -bv_orthog_eta <eta> - For setting the value of eta
910: - -bv_orthog_block <block> - Where <block> is the block-orthogonalization method
912: Notes:
913: The default settings work well for most problems.
915: The parameter eta should be a real value between 0 and 1 (or PETSC_DEFAULT).
916: The value of eta is used only when the refinement type is "ifneeded".
918: When using several processors, MGS is likely to result in bad scalability.
920: If the method set for block orthogonalization is GS, then the computation
921: is done column by column with the vector orthogonalization.
923: Level: advanced
925: .seealso: BVOrthogonalizeColumn(), BVGetOrthogonalization(), BVOrthogType, BVOrthogRefineType, BVOrthogBlockType
926: @*/
927: PetscErrorCode BVSetOrthogonalization(BV bv,BVOrthogType type,BVOrthogRefineType refine,PetscReal eta,BVOrthogBlockType block)
928: {
929: PetscFunctionBegin;
935: switch (type) {
936: case BV_ORTHOG_CGS:
937: case BV_ORTHOG_MGS:
938: bv->orthog_type = type;
939: break;
940: default:
941: SETERRQ(PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_WRONG,"Unknown orthogonalization type");
942: }
943: switch (refine) {
944: case BV_ORTHOG_REFINE_NEVER:
945: case BV_ORTHOG_REFINE_IFNEEDED:
946: case BV_ORTHOG_REFINE_ALWAYS:
947: bv->orthog_ref = refine;
948: break;
949: default:
950: SETERRQ(PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_WRONG,"Unknown refinement type");
951: }
952: if (eta == (PetscReal)PETSC_DEFAULT) {
953: bv->orthog_eta = 0.7071;
954: } else {
955: PetscCheck(eta>0.0 && eta<=1.0,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_OUTOFRANGE,"Invalid eta value");
956: bv->orthog_eta = eta;
957: }
958: switch (block) {
959: case BV_ORTHOG_BLOCK_GS:
960: case BV_ORTHOG_BLOCK_CHOL:
961: case BV_ORTHOG_BLOCK_TSQR:
962: case BV_ORTHOG_BLOCK_TSQRCHOL:
963: case BV_ORTHOG_BLOCK_SVQB:
964: bv->orthog_block = block;
965: break;
966: default:
967: SETERRQ(PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_WRONG,"Unknown block orthogonalization type");
968: }
969: PetscFunctionReturn(PETSC_SUCCESS);
970: }
972: /*@
973: BVGetOrthogonalization - Gets the orthogonalization settings from the BV object.
975: Not Collective
977: Input Parameter:
978: . bv - basis vectors context
980: Output Parameters:
981: + type - the method of vector orthogonalization
982: . refine - type of refinement
983: . eta - parameter for selective refinement
984: - block - the method of block orthogonalization
986: Level: advanced
988: .seealso: BVOrthogonalizeColumn(), BVSetOrthogonalization(), BVOrthogType, BVOrthogRefineType, BVOrthogBlockType
989: @*/
990: PetscErrorCode BVGetOrthogonalization(BV bv,BVOrthogType *type,BVOrthogRefineType *refine,PetscReal *eta,BVOrthogBlockType *block)
991: {
992: PetscFunctionBegin;
994: if (type) *type = bv->orthog_type;
995: if (refine) *refine = bv->orthog_ref;
996: if (eta) *eta = bv->orthog_eta;
997: if (block) *block = bv->orthog_block;
998: PetscFunctionReturn(PETSC_SUCCESS);
999: }
1001: /*@
1002: BVSetMatMultMethod - Specifies the method used for the BVMatMult() operation.
1004: Logically Collective
1006: Input Parameters:
1007: + bv - the basis vectors context
1008: - method - the method for the BVMatMult() operation
1010: Options Database Keys:
1011: . -bv_matmult <meth> - choose one of the methods: vecs, mat
1013: Notes:
1014: Allowed values are
1015: + BV_MATMULT_VECS - perform a matrix-vector multiply per each column
1016: . BV_MATMULT_MAT - carry out a Mat-Mat product with a dense matrix
1017: - BV_MATMULT_MAT_SAVE - this case is deprecated
1019: The default is BV_MATMULT_MAT except in the case of BVVECS.
1021: Level: advanced
1023: .seealso: BVMatMult(), BVGetMatMultMethod(), BVMatMultType
1024: @*/
1025: PetscErrorCode BVSetMatMultMethod(BV bv,BVMatMultType method)
1026: {
1027: PetscFunctionBegin;
1030: switch (method) {
1031: case BV_MATMULT_VECS:
1032: case BV_MATMULT_MAT:
1033: bv->vmm = method;
1034: break;
1035: case BV_MATMULT_MAT_SAVE:
1036: PetscCall(PetscInfo(bv,"BV_MATMULT_MAT_SAVE is deprecated, using BV_MATMULT_MAT\n"));
1037: bv->vmm = BV_MATMULT_MAT;
1038: break;
1039: default:
1040: SETERRQ(PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_WRONG,"Unknown matmult method");
1041: }
1042: PetscFunctionReturn(PETSC_SUCCESS);
1043: }
1045: /*@
1046: BVGetMatMultMethod - Gets the method used for the BVMatMult() operation.
1048: Not Collective
1050: Input Parameter:
1051: . bv - basis vectors context
1053: Output Parameter:
1054: . method - the method for the BVMatMult() operation
1056: Level: advanced
1058: .seealso: BVMatMult(), BVSetMatMultMethod(), BVMatMultType
1059: @*/
1060: PetscErrorCode BVGetMatMultMethod(BV bv,BVMatMultType *method)
1061: {
1062: PetscFunctionBegin;
1064: PetscAssertPointer(method,2);
1065: *method = bv->vmm;
1066: PetscFunctionReturn(PETSC_SUCCESS);
1067: }
1069: /*@
1070: BVGetColumn - Returns a Vec object that contains the entries of the
1071: requested column of the basis vectors object.
1073: Logically Collective
1075: Input Parameters:
1076: + bv - the basis vectors context
1077: - j - the index of the requested column
1079: Output Parameter:
1080: . v - vector containing the jth column
1082: Notes:
1083: The returned Vec must be seen as a reference (not a copy) of the BV
1084: column, that is, modifying the Vec will change the BV entries as well.
1086: The returned Vec must not be destroyed. BVRestoreColumn() must be
1087: called when it is no longer needed. At most, two columns can be fetched,
1088: that is, this function can only be called twice before the corresponding
1089: BVRestoreColumn() is invoked.
1091: A negative index j selects the i-th constraint, where i=-j. Constraints
1092: should not be modified.
1094: Level: beginner
1096: .seealso: BVRestoreColumn(), BVInsertConstraints()
1097: @*/
1098: PetscErrorCode BVGetColumn(BV bv,PetscInt j,Vec *v)
1099: {
1100: PetscInt l;
1102: PetscFunctionBegin;
1105: BVCheckSizes(bv,1);
1106: BVCheckOp(bv,1,getcolumn);
1108: PetscCheck(j>=0 || -j<=bv->nc,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_OUTOFRANGE,"You requested constraint %" PetscInt_FMT " but only %" PetscInt_FMT " are available",-j,bv->nc);
1109: PetscCheck(j<bv->m,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_OUTOFRANGE,"You requested column %" PetscInt_FMT " but only %" PetscInt_FMT " are available",j,bv->m);
1110: PetscCheck(j!=bv->ci[0] && j!=bv->ci[1],PetscObjectComm((PetscObject)bv),PETSC_ERR_SUP,"Column %" PetscInt_FMT " already fetched in a previous call to BVGetColumn",j);
1111: l = BVAvailableVec;
1112: PetscCheck(l!=-1,PetscObjectComm((PetscObject)bv),PETSC_ERR_SUP,"Too many requested columns; you must call BVRestoreColumn for one of the previously fetched columns");
1113: PetscUseTypeMethod(bv,getcolumn,j,v);
1114: bv->ci[l] = j;
1115: PetscCall(PetscObjectStateGet((PetscObject)bv->cv[l],&bv->st[l]));
1116: PetscCall(PetscObjectGetId((PetscObject)bv->cv[l],&bv->id[l]));
1117: *v = bv->cv[l];
1118: PetscFunctionReturn(PETSC_SUCCESS);
1119: }
1121: /*@
1122: BVRestoreColumn - Restore a column obtained with BVGetColumn().
1124: Logically Collective
1126: Input Parameters:
1127: + bv - the basis vectors context
1128: . j - the index of the column
1129: - v - vector obtained with BVGetColumn()
1131: Note:
1132: The arguments must match the corresponding call to BVGetColumn().
1134: Level: beginner
1136: .seealso: BVGetColumn()
1137: @*/
1138: PetscErrorCode BVRestoreColumn(BV bv,PetscInt j,Vec *v)
1139: {
1140: PetscObjectId id;
1141: PetscObjectState st;
1142: PetscInt l;
1144: PetscFunctionBegin;
1147: BVCheckSizes(bv,1);
1149: PetscAssertPointer(v,3);
1151: PetscCheck(j>=0 || -j<=bv->nc,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_OUTOFRANGE,"You requested constraint %" PetscInt_FMT " but only %" PetscInt_FMT " are available",-j,bv->nc);
1152: PetscCheck(j<bv->m,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_OUTOFRANGE,"You requested column %" PetscInt_FMT " but only %" PetscInt_FMT " are available",j,bv->m);
1153: PetscCheck(j==bv->ci[0] || j==bv->ci[1],PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_WRONG,"Column %" PetscInt_FMT " has not been fetched with a call to BVGetColumn",j);
1154: l = (j==bv->ci[0])? 0: 1;
1155: PetscCall(PetscObjectGetId((PetscObject)*v,&id));
1156: PetscCheck(id==bv->id[l],PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_WRONG,"Argument 3 is not the same Vec that was obtained with BVGetColumn");
1157: PetscCall(PetscObjectStateGet((PetscObject)*v,&st));
1158: if (st!=bv->st[l]) PetscCall(PetscObjectStateIncrease((PetscObject)bv));
1159: PetscUseTypeMethod(bv,restorecolumn,j,v);
1160: bv->ci[l] = -bv->nc-1;
1161: bv->st[l] = -1;
1162: bv->id[l] = 0;
1163: *v = NULL;
1164: PetscFunctionReturn(PETSC_SUCCESS);
1165: }
1167: /*@C
1168: BVGetArray - Returns a pointer to a contiguous array that contains this
1169: processor's portion of the BV data.
1171: Logically Collective
1173: Input Parameters:
1174: . bv - the basis vectors context
1176: Output Parameter:
1177: . a - location to put pointer to the array
1179: Notes:
1180: BVRestoreArray() must be called when access to the array is no longer needed.
1181: This operation may imply a data copy, for BV types that do not store
1182: data contiguously in memory.
1184: The pointer will normally point to the first entry of the first column,
1185: but if the BV has constraints then these go before the regular columns.
1187: Note that for manipulating the pointer to the BV array, one must take into
1188: account the leading dimension, which might be different from the local
1189: number of rows, see BVGetLeadingDimension().
1191: Use BVGetArrayRead() for read-only access.
1193: Level: advanced
1195: .seealso: BVRestoreArray(), BVInsertConstraints(), BVGetLeadingDimension(), BVGetArrayRead()
1196: @*/
1197: PetscErrorCode BVGetArray(BV bv,PetscScalar **a)
1198: {
1199: PetscFunctionBegin;
1202: BVCheckSizes(bv,1);
1203: BVCheckOp(bv,1,getarray);
1204: PetscUseTypeMethod(bv,getarray,a);
1205: PetscFunctionReturn(PETSC_SUCCESS);
1206: }
1208: /*@C
1209: BVRestoreArray - Restore the BV object after BVGetArray() has been called.
1211: Logically Collective
1213: Input Parameters:
1214: + bv - the basis vectors context
1215: - a - location of pointer to array obtained from BVGetArray()
1217: Note:
1218: This operation may imply a data copy, for BV types that do not store
1219: data contiguously in memory.
1221: Level: advanced
1223: .seealso: BVGetColumn()
1224: @*/
1225: PetscErrorCode BVRestoreArray(BV bv,PetscScalar **a)
1226: {
1227: PetscFunctionBegin;
1230: BVCheckSizes(bv,1);
1231: PetscTryTypeMethod(bv,restorearray,a);
1232: if (a) *a = NULL;
1233: PetscCall(PetscObjectStateIncrease((PetscObject)bv));
1234: PetscFunctionReturn(PETSC_SUCCESS);
1235: }
1237: /*@C
1238: BVGetArrayRead - Returns a read-only pointer to a contiguous array that
1239: contains this processor's portion of the BV data.
1241: Not Collective
1243: Input Parameters:
1244: . bv - the basis vectors context
1246: Output Parameter:
1247: . a - location to put pointer to the array
1249: Notes:
1250: BVRestoreArrayRead() must be called when access to the array is no
1251: longer needed. This operation may imply a data copy, for BV types that
1252: do not store data contiguously in memory.
1254: The pointer will normally point to the first entry of the first column,
1255: but if the BV has constraints then these go before the regular columns.
1257: Level: advanced
1259: .seealso: BVRestoreArray(), BVInsertConstraints(), BVGetLeadingDimension(), BVGetArray()
1260: @*/
1261: PetscErrorCode BVGetArrayRead(BV bv,const PetscScalar **a)
1262: {
1263: PetscFunctionBegin;
1266: BVCheckSizes(bv,1);
1267: BVCheckOp(bv,1,getarrayread);
1268: PetscUseTypeMethod(bv,getarrayread,a);
1269: PetscFunctionReturn(PETSC_SUCCESS);
1270: }
1272: /*@C
1273: BVRestoreArrayRead - Restore the BV object after BVGetArrayRead() has
1274: been called.
1276: Not Collective
1278: Input Parameters:
1279: + bv - the basis vectors context
1280: - a - location of pointer to array obtained from BVGetArrayRead()
1282: Level: advanced
1284: .seealso: BVGetColumn()
1285: @*/
1286: PetscErrorCode BVRestoreArrayRead(BV bv,const PetscScalar **a)
1287: {
1288: PetscFunctionBegin;
1291: BVCheckSizes(bv,1);
1292: PetscTryTypeMethod(bv,restorearrayread,a);
1293: if (a) *a = NULL;
1294: PetscFunctionReturn(PETSC_SUCCESS);
1295: }
1297: /*@
1298: BVCreateVec - Creates a new Vec object with the same type and dimensions
1299: as the columns of the basis vectors object.
1301: Collective
1303: Input Parameter:
1304: . bv - the basis vectors context
1306: Output Parameter:
1307: . v - the new vector
1309: Note:
1310: The user is responsible of destroying the returned vector.
1312: Level: beginner
1314: .seealso: BVCreateMat()
1315: @*/
1316: PetscErrorCode BVCreateVec(BV bv,Vec *v)
1317: {
1318: PetscFunctionBegin;
1320: BVCheckSizes(bv,1);
1321: PetscAssertPointer(v,2);
1322: PetscCall(VecDuplicate(bv->t,v));
1323: PetscFunctionReturn(PETSC_SUCCESS);
1324: }
1326: /*@
1327: BVCreateMat - Creates a new Mat object of dense type and copies the contents
1328: of the BV object.
1330: Collective
1332: Input Parameter:
1333: . bv - the basis vectors context
1335: Output Parameter:
1336: . A - the new matrix
1338: Notes:
1339: The user is responsible of destroying the returned matrix.
1341: The matrix contains all columns of the BV, not just the active columns.
1343: Level: intermediate
1345: .seealso: BVCreateFromMat(), BVCreateVec(), BVGetMat()
1346: @*/
1347: PetscErrorCode BVCreateMat(BV bv,Mat *A)
1348: {
1349: PetscInt ksave,lsave;
1350: Mat B;
1351: VecType vtype;
1353: PetscFunctionBegin;
1355: BVCheckSizes(bv,1);
1356: PetscAssertPointer(A,2);
1358: PetscCall(VecGetType(bv->t,&vtype));
1359: PetscCall(MatCreateDenseFromVecType(PetscObjectComm((PetscObject)bv->t),vtype,bv->n,PETSC_DECIDE,bv->N,bv->m,bv->ld,NULL,A));
1360: lsave = bv->l;
1361: ksave = bv->k;
1362: bv->l = 0;
1363: bv->k = bv->m;
1364: PetscCall(BVGetMat(bv,&B));
1365: PetscCall(MatCopy(B,*A,SAME_NONZERO_PATTERN));
1366: PetscCall(BVRestoreMat(bv,&B));
1367: bv->l = lsave;
1368: bv->k = ksave;
1369: PetscFunctionReturn(PETSC_SUCCESS);
1370: }
1372: PetscErrorCode BVGetMat_Default(BV bv,Mat *A)
1373: {
1374: PetscScalar *vv,*aa;
1375: PetscBool create=PETSC_FALSE;
1376: PetscInt m,cols;
1377: VecType vtype;
1379: PetscFunctionBegin;
1380: m = bv->k-bv->l;
1381: if (!bv->Aget) create=PETSC_TRUE;
1382: else {
1383: PetscCall(MatDenseGetArray(bv->Aget,&aa));
1384: PetscCheck(!aa,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_WRONGSTATE,"BVGetMat already called on this BV");
1385: PetscCall(MatGetSize(bv->Aget,NULL,&cols));
1386: if (cols!=m) {
1387: PetscCall(MatDestroy(&bv->Aget));
1388: create=PETSC_TRUE;
1389: }
1390: }
1391: PetscCall(BVGetArray(bv,&vv));
1392: if (create) {
1393: PetscCall(VecGetType(bv->t,&vtype));
1394: PetscCall(MatCreateDenseFromVecType(PetscObjectComm((PetscObject)bv),vtype,bv->n,PETSC_DECIDE,bv->N,m,bv->ld,vv,&bv->Aget)); /* pass a pointer to avoid allocation of storage */
1395: PetscCall(MatDenseReplaceArray(bv->Aget,NULL)); /* replace with a null pointer, the value after BVRestoreMat */
1396: }
1397: PetscCall(MatDensePlaceArray(bv->Aget,vv+(bv->nc+bv->l)*bv->ld)); /* set the actual pointer */
1398: *A = bv->Aget;
1399: PetscFunctionReturn(PETSC_SUCCESS);
1400: }
1402: /*@
1403: BVGetMat - Returns a Mat object of dense type that shares the memory of
1404: the BV object.
1406: Collective
1408: Input Parameter:
1409: . bv - the basis vectors context
1411: Output Parameter:
1412: . A - the matrix
1414: Notes:
1415: The returned matrix contains only the active columns. If the content of
1416: the Mat is modified, these changes are also done in the BV object. The
1417: user must call BVRestoreMat() when no longer needed.
1419: This operation implies a call to BVGetArray(), which may result in data
1420: copies.
1422: Level: advanced
1424: .seealso: BVRestoreMat(), BVCreateMat(), BVGetArray()
1425: @*/
1426: PetscErrorCode BVGetMat(BV bv,Mat *A)
1427: {
1428: PetscFunctionBegin;
1430: BVCheckSizes(bv,1);
1431: PetscAssertPointer(A,2);
1432: PetscUseTypeMethod(bv,getmat,A);
1433: PetscFunctionReturn(PETSC_SUCCESS);
1434: }
1436: PetscErrorCode BVRestoreMat_Default(BV bv,Mat *A)
1437: {
1438: PetscScalar *vv,*aa;
1440: PetscFunctionBegin;
1441: PetscCall(MatDenseGetArray(bv->Aget,&aa));
1442: vv = aa-(bv->nc+bv->l)*bv->ld;
1443: PetscCall(MatDenseResetArray(bv->Aget));
1444: PetscCall(BVRestoreArray(bv,&vv));
1445: *A = NULL;
1446: PetscFunctionReturn(PETSC_SUCCESS);
1447: }
1449: /*@
1450: BVRestoreMat - Restores the Mat obtained with BVGetMat().
1452: Logically Collective
1454: Input Parameters:
1455: + bv - the basis vectors context
1456: - A - the fetched matrix
1458: Note:
1459: A call to this function must match a previous call of BVGetMat().
1460: The effect is that the contents of the Mat are copied back to the
1461: BV internal data structures.
1463: Level: advanced
1465: .seealso: BVGetMat(), BVRestoreArray()
1466: @*/
1467: PetscErrorCode BVRestoreMat(BV bv,Mat *A)
1468: {
1469: PetscFunctionBegin;
1471: BVCheckSizes(bv,1);
1472: PetscAssertPointer(A,2);
1473: PetscCheck(bv->Aget,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_WRONGSTATE,"BVRestoreMat must match a previous call to BVGetMat");
1474: PetscCheck(bv->Aget==*A,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_WRONGSTATE,"Mat argument is not the same as the one obtained with BVGetMat");
1475: PetscUseTypeMethod(bv,restoremat,A);
1476: PetscFunctionReturn(PETSC_SUCCESS);
1477: }
1479: /*
1480: Copy all user-provided attributes of V to another BV object W
1481: */
1482: static inline PetscErrorCode BVDuplicate_Private(BV V,BV W)
1483: {
1484: PetscFunctionBegin;
1485: W->ld = V->ld;
1486: PetscCall(BVSetType(W,((PetscObject)V)->type_name));
1487: W->orthog_type = V->orthog_type;
1488: W->orthog_ref = V->orthog_ref;
1489: W->orthog_eta = V->orthog_eta;
1490: W->orthog_block = V->orthog_block;
1491: if (V->matrix) PetscCall(PetscObjectReference((PetscObject)V->matrix));
1492: W->matrix = V->matrix;
1493: W->indef = V->indef;
1494: W->vmm = V->vmm;
1495: W->rrandom = V->rrandom;
1496: W->deftol = V->deftol;
1497: if (V->rand) PetscCall(PetscObjectReference((PetscObject)V->rand));
1498: W->rand = V->rand;
1499: W->sfocalled = V->sfocalled;
1500: PetscTryTypeMethod(V,duplicate,W);
1501: PetscCall(PetscObjectStateIncrease((PetscObject)W));
1502: PetscFunctionReturn(PETSC_SUCCESS);
1503: }
1505: /*@
1506: BVDuplicate - Creates a new basis vector object of the same type and
1507: dimensions as an existing one.
1509: Collective
1511: Input Parameter:
1512: . V - basis vectors context
1514: Output Parameter:
1515: . W - location to put the new BV
1517: Notes:
1518: The new BV has the same type and dimensions as V, and it shares the same
1519: template vector. Also, the inner product matrix and orthogonalization
1520: options are copied.
1522: BVDuplicate() DOES NOT COPY the entries, but rather allocates storage
1523: for the new basis vectors. Use BVCopy() to copy the contents.
1525: Level: intermediate
1527: .seealso: BVDuplicateResize(), BVCreate(), BVSetSizesFromVec(), BVCopy()
1528: @*/
1529: PetscErrorCode BVDuplicate(BV V,BV *W)
1530: {
1531: PetscFunctionBegin;
1534: BVCheckSizes(V,1);
1535: PetscAssertPointer(W,2);
1536: PetscCall(BVCreate(PetscObjectComm((PetscObject)V),W));
1537: PetscCall(BVSetSizesFromVec(*W,V->t,V->m));
1538: PetscCall(BVDuplicate_Private(V,*W));
1539: PetscFunctionReturn(PETSC_SUCCESS);
1540: }
1542: /*@
1543: BVDuplicateResize - Creates a new basis vector object of the same type and
1544: dimensions as an existing one, but with possibly different number of columns.
1546: Collective
1548: Input Parameters:
1549: + V - basis vectors context
1550: - m - the new number of columns
1552: Output Parameter:
1553: . W - location to put the new BV
1555: Note:
1556: This is equivalent of a call to BVDuplicate() followed by BVResize(). The
1557: contents of V are not copied to W.
1559: Level: intermediate
1561: .seealso: BVDuplicate(), BVResize()
1562: @*/
1563: PetscErrorCode BVDuplicateResize(BV V,PetscInt m,BV *W)
1564: {
1565: PetscFunctionBegin;
1568: BVCheckSizes(V,1);
1570: PetscAssertPointer(W,3);
1571: PetscCall(BVCreate(PetscObjectComm((PetscObject)V),W));
1572: PetscCall(BVSetSizesFromVec(*W,V->t,m));
1573: PetscCall(BVDuplicate_Private(V,*W));
1574: PetscFunctionReturn(PETSC_SUCCESS);
1575: }
1577: /*@
1578: BVGetCachedBV - Returns a BV object stored internally that holds the
1579: result of B*X after a call to BVApplyMatrixBV().
1581: Collective
1583: Input Parameter:
1584: . bv - the basis vectors context
1586: Output Parameter:
1587: . cached - the cached BV
1589: Note:
1590: The cached BV is created if not available previously.
1592: Level: developer
1594: .seealso: BVApplyMatrixBV()
1595: @*/
1596: PetscErrorCode BVGetCachedBV(BV bv,BV *cached)
1597: {
1598: PetscFunctionBegin;
1600: PetscAssertPointer(cached,2);
1601: BVCheckSizes(bv,1);
1602: if (!bv->cached) {
1603: PetscCall(BVCreate(PetscObjectComm((PetscObject)bv),&bv->cached));
1604: PetscCall(BVSetSizesFromVec(bv->cached,bv->t,bv->m));
1605: PetscCall(BVDuplicate_Private(bv,bv->cached));
1606: }
1607: *cached = bv->cached;
1608: PetscFunctionReturn(PETSC_SUCCESS);
1609: }
1611: /*@
1612: BVCopy - Copies a basis vector object into another one, W <- V.
1614: Logically Collective
1616: Input Parameter:
1617: . V - basis vectors context
1619: Output Parameter:
1620: . W - the copy
1622: Note:
1623: Both V and W must be distributed in the same manner; local copies are
1624: done. Only active columns (excluding the leading ones) are copied.
1625: In the destination W, columns are overwritten starting from the leading ones.
1626: Constraints are not copied.
1628: Level: beginner
1630: .seealso: BVCopyVec(), BVCopyColumn(), BVDuplicate(), BVSetActiveColumns()
1631: @*/
1632: PetscErrorCode BVCopy(BV V,BV W)
1633: {
1634: PetscScalar *womega;
1635: const PetscScalar *vomega;
1637: PetscFunctionBegin;
1640: BVCheckSizes(V,1);
1641: BVCheckOp(V,1,copy);
1644: BVCheckSizes(W,2);
1645: PetscCheckSameTypeAndComm(V,1,W,2);
1646: PetscCheck(V->n==W->n,PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_INCOMP,"Mismatching local dimension V %" PetscInt_FMT ", W %" PetscInt_FMT,V->n,W->n);
1647: PetscCheck(V->k-V->l<=W->m-W->l,PetscObjectComm((PetscObject)V),PETSC_ERR_ARG_SIZ,"W has %" PetscInt_FMT " non-leading columns, not enough to store %" PetscInt_FMT " columns",W->m-W->l,V->k-V->l);
1648: if (V==W || !V->n) PetscFunctionReturn(PETSC_SUCCESS);
1650: PetscCall(PetscLogEventBegin(BV_Copy,V,W,0,0));
1651: if (V->indef && V->matrix && V->indef==W->indef && V->matrix==W->matrix) {
1652: /* copy signature */
1653: PetscCall(BV_AllocateSignature(W));
1654: PetscCall(VecGetArrayRead(V->omega,&vomega));
1655: PetscCall(VecGetArray(W->omega,&womega));
1656: PetscCall(PetscArraycpy(womega+W->nc+W->l,vomega+V->nc+V->l,V->k-V->l));
1657: PetscCall(VecRestoreArray(W->omega,&womega));
1658: PetscCall(VecRestoreArrayRead(V->omega,&vomega));
1659: }
1660: PetscUseTypeMethod(V,copy,W);
1661: PetscCall(PetscLogEventEnd(BV_Copy,V,W,0,0));
1662: PetscCall(PetscObjectStateIncrease((PetscObject)W));
1663: PetscFunctionReturn(PETSC_SUCCESS);
1664: }
1666: /*@
1667: BVCopyVec - Copies one of the columns of a basis vectors object into a Vec.
1669: Logically Collective
1671: Input Parameters:
1672: + V - basis vectors context
1673: - j - the column number to be copied
1675: Output Parameter:
1676: . w - the copied column
1678: Note:
1679: Both V and w must be distributed in the same manner; local copies are done.
1681: Level: beginner
1683: .seealso: BVCopy(), BVCopyColumn(), BVInsertVec()
1684: @*/
1685: PetscErrorCode BVCopyVec(BV V,PetscInt j,Vec w)
1686: {
1687: PetscInt n,N;
1688: Vec z;
1690: PetscFunctionBegin;
1693: BVCheckSizes(V,1);
1696: PetscCheckSameComm(V,1,w,3);
1698: PetscCall(VecGetSize(w,&N));
1699: PetscCall(VecGetLocalSize(w,&n));
1700: 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);
1702: PetscCall(PetscLogEventBegin(BV_Copy,V,w,0,0));
1703: PetscCall(BVGetColumn(V,j,&z));
1704: PetscCall(VecCopy(z,w));
1705: PetscCall(BVRestoreColumn(V,j,&z));
1706: PetscCall(PetscLogEventEnd(BV_Copy,V,w,0,0));
1707: PetscFunctionReturn(PETSC_SUCCESS);
1708: }
1710: /*@
1711: BVCopyColumn - Copies the values from one of the columns to another one.
1713: Logically Collective
1715: Input Parameters:
1716: + V - basis vectors context
1717: . j - the number of the source column
1718: - i - the number of the destination column
1720: Level: beginner
1722: .seealso: BVCopy(), BVCopyVec()
1723: @*/
1724: PetscErrorCode BVCopyColumn(BV V,PetscInt j,PetscInt i)
1725: {
1726: PetscScalar *omega;
1728: PetscFunctionBegin;
1731: BVCheckSizes(V,1);
1734: if (j==i) PetscFunctionReturn(PETSC_SUCCESS);
1736: PetscCall(PetscLogEventBegin(BV_Copy,V,0,0,0));
1737: if (V->omega) {
1738: PetscCall(VecGetArray(V->omega,&omega));
1739: omega[i] = omega[j];
1740: PetscCall(VecRestoreArray(V->omega,&omega));
1741: }
1742: PetscUseTypeMethod(V,copycolumn,j,i);
1743: PetscCall(PetscLogEventEnd(BV_Copy,V,0,0,0));
1744: PetscCall(PetscObjectStateIncrease((PetscObject)V));
1745: PetscFunctionReturn(PETSC_SUCCESS);
1746: }
1748: static PetscErrorCode BVGetSplit_Private(BV bv,PetscBool left,BV *split)
1749: {
1750: PetscInt ncols;
1752: PetscFunctionBegin;
1753: ncols = left? bv->nc+bv->l: bv->m-bv->l;
1754: if (*split && ncols!=(*split)->m) PetscCall(BVDestroy(split));
1755: if (!*split) {
1756: PetscCall(BVCreate(PetscObjectComm((PetscObject)bv),split));
1757: (*split)->issplit = left? 1: 2;
1758: (*split)->splitparent = bv;
1759: PetscCall(BVSetSizesFromVec(*split,bv->t,ncols));
1760: PetscCall(BVDuplicate_Private(bv,*split));
1761: }
1762: (*split)->l = 0;
1763: (*split)->k = left? bv->l: bv->k-bv->l;
1764: (*split)->nc = left? bv->nc: 0;
1765: (*split)->m = ncols-(*split)->nc;
1766: if ((*split)->nc) {
1767: (*split)->ci[0] = -(*split)->nc-1;
1768: (*split)->ci[1] = -(*split)->nc-1;
1769: }
1770: if (left) PetscCall(PetscObjectStateGet((PetscObject)*split,&bv->lstate));
1771: else PetscCall(PetscObjectStateGet((PetscObject)*split,&bv->rstate));
1772: PetscFunctionReturn(PETSC_SUCCESS);
1773: }
1775: /*@
1776: BVGetSplit - Splits the BV object into two BV objects that share the
1777: internal data, one of them containing the leading columns and the other
1778: one containing the remaining columns.
1780: Collective
1782: Input Parameter:
1783: . bv - the basis vectors context
1785: Output Parameters:
1786: + L - left BV containing leading columns (can be NULL)
1787: - R - right BV containing remaining columns (can be NULL)
1789: Notes:
1790: The columns are split in two sets. The leading columns (including the
1791: constraints) are assigned to the left BV and the remaining columns
1792: are assigned to the right BV. The number of leading columns, as
1793: specified with BVSetActiveColumns(), must be between 1 and m-1 (to
1794: guarantee that both L and R have at least one column).
1796: The returned BV's must be seen as references (not copies) of the input
1797: BV, that is, modifying them will change the entries of bv as well.
1798: The returned BV's must not be destroyed. BVRestoreSplit() must be called
1799: when they are no longer needed.
1801: Pass NULL for any of the output BV's that is not needed.
1803: Level: advanced
1805: .seealso: BVRestoreSplit(), BVSetActiveColumns(), BVSetNumConstraints()
1806: @*/
1807: PetscErrorCode BVGetSplit(BV bv,BV *L,BV *R)
1808: {
1809: PetscFunctionBegin;
1812: BVCheckSizes(bv,1);
1813: PetscCheck(bv->l,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_WRONGSTATE,"Must indicate the number of leading columns with BVSetActiveColumns()");
1814: PetscCheck(!bv->lsplit,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_WRONGSTATE,"Cannot get the split BV's twice before restoring them with BVRestoreSplit()");
1815: bv->lsplit = bv->nc+bv->l;
1816: PetscCall(BVGetSplit_Private(bv,PETSC_TRUE,&bv->L));
1817: PetscCall(BVGetSplit_Private(bv,PETSC_FALSE,&bv->R));
1818: if (L) *L = bv->L;
1819: if (R) *R = bv->R;
1820: PetscFunctionReturn(PETSC_SUCCESS);
1821: }
1823: /*@
1824: BVRestoreSplit - Restore the BV objects obtained with BVGetSplit().
1826: Logically Collective
1828: Input Parameters:
1829: + bv - the basis vectors context
1830: . L - left BV obtained with BVGetSplit()
1831: - R - right BV obtained with BVGetSplit()
1833: Note:
1834: The arguments must match the corresponding call to BVGetSplit().
1836: Level: advanced
1838: .seealso: BVGetSplit()
1839: @*/
1840: PetscErrorCode BVRestoreSplit(BV bv,BV *L,BV *R)
1841: {
1842: PetscFunctionBegin;
1845: BVCheckSizes(bv,1);
1846: PetscCheck(bv->lsplit,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_WRONGSTATE,"Must call BVGetSplit first");
1847: PetscCheck(!L || *L==bv->L,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_WRONG,"Argument 2 is not the same BV that was obtained with BVGetSplit");
1848: PetscCheck(!R || *R==bv->R,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_WRONG,"Argument 3 is not the same BV that was obtained with BVGetSplit");
1849: PetscCheck(!L || ((*L)->ci[0]<=(*L)->nc-1 && (*L)->ci[1]<=(*L)->nc-1),PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_WRONGSTATE,"Argument 2 has unrestored columns, use BVRestoreColumn()");
1850: PetscCheck(!R || ((*R)->ci[0]<=(*R)->nc-1 && (*R)->ci[1]<=(*R)->nc-1),PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_WRONGSTATE,"Argument 3 has unrestored columns, use BVRestoreColumn()");
1852: PetscTryTypeMethod(bv,restoresplit,L,R);
1853: bv->lsplit = 0;
1854: if (L) *L = NULL;
1855: if (R) *R = NULL;
1856: PetscFunctionReturn(PETSC_SUCCESS);
1857: }
1859: /*@
1860: BVSetDefiniteTolerance - Set the tolerance to be used when checking a
1861: definite inner product.
1863: Logically Collective
1865: Input Parameters:
1866: + bv - basis vectors
1867: - deftol - the tolerance
1869: Options Database Key:
1870: . -bv_definite_tol <deftol> - the tolerance
1872: Notes:
1873: When using a non-standard inner product, see BVSetMatrix(), the solver needs
1874: to compute sqrt(z'*B*z) for various vectors z. If the inner product has not
1875: been declared indefinite, the value z'*B*z must be positive, but due to
1876: rounding error a tiny value may become negative. A tolerance is used to
1877: detect this situation. Likewise, in complex arithmetic z'*B*z should be
1878: real, and we use the same tolerance to check whether a nonzero imaginary part
1879: can be considered negligible.
1881: This function sets this tolerance, which defaults to 10*eps, where eps is
1882: the machine epsilon. The default value should be good for most applications.
1884: Level: advanced
1886: .seealso: BVSetMatrix()
1887: @*/
1888: PetscErrorCode BVSetDefiniteTolerance(BV bv,PetscReal deftol)
1889: {
1890: PetscFunctionBegin;
1893: if (deftol == (PetscReal)PETSC_DEFAULT) bv->deftol = 10*PETSC_MACHINE_EPSILON;
1894: else {
1895: PetscCheck(deftol>0.0,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of deftol. Must be > 0");
1896: bv->deftol = deftol;
1897: }
1898: PetscFunctionReturn(PETSC_SUCCESS);
1899: }
1901: /*@
1902: BVGetDefiniteTolerance - Returns the tolerance for checking a definite
1903: inner product.
1905: Not Collective
1907: Input Parameter:
1908: . bv - the basis vectors
1910: Output Parameter:
1911: . deftol - the tolerance
1913: Level: advanced
1915: .seealso: BVSetDefiniteTolerance()
1916: @*/
1917: PetscErrorCode BVGetDefiniteTolerance(BV bv,PetscReal *deftol)
1918: {
1919: PetscFunctionBegin;
1921: PetscAssertPointer(deftol,2);
1922: *deftol = bv->deftol;
1923: PetscFunctionReturn(PETSC_SUCCESS);
1924: }
1926: /*@
1927: BVSetLeadingDimension - Set the leading dimension to be used for storing the BV data.
1929: Not Collective
1931: Input Parameters:
1932: + bv - basis vectors
1933: - ld - the leading dimension
1935: Notes:
1936: This parameter is relevant for BVMAT, though it might be employed in other types
1937: as well.
1939: When the internal data of the BV is stored as a dense matrix, the leading dimension
1940: has the same meaning as in MatDenseSetLDA(), i.e., the distance in number of
1941: elements from one entry of the matrix to the one in the next column at the same
1942: row. The leading dimension refers to the local array, and hence can be different
1943: in different processes.
1945: The user does not need to change this parameter. The default value is equal to the
1946: number of local rows, but this value may be increased a little to guarantee alignment
1947: (especially in the case of GPU storage).
1949: Level: advanced
1951: .seealso: BVGetLeadingDimension()
1952: @*/
1953: PetscErrorCode BVSetLeadingDimension(BV bv,PetscInt ld)
1954: {
1955: PetscFunctionBegin;
1958: PetscCheck((bv->n<0 && bv->N<0) || !bv->ops->create,PetscObjectComm((PetscObject)bv),PETSC_ERR_ORDER,"Must call BVSetLeadingDimension() before setting the BV type and sizes");
1959: if (ld == PETSC_DEFAULT) bv->ld = 0;
1960: else {
1961: PetscCheck(ld>0,PetscObjectComm((PetscObject)bv),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of ld. Must be > 0");
1962: bv->ld = ld;
1963: }
1964: PetscFunctionReturn(PETSC_SUCCESS);
1965: }
1967: /*@
1968: BVGetLeadingDimension - Returns the leading dimension of the BV.
1970: Not Collective
1972: Input Parameter:
1973: . bv - the basis vectors
1975: Output Parameter:
1976: . ld - the leading dimension
1978: Level: advanced
1980: Notes:
1981: The returned value may be different in different processes.
1983: The leading dimension must be used when accessing the internal array via
1984: BVGetArray() or BVGetArrayRead().
1986: .seealso: BVSetLeadingDimension(), BVGetArray(), BVGetArrayRead()
1987: @*/
1988: PetscErrorCode BVGetLeadingDimension(BV bv,PetscInt *ld)
1989: {
1990: PetscFunctionBegin;
1992: PetscAssertPointer(ld,2);
1993: *ld = bv->ld;
1994: PetscFunctionReturn(PETSC_SUCCESS);
1995: }