Date: 2024-09-25T09:34:26+00:00

Actual source code: bvfunc.c
slepc-3.21.2 2024-09-25
Report Typos and Errors

      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: /*@C
    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:   *newbv = NULL;
    165:   PetscCall(BVInitializePackage());
    166:   PetscCall(SlepcHeaderCreate(bv,BV_CLASSID,"BV","Basis Vectors","BV",comm,BVDestroy,BVView));

    168:   bv->map          = NULL;
    169:   bv->vtype        = NULL;
    170:   bv->n            = -1;
    171:   bv->N            = -1;
    172:   bv->m            = 0;
    173:   bv->l            = 0;
    174:   bv->k            = 0;
    175:   bv->nc           = 0;
    176:   bv->ld           = 0;
    177:   bv->orthog_type  = BV_ORTHOG_CGS;
    178:   bv->orthog_ref   = BV_ORTHOG_REFINE_IFNEEDED;
    179:   bv->orthog_eta   = 0.7071;
    180:   bv->orthog_block = BV_ORTHOG_BLOCK_GS;
    181:   bv->matrix       = NULL;
    182:   bv->indef        = PETSC_FALSE;
    183:   bv->vmm          = BV_MATMULT_MAT;
    184:   bv->rrandom      = PETSC_FALSE;
    185:   bv->deftol       = 10*PETSC_MACHINE_EPSILON;

    187:   bv->buffer       = NULL;
    188:   bv->Abuffer      = NULL;
    189:   bv->Bx           = NULL;
    190:   bv->xid          = 0;
    191:   bv->xstate       = 0;
    192:   bv->cv[0]        = NULL;
    193:   bv->cv[1]        = NULL;
    194:   bv->ci[0]        = -1;
    195:   bv->ci[1]        = -1;
    196:   bv->st[0]        = -1;
    197:   bv->st[1]        = -1;
    198:   bv->id[0]        = 0;
    199:   bv->id[1]        = 0;
    200:   bv->h            = NULL;
    201:   bv->c            = NULL;
    202:   bv->omega        = NULL;
    203:   bv->defersfo     = PETSC_FALSE;
    204:   bv->cached       = NULL;
    205:   bv->bvstate      = 0;
    206:   bv->L            = NULL;
    207:   bv->R            = NULL;
    208:   bv->lstate       = 0;
    209:   bv->rstate       = 0;
    210:   bv->lsplit       = 0;
    211:   bv->issplit      = 0;
    212:   bv->splitparent  = NULL;
    213:   bv->rand         = NULL;
    214:   bv->Acreate      = NULL;
    215:   bv->Aget         = NULL;
    216:   bv->cuda         = 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: /*@C
    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: /*@C
    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: /*@C
    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: /*@C
    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)":""));
    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: /*@C
    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