Date: 2024-12-02T08:57:25+00:00

Actual source code: nepview.c
slepc-3.22.2 2024-12-02
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:    NEP routines related to various viewers
     12: */

     14: #include <slepc/private/nepimpl.h>
     15: #include <slepc/private/bvimpl.h>
     16: #include <petscdraw.h>

     18: /*@
     19:    NEPView - Prints the NEP data structure.

     21:    Collective

     23:    Input Parameters:
     24: +  nep - the nonlinear eigenproblem solver context
     25: -  viewer - optional visualization context

     27:    Options Database Key:
     28: .  -nep_view -  Calls NEPView() at end of NEPSolve()

     30:    Note:
     31:    The available visualization contexts include
     32: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
     33: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
     34:          output where only the first processor opens
     35:          the file.  All other processors send their
     36:          data to the first processor to print.

     38:    The user can open an alternative visualization context with
     39:    PetscViewerASCIIOpen() - output to a specified file.

     41:    Level: beginner

     43: .seealso: FNView()
     44: @*/
     45: PetscErrorCode NEPView(NEP nep,PetscViewer viewer)
     46: {
     47:   const char     *type=NULL;
     48:   char           str[50];
     49:   PetscInt       i;
     50:   PetscBool      isascii,istrivial;
     51:   PetscViewer    sviewer;
     52:   MPI_Comm       child;

     54:   PetscFunctionBegin;
     56:   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)nep),&viewer));
     58:   PetscCheckSameComm(nep,1,viewer,2);

     60:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
     61:   if (isascii) {
     62:     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)nep,viewer));
     63:     PetscCall(PetscViewerASCIIPushTab(viewer));
     64:     PetscTryTypeMethod(nep,view,viewer);
     65:     PetscCall(PetscViewerASCIIPopTab(viewer));
     66:     if (nep->problem_type) {
     67:       switch (nep->problem_type) {
     68:         case NEP_GENERAL:  type = "general nonlinear eigenvalue problem"; break;
     69:         case NEP_RATIONAL: type = "rational eigenvalue problem"; break;
     70:       }
     71:     } else type = "not yet set";
     72:     PetscCall(PetscViewerASCIIPrintf(viewer,"  problem type: %s\n",type));
     73:     if (nep->fui) {
     74:       switch (nep->fui) {
     75:       case NEP_USER_INTERFACE_CALLBACK:
     76:         PetscCall(PetscViewerASCIIPrintf(viewer,"  nonlinear operator from user callbacks\n"));
     77:         break;
     78:       case NEP_USER_INTERFACE_SPLIT:
     79:         PetscCall(PetscViewerASCIIPrintf(viewer,"  nonlinear operator in split form\n"));
     80:         PetscCall(PetscViewerASCIIPrintf(viewer,"    number of terms: %" PetscInt_FMT "\n",nep->nt));
     81:         PetscCall(PetscViewerASCIIPrintf(viewer,"    nonzero pattern of the matrices: %s\n",MatStructures[nep->mstr]));
     82:         break;
     83:       }
     84:     } else PetscCall(PetscViewerASCIIPrintf(viewer,"  nonlinear operator not specified yet\n"));
     85:     PetscCall(PetscViewerASCIIPrintf(viewer,"  selected portion of the spectrum: "));
     86:     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
     87:     PetscCall(SlepcSNPrintfScalar(str,sizeof(str),nep->target,PETSC_FALSE));
     88:     if (!nep->which) PetscCall(PetscViewerASCIIPrintf(viewer,"not yet set\n"));
     89:     else switch (nep->which) {
     90:       case NEP_WHICH_USER:
     91:         PetscCall(PetscViewerASCIIPrintf(viewer,"user defined\n"));
     92:         break;
     93:       case NEP_TARGET_MAGNITUDE:
     94:         PetscCall(PetscViewerASCIIPrintf(viewer,"closest to target: %s (in magnitude)\n",str));
     95:         break;
     96:       case NEP_TARGET_REAL:
     97:         PetscCall(PetscViewerASCIIPrintf(viewer,"closest to target: %s (along the real axis)\n",str));
     98:         break;
     99:       case NEP_TARGET_IMAGINARY:
    100:         PetscCall(PetscViewerASCIIPrintf(viewer,"closest to target: %s (along the imaginary axis)\n",str));
    101:         break;
    102:       case NEP_LARGEST_MAGNITUDE:
    103:         PetscCall(PetscViewerASCIIPrintf(viewer,"largest eigenvalues in magnitude\n"));
    104:         break;
    105:       case NEP_SMALLEST_MAGNITUDE:
    106:         PetscCall(PetscViewerASCIIPrintf(viewer,"smallest eigenvalues in magnitude\n"));
    107:         break;
    108:       case NEP_LARGEST_REAL:
    109:         PetscCall(PetscViewerASCIIPrintf(viewer,"largest real parts\n"));
    110:         break;
    111:       case NEP_SMALLEST_REAL:
    112:         PetscCall(PetscViewerASCIIPrintf(viewer,"smallest real parts\n"));
    113:         break;
    114:       case NEP_LARGEST_IMAGINARY:
    115:         PetscCall(PetscViewerASCIIPrintf(viewer,"largest imaginary parts\n"));
    116:         break;
    117:       case NEP_SMALLEST_IMAGINARY:
    118:         PetscCall(PetscViewerASCIIPrintf(viewer,"smallest imaginary parts\n"));
    119:         break;
    120:       case NEP_ALL:
    121:         PetscCall(PetscViewerASCIIPrintf(viewer,"all eigenvalues in the region\n"));
    122:         break;
    123:     }
    124:     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
    125:     if (nep->twosided) PetscCall(PetscViewerASCIIPrintf(viewer,"  using two-sided variant (for left eigenvectors)\n"));
    126:     PetscCall(PetscViewerASCIIPrintf(viewer,"  number of eigenvalues (nev): %" PetscInt_FMT "\n",nep->nev));
    127:     PetscCall(PetscViewerASCIIPrintf(viewer,"  number of column vectors (ncv): %" PetscInt_FMT "\n",nep->ncv));
    128:     PetscCall(PetscViewerASCIIPrintf(viewer,"  maximum dimension of projected problem (mpd): %" PetscInt_FMT "\n",nep->mpd));
    129:     PetscCall(PetscViewerASCIIPrintf(viewer,"  maximum number of iterations: %" PetscInt_FMT "\n",nep->max_it));
    130:     PetscCall(PetscViewerASCIIPrintf(viewer,"  tolerance: %g\n",(double)nep->tol));
    131:     PetscCall(PetscViewerASCIIPrintf(viewer,"  convergence test: "));
    132:     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
    133:     switch (nep->conv) {
    134:     case NEP_CONV_ABS:
    135:       PetscCall(PetscViewerASCIIPrintf(viewer,"absolute\n"));break;
    136:     case NEP_CONV_REL:
    137:       PetscCall(PetscViewerASCIIPrintf(viewer,"relative to the eigenvalue\n"));break;
    138:     case NEP_CONV_NORM:
    139:       PetscCall(PetscViewerASCIIPrintf(viewer,"relative to the matrix norms\n"));
    140:       if (nep->nrma) {
    141:         PetscCall(PetscViewerASCIIPrintf(viewer,"  computed matrix norms: %g",(double)nep->nrma[0]));
    142:         for (i=1;i<nep->nt;i++) PetscCall(PetscViewerASCIIPrintf(viewer,", %g",(double)nep->nrma[i]));
    143:         PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
    144:       }
    145:       break;
    146:     case NEP_CONV_USER:
    147:       PetscCall(PetscViewerASCIIPrintf(viewer,"user-defined\n"));break;
    148:     }
    149:     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
    150:     if (nep->refine) {
    151:       PetscCall(PetscViewerASCIIPrintf(viewer,"  iterative refinement: %s, with %s scheme\n",NEPRefineTypes[nep->refine],NEPRefineSchemes[nep->scheme]));
    152:       PetscCall(PetscViewerASCIIPrintf(viewer,"  refinement stopping criterion: tol=%g, its=%" PetscInt_FMT "\n",(double)nep->rtol,nep->rits));
    153:       if (nep->npart>1) PetscCall(PetscViewerASCIIPrintf(viewer,"  splitting communicator in %" PetscInt_FMT " partitions for refinement\n",nep->npart));
    154:     }
    155:     if (nep->nini) PetscCall(PetscViewerASCIIPrintf(viewer,"  dimension of user-provided initial space: %" PetscInt_FMT "\n",PetscAbs(nep->nini)));
    156:   } else PetscTryTypeMethod(nep,view,viewer);
    157:   PetscCall(PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_INFO));
    158:   if (!nep->V) PetscCall(NEPGetBV(nep,&nep->V));
    159:   PetscCall(BVView(nep->V,viewer));
    160:   if (!nep->rg) PetscCall(NEPGetRG(nep,&nep->rg));
    161:   PetscCall(RGIsTrivial(nep->rg,&istrivial));
    162:   if (!istrivial) PetscCall(RGView(nep->rg,viewer));
    163:   if (nep->useds) {
    164:     if (!nep->ds) PetscCall(NEPGetDS(nep,&nep->ds));
    165:     PetscCall(DSView(nep->ds,viewer));
    166:   }
    167:   PetscCall(PetscViewerPopFormat(viewer));
    168:   if (nep->refine!=NEP_REFINE_NONE) {
    169:     PetscCall(PetscViewerASCIIPushTab(viewer));
    170:     if (nep->npart>1) {
    171:       if (nep->refinesubc->color==0) {
    172:         PetscCall(PetscSubcommGetChild(nep->refinesubc,&child));
    173:         PetscCall(PetscViewerASCIIGetStdout(child,&sviewer));
    174:         PetscCall(KSPView(nep->refineksp,sviewer));
    175:       }
    176:     } else PetscCall(KSPView(nep->refineksp,viewer));
    177:     PetscCall(PetscViewerASCIIPopTab(viewer));
    178:   }
    179:   PetscFunctionReturn(PETSC_SUCCESS);
    180: }

    182: /*@
    183:    NEPViewFromOptions - View from options

    185:    Collective

    187:    Input Parameters:
    188: +  nep  - the nonlinear eigensolver context
    189: .  obj  - optional object
    190: -  name - command line option

    192:    Level: intermediate

    194: .seealso: NEPView(), NEPCreate()
    195: @*/
    196: PetscErrorCode NEPViewFromOptions(NEP nep,PetscObject obj,const char name[])
    197: {
    198:   PetscFunctionBegin;
    200:   PetscCall(PetscObjectViewFromOptions((PetscObject)nep,obj,name));
    201:   PetscFunctionReturn(PETSC_SUCCESS);
    202: }

    204: /*@
    205:    NEPConvergedReasonView - Displays the reason a NEP solve converged or diverged.

    207:    Collective

    209:    Input Parameters:
    210: +  nep - the nonlinear eigensolver context
    211: -  viewer - the viewer to display the reason

    213:    Options Database Keys:
    214: .  -nep_converged_reason - print reason for convergence, and number of iterations

    216:    Note:
    217:    To change the format of the output call PetscViewerPushFormat(viewer,format) before
    218:    this call. Use PETSC_VIEWER_DEFAULT for the default, use PETSC_VIEWER_FAILED to only
    219:    display a reason if it fails. The latter can be set in the command line with
    220:    -nep_converged_reason ::failed

    222:    Level: intermediate

    224: .seealso: NEPSetConvergenceTest(), NEPSetTolerances(), NEPGetIterationNumber(), NEPConvergedReasonViewFromOptions()
    225: @*/
    226: PetscErrorCode NEPConvergedReasonView(NEP nep,PetscViewer viewer)
    227: {
    228:   PetscBool         isAscii;
    229:   PetscViewerFormat format;

    231:   PetscFunctionBegin;
    232:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)nep));
    233:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii));
    234:   if (isAscii) {
    235:     PetscCall(PetscViewerGetFormat(viewer,&format));
    236:     PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)nep)->tablevel));
    237:     if (nep->reason > 0 && format != PETSC_VIEWER_FAILED) PetscCall(PetscViewerASCIIPrintf(viewer,"%s Nonlinear eigensolve converged (%" PetscInt_FMT " eigenpair%s) due to %s; iterations %" PetscInt_FMT "\n",((PetscObject)nep)->prefix?((PetscObject)nep)->prefix:"",nep->nconv,(nep->nconv>1)?"s":"",NEPConvergedReasons[nep->reason],nep->its));
    238:     else if (nep->reason <= 0) PetscCall(PetscViewerASCIIPrintf(viewer,"%s Nonlinear eigensolve did not converge due to %s; iterations %" PetscInt_FMT "\n",((PetscObject)nep)->prefix?((PetscObject)nep)->prefix:"",NEPConvergedReasons[nep->reason],nep->its));
    239:     PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)nep)->tablevel));
    240:   }
    241:   PetscFunctionReturn(PETSC_SUCCESS);
    242: }

    244: /*@
    245:    NEPConvergedReasonViewFromOptions - Processes command line options to determine if/how
    246:    the NEP converged reason is to be viewed.

    248:    Collective

    250:    Input Parameter:
    251: .  nep - the nonlinear eigensolver context

    253:    Level: developer

    255: .seealso: NEPConvergedReasonView()
    256: @*/
    257: PetscErrorCode NEPConvergedReasonViewFromOptions(NEP nep)
    258: {
    259:   PetscViewer       viewer;
    260:   PetscBool         flg;
    261:   static PetscBool  incall = PETSC_FALSE;
    262:   PetscViewerFormat format;

    264:   PetscFunctionBegin;
    265:   if (incall) PetscFunctionReturn(PETSC_SUCCESS);
    266:   incall = PETSC_TRUE;
    267:   PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)nep),((PetscObject)nep)->options,((PetscObject)nep)->prefix,"-nep_converged_reason",&viewer,&format,&flg));
    268:   if (flg) {
    269:     PetscCall(PetscViewerPushFormat(viewer,format));
    270:     PetscCall(NEPConvergedReasonView(nep,viewer));
    271:     PetscCall(PetscViewerPopFormat(viewer));
    272:     PetscCall(PetscViewerDestroy(&viewer));
    273:   }
    274:   incall = PETSC_FALSE;
    275:   PetscFunctionReturn(PETSC_SUCCESS);
    276: }

    278: static PetscErrorCode NEPErrorView_ASCII(NEP nep,NEPErrorType etype,PetscViewer viewer)
    279: {
    280:   PetscReal      error;
    281:   PetscInt       i,j,k,nvals;

    283:   PetscFunctionBegin;
    284:   nvals = (nep->which==NEP_ALL)? nep->nconv: nep->nev;
    285:   if (nep->which!=NEP_ALL && nep->nconv<nvals) {
    286:     PetscCall(PetscViewerASCIIPrintf(viewer," Problem: less than %" PetscInt_FMT " eigenvalues converged\n\n",nep->nev));
    287:     PetscFunctionReturn(PETSC_SUCCESS);
    288:   }
    289:   if (nep->which==NEP_ALL && !nvals) {
    290:     PetscCall(PetscViewerASCIIPrintf(viewer," No eigenvalues have been found\n\n"));
    291:     PetscFunctionReturn(PETSC_SUCCESS);
    292:   }
    293:   for (i=0;i<nvals;i++) {
    294:     PetscCall(NEPComputeError(nep,i,etype,&error));
    295:     if (error>=5.0*nep->tol) {
    296:       PetscCall(PetscViewerASCIIPrintf(viewer," Problem: some of the first %" PetscInt_FMT " relative errors are higher than the tolerance\n\n",nvals));
    297:       PetscFunctionReturn(PETSC_SUCCESS);
    298:     }
    299:   }
    300:   if (nep->which==NEP_ALL) PetscCall(PetscViewerASCIIPrintf(viewer," Found %" PetscInt_FMT " eigenvalues, all of them computed up to the required tolerance:",nvals));
    301:   else PetscCall(PetscViewerASCIIPrintf(viewer," All requested eigenvalues computed up to the required tolerance:"));
    302:   for (i=0;i<=(nvals-1)/8;i++) {
    303:     PetscCall(PetscViewerASCIIPrintf(viewer,"\n     "));
    304:     for (j=0;j<PetscMin(8,nvals-8*i);j++) {
    305:       k = nep->perm[8*i+j];
    306:       PetscCall(SlepcPrintEigenvalueASCII(viewer,nep->eigr[k],nep->eigi[k]));
    307:       if (8*i+j+1<nvals) PetscCall(PetscViewerASCIIPrintf(viewer,", "));
    308:     }
    309:   }
    310:   PetscCall(PetscViewerASCIIPrintf(viewer,"\n\n"));
    311:   PetscFunctionReturn(PETSC_SUCCESS);
    312: }

    314: static PetscErrorCode NEPErrorView_DETAIL(NEP nep,NEPErrorType etype,PetscViewer viewer)
    315: {
    316:   PetscReal      error,re,im;
    317:   PetscScalar    kr,ki;
    318:   PetscInt       i;
    319:   char           ex[30],sep[]=" ---------------------- --------------------\n";

    321:   PetscFunctionBegin;
    322:   if (!nep->nconv) PetscFunctionReturn(PETSC_SUCCESS);
    323:   switch (etype) {
    324:     case NEP_ERROR_ABSOLUTE:
    325:       PetscCall(PetscSNPrintf(ex,sizeof(ex),"    ||T(k)x||"));
    326:       break;
    327:     case NEP_ERROR_RELATIVE:
    328:       PetscCall(PetscSNPrintf(ex,sizeof(ex)," ||T(k)x||/||kx||"));
    329:       break;
    330:     case NEP_ERROR_BACKWARD:
    331:       PetscCall(PetscSNPrintf(ex,sizeof(ex),"    eta(x,k)"));
    332:       break;
    333:   }
    334:   PetscCall(PetscViewerASCIIPrintf(viewer,"%s            k             %s\n%s",sep,ex,sep));
    335:   for (i=0;i<nep->nconv;i++) {
    336:     PetscCall(NEPGetEigenpair(nep,i,&kr,&ki,NULL,NULL));
    337:     PetscCall(NEPComputeError(nep,i,etype,&error));
    338: #if defined(PETSC_USE_COMPLEX)
    339:     re = PetscRealPart(kr);
    340:     im = PetscImaginaryPart(kr);
    341: #else
    342:     re = kr;
    343:     im = ki;
    344: #endif
    345:     if (im!=0.0) PetscCall(PetscViewerASCIIPrintf(viewer,"  % 9f%+9fi      %12g\n",(double)re,(double)im,(double)error));
    346:     else PetscCall(PetscViewerASCIIPrintf(viewer,"    % 12f           %12g\n",(double)re,(double)error));
    347:   }
    348:   PetscCall(PetscViewerASCIIPrintf(viewer,"%s",sep));
    349:   PetscFunctionReturn(PETSC_SUCCESS);
    350: }

    352: static PetscErrorCode NEPErrorView_MATLAB(NEP nep,NEPErrorType etype,PetscViewer viewer)
    353: {
    354:   PetscReal      error;
    355:   PetscInt       i;
    356:   const char     *name;

    358:   PetscFunctionBegin;
    359:   PetscCall(PetscObjectGetName((PetscObject)nep,&name));
    360:   PetscCall(PetscViewerASCIIPrintf(viewer,"Error_%s = [\n",name));
    361:   for (i=0;i<nep->nconv;i++) {
    362:     PetscCall(NEPComputeError(nep,i,etype,&error));
    363:     PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e\n",(double)error));
    364:   }
    365:   PetscCall(PetscViewerASCIIPrintf(viewer,"];\n"));
    366:   PetscFunctionReturn(PETSC_SUCCESS);
    367: }

    369: /*@
    370:    NEPErrorView - Displays the errors associated with the computed solution
    371:    (as well as the eigenvalues).

    373:    Collective

    375:    Input Parameters:
    376: +  nep    - the nonlinear eigensolver context
    377: .  etype  - error type
    378: -  viewer - optional visualization context

    380:    Options Database Keys:
    381: +  -nep_error_absolute - print absolute errors of each eigenpair
    382: .  -nep_error_relative - print relative errors of each eigenpair
    383: -  -nep_error_backward - print backward errors of each eigenpair

    385:    Notes:
    386:    By default, this function checks the error of all eigenpairs and prints
    387:    the eigenvalues if all of them are below the requested tolerance.
    388:    If the viewer has format=PETSC_VIEWER_ASCII_INFO_DETAIL then a table with
    389:    eigenvalues and corresponding errors is printed.

    391:    Level: intermediate

    393: .seealso: NEPSolve(), NEPValuesView(), NEPVectorsView()
    394: @*/
    395: PetscErrorCode NEPErrorView(NEP nep,NEPErrorType etype,PetscViewer viewer)
    396: {
    397:   PetscBool         isascii;
    398:   PetscViewerFormat format;

    400:   PetscFunctionBegin;
    402:   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)nep),&viewer));
    404:   PetscCheckSameComm(nep,1,viewer,3);
    405:   NEPCheckSolved(nep,1);
    406:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
    407:   if (!isascii) PetscFunctionReturn(PETSC_SUCCESS);

    409:   PetscCall(PetscViewerGetFormat(viewer,&format));
    410:   switch (format) {
    411:     case PETSC_VIEWER_DEFAULT:
    412:     case PETSC_VIEWER_ASCII_INFO:
    413:       PetscCall(NEPErrorView_ASCII(nep,etype,viewer));
    414:       break;
    415:     case PETSC_VIEWER_ASCII_INFO_DETAIL:
    416:       PetscCall(NEPErrorView_DETAIL(nep,etype,viewer));
    417:       break;
    418:     case PETSC_VIEWER_ASCII_MATLAB:
    419:       PetscCall(NEPErrorView_MATLAB(nep,etype,viewer));
    420:       break;
    421:     default:
    422:       PetscCall(PetscInfo(nep,"Unsupported viewer format %s\n",PetscViewerFormats[format]));
    423:   }
    424:   PetscFunctionReturn(PETSC_SUCCESS);
    425: }

    427: /*@
    428:    NEPErrorViewFromOptions - Processes command line options to determine if/how
    429:    the errors of the computed solution are to be viewed.

    431:    Collective

    433:    Input Parameter:
    434: .  nep - the nonlinear eigensolver context

    436:    Level: developer

    438: .seealso: NEPErrorView()
    439: @*/
    440: PetscErrorCode NEPErrorViewFromOptions(NEP nep)
    441: {
    442:   PetscViewer       viewer;
    443:   PetscBool         flg;
    444:   static PetscBool  incall = PETSC_FALSE;
    445:   PetscViewerFormat format;

    447:   PetscFunctionBegin;
    448:   if (incall) PetscFunctionReturn(PETSC_SUCCESS);
    449:   incall = PETSC_TRUE;
    450:   PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)nep),((PetscObject)nep)->options,((PetscObject)nep)->prefix,"-nep_error_absolute",&viewer,&format,&flg));
    451:   if (flg) {
    452:     PetscCall(PetscViewerPushFormat(viewer,format));
    453:     PetscCall(NEPErrorView(nep,NEP_ERROR_ABSOLUTE,viewer));
    454:     PetscCall(PetscViewerPopFormat(viewer));
    455:     PetscCall(PetscViewerDestroy(&viewer));
    456:   }
    457:   PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)nep),((PetscObject)nep)->options,((PetscObject)nep)->prefix,"-nep_error_relative",&viewer,&format,&flg));
    458:   if (flg) {
    459:     PetscCall(PetscViewerPushFormat(viewer,format));
    460:     PetscCall(NEPErrorView(nep,NEP_ERROR_RELATIVE,viewer));
    461:     PetscCall(PetscViewerPopFormat(viewer));
    462:     PetscCall(PetscViewerDestroy(&viewer));
    463:   }
    464:   PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)nep),((PetscObject)nep)->options,((PetscObject)nep)->prefix,"-nep_error_backward",&viewer,&format,&flg));
    465:   if (flg) {
    466:     PetscCall(PetscViewerPushFormat(viewer,format));
    467:     PetscCall(NEPErrorView(nep,NEP_ERROR_BACKWARD,viewer));
    468:     PetscCall(PetscViewerPopFormat(viewer));
    469:     PetscCall(PetscViewerDestroy(&viewer));
    470:   }
    471:   incall = PETSC_FALSE;
    472:   PetscFunctionReturn(PETSC_SUCCESS);
    473: }

    475: static PetscErrorCode NEPValuesView_DRAW(NEP nep,PetscViewer viewer)
    476: {
    477:   PetscDraw      draw;
    478:   PetscDrawSP    drawsp;
    479:   PetscReal      re,im;
    480:   PetscInt       i,k;

    482:   PetscFunctionBegin;
    483:   if (!nep->nconv) PetscFunctionReturn(PETSC_SUCCESS);
    484:   PetscCall(PetscViewerDrawGetDraw(viewer,0,&draw));
    485:   PetscCall(PetscDrawSetTitle(draw,"Computed Eigenvalues"));
    486:   PetscCall(PetscDrawSPCreate(draw,1,&drawsp));
    487:   for (i=0;i<nep->nconv;i++) {
    488:     k = nep->perm[i];
    489: #if defined(PETSC_USE_COMPLEX)
    490:     re = PetscRealPart(nep->eigr[k]);
    491:     im = PetscImaginaryPart(nep->eigr[k]);
    492: #else
    493:     re = nep->eigr[k];
    494:     im = nep->eigi[k];
    495: #endif
    496:     PetscCall(PetscDrawSPAddPoint(drawsp,&re,&im));
    497:   }
    498:   PetscCall(PetscDrawSPDraw(drawsp,PETSC_TRUE));
    499:   PetscCall(PetscDrawSPSave(drawsp));
    500:   PetscCall(PetscDrawSPDestroy(&drawsp));
    501:   PetscFunctionReturn(PETSC_SUCCESS);
    502: }

    504: static PetscErrorCode NEPValuesView_BINARY(NEP nep,PetscViewer viewer)
    505: {
    506: #if defined(PETSC_HAVE_COMPLEX)
    507:   PetscInt       i,k;
    508:   PetscComplex   *ev;
    509: #endif

    511:   PetscFunctionBegin;
    512: #if defined(PETSC_HAVE_COMPLEX)
    513:   PetscCall(PetscMalloc1(nep->nconv,&ev));
    514:   for (i=0;i<nep->nconv;i++) {
    515:     k = nep->perm[i];
    516: #if defined(PETSC_USE_COMPLEX)
    517:     ev[i] = nep->eigr[k];
    518: #else
    519:     ev[i] = PetscCMPLX(nep->eigr[k],nep->eigi[k]);
    520: #endif
    521:   }
    522:   PetscCall(PetscViewerBinaryWrite(viewer,ev,nep->nconv,PETSC_COMPLEX));
    523:   PetscCall(PetscFree(ev));
    524: #endif
    525:   PetscFunctionReturn(PETSC_SUCCESS);
    526: }

    528: #if defined(PETSC_HAVE_HDF5)
    529: static PetscErrorCode NEPValuesView_HDF5(NEP nep,PetscViewer viewer)
    530: {
    531:   PetscInt       i,k,n,N;
    532:   PetscMPIInt    rank;
    533:   Vec            v;
    534:   char           vname[30];
    535:   const char     *ename;

    537:   PetscFunctionBegin;
    538:   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)nep),&rank));
    539:   N = nep->nconv;
    540:   n = rank? 0: N;
    541:   /* create a vector containing the eigenvalues */
    542:   PetscCall(VecCreateMPI(PetscObjectComm((PetscObject)nep),n,N,&v));
    543:   PetscCall(PetscObjectGetName((PetscObject)nep,&ename));
    544:   PetscCall(PetscSNPrintf(vname,sizeof(vname),"eigr_%s",ename));
    545:   PetscCall(PetscObjectSetName((PetscObject)v,vname));
    546:   if (!rank) {
    547:     for (i=0;i<nep->nconv;i++) {
    548:       k = nep->perm[i];
    549:       PetscCall(VecSetValue(v,i,nep->eigr[k],INSERT_VALUES));
    550:     }
    551:   }
    552:   PetscCall(VecAssemblyBegin(v));
    553:   PetscCall(VecAssemblyEnd(v));
    554:   PetscCall(VecView(v,viewer));
    555: #if !defined(PETSC_USE_COMPLEX)
    556:   /* in real scalars write the imaginary part as a separate vector */
    557:   PetscCall(PetscSNPrintf(vname,sizeof(vname),"eigi_%s",ename));
    558:   PetscCall(PetscObjectSetName((PetscObject)v,vname));
    559:   if (!rank) {
    560:     for (i=0;i<nep->nconv;i++) {
    561:       k = nep->perm[i];
    562:       PetscCall(VecSetValue(v,i,nep->eigi[k],INSERT_VALUES));
    563:     }
    564:   }
    565:   PetscCall(VecAssemblyBegin(v));
    566:   PetscCall(VecAssemblyEnd(v));
    567:   PetscCall(VecView(v,viewer));
    568: #endif
    569:   PetscCall(VecDestroy(&v));
    570:   PetscFunctionReturn(PETSC_SUCCESS);
    571: }
    572: #endif

    574: static PetscErrorCode NEPValuesView_ASCII(NEP nep,PetscViewer viewer)
    575: {
    576:   PetscInt       i,k;

    578:   PetscFunctionBegin;
    579:   PetscCall(PetscViewerASCIIPrintf(viewer,"Eigenvalues = \n"));
    580:   for (i=0;i<nep->nconv;i++) {
    581:     k = nep->perm[i];
    582:     PetscCall(PetscViewerASCIIPrintf(viewer,"   "));
    583:     PetscCall(SlepcPrintEigenvalueASCII(viewer,nep->eigr[k],nep->eigi[k]));
    584:     PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
    585:   }
    586:   PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
    587:   PetscFunctionReturn(PETSC_SUCCESS);
    588: }

    590: static PetscErrorCode NEPValuesView_MATLAB(NEP nep,PetscViewer viewer)
    591: {
    592:   PetscInt       i,k;
    593:   PetscReal      re,im;
    594:   const char     *name;

    596:   PetscFunctionBegin;
    597:   PetscCall(PetscObjectGetName((PetscObject)nep,&name));
    598:   PetscCall(PetscViewerASCIIPrintf(viewer,"Lambda_%s = [\n",name));
    599:   for (i=0;i<nep->nconv;i++) {
    600:     k = nep->perm[i];
    601: #if defined(PETSC_USE_COMPLEX)
    602:     re = PetscRealPart(nep->eigr[k]);
    603:     im = PetscImaginaryPart(nep->eigr[k]);
    604: #else
    605:     re = nep->eigr[k];
    606:     im = nep->eigi[k];
    607: #endif
    608:     if (im!=0.0) PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e%+18.16ei\n",(double)re,(double)im));
    609:     else PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e\n",(double)re));
    610:   }
    611:   PetscCall(PetscViewerASCIIPrintf(viewer,"];\n"));
    612:   PetscFunctionReturn(PETSC_SUCCESS);
    613: }

    615: /*@
    616:    NEPValuesView - Displays the computed eigenvalues in a viewer.

    618:    Collective

    620:    Input Parameters:
    621: +  nep    - the nonlinear eigensolver context
    622: -  viewer - the viewer

    624:    Options Database Key:
    625: .  -nep_view_values - print computed eigenvalues

    627:    Level: intermediate

    629: .seealso: NEPSolve(), NEPVectorsView(), NEPErrorView()
    630: @*/
    631: PetscErrorCode NEPValuesView(NEP nep,PetscViewer viewer)
    632: {
    633:   PetscBool         isascii,isdraw,isbinary;
    634:   PetscViewerFormat format;
    635: #if defined(PETSC_HAVE_HDF5)
    636:   PetscBool         ishdf5;
    637: #endif

    639:   PetscFunctionBegin;
    641:   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)nep),&viewer));
    643:   PetscCheckSameComm(nep,1,viewer,2);
    644:   NEPCheckSolved(nep,1);
    645:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw));
    646:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary));
    647: #if defined(PETSC_HAVE_HDF5)
    648:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5));
    649: #endif
    650:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
    651:   if (isdraw) PetscCall(NEPValuesView_DRAW(nep,viewer));
    652:   else if (isbinary) PetscCall(NEPValuesView_BINARY(nep,viewer));
    653: #if defined(PETSC_HAVE_HDF5)
    654:   else if (ishdf5) PetscCall(NEPValuesView_HDF5(nep,viewer));
    655: #endif
    656:   else if (isascii) {
    657:     PetscCall(PetscViewerGetFormat(viewer,&format));
    658:     switch (format) {
    659:       case PETSC_VIEWER_DEFAULT:
    660:       case PETSC_VIEWER_ASCII_INFO:
    661:       case PETSC_VIEWER_ASCII_INFO_DETAIL:
    662:         PetscCall(NEPValuesView_ASCII(nep,viewer));
    663:         break;
    664:       case PETSC_VIEWER_ASCII_MATLAB:
    665:         PetscCall(NEPValuesView_MATLAB(nep,viewer));
    666:         break;
    667:       default:
    668:         PetscCall(PetscInfo(nep,"Unsupported viewer format %s\n",PetscViewerFormats[format]));
    669:     }
    670:   }
    671:   PetscFunctionReturn(PETSC_SUCCESS);
    672: }

    674: /*@
    675:    NEPValuesViewFromOptions - Processes command line options to determine if/how
    676:    the computed eigenvalues are to be viewed.

    678:    Collective

    680:    Input Parameter:
    681: .  nep - the nonlinear eigensolver context

    683:    Level: developer

    685: .seealso: NEPValuesView()
    686: @*/
    687: PetscErrorCode NEPValuesViewFromOptions(NEP nep)
    688: {
    689:   PetscViewer       viewer;
    690:   PetscBool         flg;
    691:   static PetscBool  incall = PETSC_FALSE;
    692:   PetscViewerFormat format;

    694:   PetscFunctionBegin;
    695:   if (incall) PetscFunctionReturn(PETSC_SUCCESS);
    696:   incall = PETSC_TRUE;
    697:   PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)nep),((PetscObject)nep)->options,((PetscObject)nep)->prefix,"-nep_view_values",&viewer,&format,&flg));
    698:   if (flg) {
    699:     PetscCall(PetscViewerPushFormat(viewer,format));
    700:     PetscCall(NEPValuesView(nep,viewer));
    701:     PetscCall(PetscViewerPopFormat(viewer));
    702:     PetscCall(PetscViewerDestroy(&viewer));
    703:   }
    704:   incall = PETSC_FALSE;
    705:   PetscFunctionReturn(PETSC_SUCCESS);
    706: }

    708: /*@
    709:    NEPVectorsView - Outputs computed eigenvectors to a viewer.

    711:    Collective

    713:    Input Parameters:
    714: +  nep    - the nonlinear eigensolver context
    715: -  viewer - the viewer

    717:    Options Database Key:
    718: .  -nep_view_vectors - output eigenvectors.

    720:    Notes:
    721:    If PETSc was configured with real scalars, complex conjugate eigenvectors
    722:    will be viewed as two separate real vectors, one containing the real part
    723:    and another one containing the imaginary part.

    725:    If left eigenvectors were computed with a two-sided eigensolver, the right
    726:    and left eigenvectors are interleaved, that is, the vectors are output in
    727:    the following order X0, Y0, X1, Y1, X2, Y2, ...

    729:    Level: intermediate

    731: .seealso: NEPSolve(), NEPValuesView(), NEPErrorView()
    732: @*/
    733: PetscErrorCode NEPVectorsView(NEP nep,PetscViewer viewer)
    734: {
    735:   PetscInt       i,k;
    736:   Vec            xr,xi=NULL;

    738:   PetscFunctionBegin;
    740:   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)nep),&viewer));
    742:   PetscCheckSameComm(nep,1,viewer,2);
    743:   NEPCheckSolved(nep,1);
    744:   if (nep->nconv) {
    745:     PetscCall(NEPComputeVectors(nep));
    746:     PetscCall(BVCreateVec(nep->V,&xr));
    747: #if !defined(PETSC_USE_COMPLEX)
    748:     PetscCall(BVCreateVec(nep->V,&xi));
    749: #endif
    750:     for (i=0;i<nep->nconv;i++) {
    751:       k = nep->perm[i];
    752:       PetscCall(BV_GetEigenvector(nep->V,k,nep->eigi[k],xr,xi));
    753:       PetscCall(SlepcViewEigenvector(viewer,xr,xi,"X",i,(PetscObject)nep));
    754:       if (nep->twosided) {
    755:         PetscCall(BV_GetEigenvector(nep->W,k,nep->eigi[k],xr,xi));
    756:         PetscCall(SlepcViewEigenvector(viewer,xr,xi,"Y",i,(PetscObject)nep));
    757:       }
    758:     }
    759:     PetscCall(VecDestroy(&xr));
    760: #if !defined(PETSC_USE_COMPLEX)
    761:     PetscCall(VecDestroy(&xi));
    762: #endif
    763:   }
    764:   PetscFunctionReturn(PETSC_SUCCESS);
    765: }

    767: /*@
    768:    NEPVectorsViewFromOptions - Processes command line options to determine if/how
    769:    the computed eigenvectors are to be viewed.

    771:    Collective

    773:    Input Parameter:
    774: .  nep - the nonlinear eigensolver context

    776:    Level: developer

    778: .seealso: NEPVectorsView()
    779: @*/
    780: PetscErrorCode NEPVectorsViewFromOptions(NEP nep)
    781: {
    782:   PetscViewer       viewer;
    783:   PetscBool         flg = PETSC_FALSE;
    784:   static PetscBool  incall = PETSC_FALSE;
    785:   PetscViewerFormat format;

    787:   PetscFunctionBegin;
    788:   if (incall) PetscFunctionReturn(PETSC_SUCCESS);
    789:   incall = PETSC_TRUE;
    790:   PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)nep),((PetscObject)nep)->options,((PetscObject)nep)->prefix,"-nep_view_vectors",&viewer,&format,&flg));
    791:   if (flg) {
    792:     PetscCall(PetscViewerPushFormat(viewer,format));
    793:     PetscCall(NEPVectorsView(nep,viewer));
    794:     PetscCall(PetscViewerPopFormat(viewer));
    795:     PetscCall(PetscViewerDestroy(&viewer));
    796:   }
    797:   incall = PETSC_FALSE;
    798:   PetscFunctionReturn(PETSC_SUCCESS);
    799: }