Date: 2022-10-01T06:40:34+00:00

Actual source code: nepview.c
slepc-3.18.0 2022-10-01
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: /*@C
     19:    NEPView - Prints the NEP data structure.

     21:    Collective on nep

     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;

     55:   if (!viewer) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)nep),&viewer);

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

    181: /*@C
    182:    NEPViewFromOptions - View from options

    184:    Collective on NEP

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

    191:    Level: intermediate

    193: .seealso: NEPView(), NEPCreate()
    194: @*/
    195: PetscErrorCode NEPViewFromOptions(NEP nep,PetscObject obj,const char name[])
    196: {
    198:   PetscObjectViewFromOptions((PetscObject)nep,obj,name);
    199:   return 0;
    200: }

    202: /*@C
    203:    NEPConvergedReasonView - Displays the reason a NEP solve converged or diverged.

    205:    Collective on nep

    207:    Input Parameters:
    208: +  nep - the nonlinear eigensolver context
    209: -  viewer - the viewer to display the reason

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

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

    220:    Level: intermediate

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

    229:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)nep));
    230:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);
    231:   if (isAscii) {
    232:     PetscViewerGetFormat(viewer,&format);
    233:     PetscViewerASCIIAddTab(viewer,((PetscObject)nep)->tablevel);
    234:     if (nep->reason > 0 && format != PETSC_VIEWER_FAILED) 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);
    235:     else if (nep->reason <= 0) 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);
    236:     PetscViewerASCIISubtractTab(viewer,((PetscObject)nep)->tablevel);
    237:   }
    238:   return 0;
    239: }

    241: /*@
    242:    NEPConvergedReasonViewFromOptions - Processes command line options to determine if/how
    243:    the NEP converged reason is to be viewed.

    245:    Collective on nep

    247:    Input Parameter:
    248: .  nep - the nonlinear eigensolver context

    250:    Level: developer

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

    261:   if (incall) return 0;
    262:   incall = PETSC_TRUE;
    263:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)nep),((PetscObject)nep)->options,((PetscObject)nep)->prefix,"-nep_converged_reason",&viewer,&format,&flg);
    264:   if (flg) {
    265:     PetscViewerPushFormat(viewer,format);
    266:     NEPConvergedReasonView(nep,viewer);
    267:     PetscViewerPopFormat(viewer);
    268:     PetscViewerDestroy(&viewer);
    269:   }
    270:   incall = PETSC_FALSE;
    271:   return 0;
    272: }

    274: static PetscErrorCode NEPErrorView_ASCII(NEP nep,NEPErrorType etype,PetscViewer viewer)
    275: {
    276:   PetscReal      error;
    277:   PetscInt       i,j,k,nvals;

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

    309: static PetscErrorCode NEPErrorView_DETAIL(NEP nep,NEPErrorType etype,PetscViewer viewer)
    310: {
    311:   PetscReal      error,re,im;
    312:   PetscScalar    kr,ki;
    313:   PetscInt       i;
    314:   char           ex[30],sep[]=" ---------------------- --------------------\n";

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

    346: static PetscErrorCode NEPErrorView_MATLAB(NEP nep,NEPErrorType etype,PetscViewer viewer)
    347: {
    348:   PetscReal      error;
    349:   PetscInt       i;
    350:   const char     *name;

    352:   PetscObjectGetName((PetscObject)nep,&name);
    353:   PetscViewerASCIIPrintf(viewer,"Error_%s = [\n",name);
    354:   for (i=0;i<nep->nconv;i++) {
    355:     NEPComputeError(nep,i,etype,&error);
    356:     PetscViewerASCIIPrintf(viewer,"%18.16e\n",(double)error);
    357:   }
    358:   PetscViewerASCIIPrintf(viewer,"];\n");
    359:   return 0;
    360: }

    362: /*@C
    363:    NEPErrorView - Displays the errors associated with the computed solution
    364:    (as well as the eigenvalues).

    366:    Collective on nep

    368:    Input Parameters:
    369: +  nep    - the nonlinear eigensolver context
    370: .  etype  - error type
    371: -  viewer - optional visualization context

    373:    Options Database Keys:
    374: +  -nep_error_absolute - print absolute errors of each eigenpair
    375: .  -nep_error_relative - print relative errors of each eigenpair
    376: -  -nep_error_backward - print backward errors of each eigenpair

    378:    Notes:
    379:    By default, this function checks the error of all eigenpairs and prints
    380:    the eigenvalues if all of them are below the requested tolerance.
    381:    If the viewer has format=PETSC_VIEWER_ASCII_INFO_DETAIL then a table with
    382:    eigenvalues and corresponding errors is printed.

    384:    Level: intermediate

    386: .seealso: NEPSolve(), NEPValuesView(), NEPVectorsView()
    387: @*/
    388: PetscErrorCode NEPErrorView(NEP nep,NEPErrorType etype,PetscViewer viewer)
    389: {
    390:   PetscBool         isascii;
    391:   PetscViewerFormat format;

    394:   if (!viewer) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)nep),&viewer);
    397:   NEPCheckSolved(nep,1);
    398:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    399:   if (!isascii) return 0;

    401:   PetscViewerGetFormat(viewer,&format);
    402:   switch (format) {
    403:     case PETSC_VIEWER_DEFAULT:
    404:     case PETSC_VIEWER_ASCII_INFO:
    405:       NEPErrorView_ASCII(nep,etype,viewer);
    406:       break;
    407:     case PETSC_VIEWER_ASCII_INFO_DETAIL:
    408:       NEPErrorView_DETAIL(nep,etype,viewer);
    409:       break;
    410:     case PETSC_VIEWER_ASCII_MATLAB:
    411:       NEPErrorView_MATLAB(nep,etype,viewer);
    412:       break;
    413:     default:
    414:       PetscInfo(nep,"Unsupported viewer format %s\n",PetscViewerFormats[format]);
    415:   }
    416:   return 0;
    417: }

    419: /*@
    420:    NEPErrorViewFromOptions - Processes command line options to determine if/how
    421:    the errors of the computed solution are to be viewed.

    423:    Collective on nep

    425:    Input Parameter:
    426: .  nep - the nonlinear eigensolver context

    428:    Level: developer

    430: .seealso: NEPErrorView()
    431: @*/
    432: PetscErrorCode NEPErrorViewFromOptions(NEP nep)
    433: {
    434:   PetscViewer       viewer;
    435:   PetscBool         flg;
    436:   static PetscBool  incall = PETSC_FALSE;
    437:   PetscViewerFormat format;

    439:   if (incall) return 0;
    440:   incall = PETSC_TRUE;
    441:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)nep),((PetscObject)nep)->options,((PetscObject)nep)->prefix,"-nep_error_absolute",&viewer,&format,&flg);
    442:   if (flg) {
    443:     PetscViewerPushFormat(viewer,format);
    444:     NEPErrorView(nep,NEP_ERROR_ABSOLUTE,viewer);
    445:     PetscViewerPopFormat(viewer);
    446:     PetscViewerDestroy(&viewer);
    447:   }
    448:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)nep),((PetscObject)nep)->options,((PetscObject)nep)->prefix,"-nep_error_relative",&viewer,&format,&flg);
    449:   if (flg) {
    450:     PetscViewerPushFormat(viewer,format);
    451:     NEPErrorView(nep,NEP_ERROR_RELATIVE,viewer);
    452:     PetscViewerPopFormat(viewer);
    453:     PetscViewerDestroy(&viewer);
    454:   }
    455:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)nep),((PetscObject)nep)->options,((PetscObject)nep)->prefix,"-nep_error_backward",&viewer,&format,&flg);
    456:   if (flg) {
    457:     PetscViewerPushFormat(viewer,format);
    458:     NEPErrorView(nep,NEP_ERROR_BACKWARD,viewer);
    459:     PetscViewerPopFormat(viewer);
    460:     PetscViewerDestroy(&viewer);
    461:   }
    462:   incall = PETSC_FALSE;
    463:   return 0;
    464: }

    466: static PetscErrorCode NEPValuesView_DRAW(NEP nep,PetscViewer viewer)
    467: {
    468:   PetscDraw      draw;
    469:   PetscDrawSP    drawsp;
    470:   PetscReal      re,im;
    471:   PetscInt       i,k;

    473:   if (!nep->nconv) return 0;
    474:   PetscViewerDrawGetDraw(viewer,0,&draw);
    475:   PetscDrawSetTitle(draw,"Computed Eigenvalues");
    476:   PetscDrawSPCreate(draw,1,&drawsp);
    477:   for (i=0;i<nep->nconv;i++) {
    478:     k = nep->perm[i];
    479: #if defined(PETSC_USE_COMPLEX)
    480:     re = PetscRealPart(nep->eigr[k]);
    481:     im = PetscImaginaryPart(nep->eigr[k]);
    482: #else
    483:     re = nep->eigr[k];
    484:     im = nep->eigi[k];
    485: #endif
    486:     PetscDrawSPAddPoint(drawsp,&re,&im);
    487:   }
    488:   PetscDrawSPDraw(drawsp,PETSC_TRUE);
    489:   PetscDrawSPSave(drawsp);
    490:   PetscDrawSPDestroy(&drawsp);
    491:   return 0;
    492: }

    494: static PetscErrorCode NEPValuesView_BINARY(NEP nep,PetscViewer viewer)
    495: {
    496: #if defined(PETSC_HAVE_COMPLEX)
    497:   PetscInt       i,k;
    498:   PetscComplex   *ev;
    499: #endif

    501: #if defined(PETSC_HAVE_COMPLEX)
    502:   PetscMalloc1(nep->nconv,&ev);
    503:   for (i=0;i<nep->nconv;i++) {
    504:     k = nep->perm[i];
    505: #if defined(PETSC_USE_COMPLEX)
    506:     ev[i] = nep->eigr[k];
    507: #else
    508:     ev[i] = PetscCMPLX(nep->eigr[k],nep->eigi[k]);
    509: #endif
    510:   }
    511:   PetscViewerBinaryWrite(viewer,ev,nep->nconv,PETSC_COMPLEX);
    512:   PetscFree(ev);
    513: #endif
    514:   return 0;
    515: }

    517: #if defined(PETSC_HAVE_HDF5)
    518: static PetscErrorCode NEPValuesView_HDF5(NEP nep,PetscViewer viewer)
    519: {
    520:   PetscInt       i,k,n,N;
    521:   PetscMPIInt    rank;
    522:   Vec            v;
    523:   char           vname[30];
    524:   const char     *ename;

    526:   MPI_Comm_rank(PetscObjectComm((PetscObject)nep),&rank);
    527:   N = nep->nconv;
    528:   n = rank? 0: N;
    529:   /* create a vector containing the eigenvalues */
    530:   VecCreateMPI(PetscObjectComm((PetscObject)nep),n,N,&v);
    531:   PetscObjectGetName((PetscObject)nep,&ename);
    532:   PetscSNPrintf(vname,sizeof(vname),"eigr_%s",ename);
    533:   PetscObjectSetName((PetscObject)v,vname);
    534:   if (!rank) {
    535:     for (i=0;i<nep->nconv;i++) {
    536:       k = nep->perm[i];
    537:       VecSetValue(v,i,nep->eigr[k],INSERT_VALUES);
    538:     }
    539:   }
    540:   VecAssemblyBegin(v);
    541:   VecAssemblyEnd(v);
    542:   VecView(v,viewer);
    543: #if !defined(PETSC_USE_COMPLEX)
    544:   /* in real scalars write the imaginary part as a separate vector */
    545:   PetscSNPrintf(vname,sizeof(vname),"eigi_%s",ename);
    546:   PetscObjectSetName((PetscObject)v,vname);
    547:   if (!rank) {
    548:     for (i=0;i<nep->nconv;i++) {
    549:       k = nep->perm[i];
    550:       VecSetValue(v,i,nep->eigi[k],INSERT_VALUES);
    551:     }
    552:   }
    553:   VecAssemblyBegin(v);
    554:   VecAssemblyEnd(v);
    555:   VecView(v,viewer);
    556: #endif
    557:   VecDestroy(&v);
    558:   return 0;
    559: }
    560: #endif

    562: static PetscErrorCode NEPValuesView_ASCII(NEP nep,PetscViewer viewer)
    563: {
    564:   PetscInt       i,k;

    566:   PetscViewerASCIIPrintf(viewer,"Eigenvalues = \n");
    567:   for (i=0;i<nep->nconv;i++) {
    568:     k = nep->perm[i];
    569:     PetscViewerASCIIPrintf(viewer,"   ");
    570:     SlepcPrintEigenvalueASCII(viewer,nep->eigr[k],nep->eigi[k]);
    571:     PetscViewerASCIIPrintf(viewer,"\n");
    572:   }
    573:   PetscViewerASCIIPrintf(viewer,"\n");
    574:   return 0;
    575: }

    577: static PetscErrorCode NEPValuesView_MATLAB(NEP nep,PetscViewer viewer)
    578: {
    579:   PetscInt       i,k;
    580:   PetscReal      re,im;
    581:   const char     *name;

    583:   PetscObjectGetName((PetscObject)nep,&name);
    584:   PetscViewerASCIIPrintf(viewer,"Lambda_%s = [\n",name);
    585:   for (i=0;i<nep->nconv;i++) {
    586:     k = nep->perm[i];
    587: #if defined(PETSC_USE_COMPLEX)
    588:     re = PetscRealPart(nep->eigr[k]);
    589:     im = PetscImaginaryPart(nep->eigr[k]);
    590: #else
    591:     re = nep->eigr[k];
    592:     im = nep->eigi[k];
    593: #endif
    594:     if (im!=0.0) PetscViewerASCIIPrintf(viewer,"%18.16e%+18.16ei\n",(double)re,(double)im);
    595:     else PetscViewerASCIIPrintf(viewer,"%18.16e\n",(double)re);
    596:   }
    597:   PetscViewerASCIIPrintf(viewer,"];\n");
    598:   return 0;
    599: }

    601: /*@C
    602:    NEPValuesView - Displays the computed eigenvalues in a viewer.

    604:    Collective on nep

    606:    Input Parameters:
    607: +  nep    - the nonlinear eigensolver context
    608: -  viewer - the viewer

    610:    Options Database Key:
    611: .  -nep_view_values - print computed eigenvalues

    613:    Level: intermediate

    615: .seealso: NEPSolve(), NEPVectorsView(), NEPErrorView()
    616: @*/
    617: PetscErrorCode NEPValuesView(NEP nep,PetscViewer viewer)
    618: {
    619:   PetscBool         isascii,isdraw,isbinary;
    620:   PetscViewerFormat format;
    621: #if defined(PETSC_HAVE_HDF5)
    622:   PetscBool         ishdf5;
    623: #endif

    626:   if (!viewer) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)nep),&viewer);
    629:   NEPCheckSolved(nep,1);
    630:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);
    631:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
    632: #if defined(PETSC_HAVE_HDF5)
    633:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);
    634: #endif
    635:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    636:   if (isdraw) NEPValuesView_DRAW(nep,viewer);
    637:   else if (isbinary) NEPValuesView_BINARY(nep,viewer);
    638: #if defined(PETSC_HAVE_HDF5)
    639:   else if (ishdf5) NEPValuesView_HDF5(nep,viewer);
    640: #endif
    641:   else if (isascii) {
    642:     PetscViewerGetFormat(viewer,&format);
    643:     switch (format) {
    644:       case PETSC_VIEWER_DEFAULT:
    645:       case PETSC_VIEWER_ASCII_INFO:
    646:       case PETSC_VIEWER_ASCII_INFO_DETAIL:
    647:         NEPValuesView_ASCII(nep,viewer);
    648:         break;
    649:       case PETSC_VIEWER_ASCII_MATLAB:
    650:         NEPValuesView_MATLAB(nep,viewer);
    651:         break;
    652:       default:
    653:         PetscInfo(nep,"Unsupported viewer format %s\n",PetscViewerFormats[format]);
    654:     }
    655:   }
    656:   return 0;
    657: }

    659: /*@
    660:    NEPValuesViewFromOptions - Processes command line options to determine if/how
    661:    the computed eigenvalues are to be viewed.

    663:    Collective on nep

    665:    Input Parameter:
    666: .  nep - the nonlinear eigensolver context

    668:    Level: developer

    670: .seealso: NEPValuesView()
    671: @*/
    672: PetscErrorCode NEPValuesViewFromOptions(NEP nep)
    673: {
    674:   PetscViewer       viewer;
    675:   PetscBool         flg;
    676:   static PetscBool  incall = PETSC_FALSE;
    677:   PetscViewerFormat format;

    679:   if (incall) return 0;
    680:   incall = PETSC_TRUE;
    681:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)nep),((PetscObject)nep)->options,((PetscObject)nep)->prefix,"-nep_view_values",&viewer,&format,&flg);
    682:   if (flg) {
    683:     PetscViewerPushFormat(viewer,format);
    684:     NEPValuesView(nep,viewer);
    685:     PetscViewerPopFormat(viewer);
    686:     PetscViewerDestroy(&viewer);
    687:   }
    688:   incall = PETSC_FALSE;
    689:   return 0;
    690: }

    692: /*@C
    693:    NEPVectorsView - Outputs computed eigenvectors to a viewer.

    695:    Collective on nep

    697:    Input Parameters:
    698: +  nep    - the nonlinear eigensolver context
    699: -  viewer - the viewer

    701:    Options Database Key:
    702: .  -nep_view_vectors - output eigenvectors.

    704:    Notes:
    705:    If PETSc was configured with real scalars, complex conjugate eigenvectors
    706:    will be viewed as two separate real vectors, one containing the real part
    707:    and another one containing the imaginary part.

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

    713:    Level: intermediate

    715: .seealso: NEPSolve(), NEPValuesView(), NEPErrorView()
    716: @*/
    717: PetscErrorCode NEPVectorsView(NEP nep,PetscViewer viewer)
    718: {
    719:   PetscInt       i,k;
    720:   Vec            xr,xi=NULL;

    723:   if (!viewer) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)nep),&viewer);
    726:   NEPCheckSolved(nep,1);
    727:   if (nep->nconv) {
    728:     NEPComputeVectors(nep);
    729:     BVCreateVec(nep->V,&xr);
    730: #if !defined(PETSC_USE_COMPLEX)
    731:     BVCreateVec(nep->V,&xi);
    732: #endif
    733:     for (i=0;i<nep->nconv;i++) {
    734:       k = nep->perm[i];
    735:       BV_GetEigenvector(nep->V,k,nep->eigi[k],xr,xi);
    736:       SlepcViewEigenvector(viewer,xr,xi,"X",i,(PetscObject)nep);
    737:       if (nep->twosided) {
    738:         BV_GetEigenvector(nep->W,k,nep->eigi[k],xr,xi);
    739:         SlepcViewEigenvector(viewer,xr,xi,"Y",i,(PetscObject)nep);
    740:       }
    741:     }
    742:     VecDestroy(&xr);
    743: #if !defined(PETSC_USE_COMPLEX)
    744:     VecDestroy(&xi);
    745: #endif
    746:   }
    747:   return 0;
    748: }

    750: /*@
    751:    NEPVectorsViewFromOptions - Processes command line options to determine if/how
    752:    the computed eigenvectors are to be viewed.

    754:    Collective on nep

    756:    Input Parameter:
    757: .  nep - the nonlinear eigensolver context

    759:    Level: developer

    761: .seealso: NEPVectorsView()
    762: @*/
    763: PetscErrorCode NEPVectorsViewFromOptions(NEP nep)
    764: {
    765:   PetscViewer       viewer;
    766:   PetscBool         flg = PETSC_FALSE;
    767:   static PetscBool  incall = PETSC_FALSE;
    768:   PetscViewerFormat format;

    770:   if (incall) return 0;
    771:   incall = PETSC_TRUE;
    772:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)nep),((PetscObject)nep)->options,((PetscObject)nep)->prefix,"-nep_view_vectors",&viewer,&format,&flg);
    773:   if (flg) {
    774:     PetscViewerPushFormat(viewer,format);
    775:     NEPVectorsView(nep,viewer);
    776:     PetscViewerPopFormat(viewer);
    777:     PetscViewerDestroy(&viewer);
    778:   }
    779:   incall = PETSC_FALSE;
    780:   return 0;
    781: }