Actual source code: nepsolve.c

  1: /*
  2:       NEP routines related to the solution process.

  4:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  5:    SLEPc - Scalable Library for Eigenvalue Problem Computations
  6:    Copyright (c) 2002-2013, Universitat Politecnica de Valencia, Spain

  8:    This file is part of SLEPc.

 10:    SLEPc is free software: you can redistribute it and/or modify it under  the
 11:    terms of version 3 of the GNU Lesser General Public License as published by
 12:    the Free Software Foundation.

 14:    SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
 15:    WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
 16:    FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
 17:    more details.

 19:    You  should have received a copy of the GNU Lesser General  Public  License
 20:    along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
 21:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 22: */

 24: #include <slepc-private/nepimpl.h>       /*I "slepcnep.h" I*/
 25: #include <petscdraw.h>

 29: /*@
 30:    NEPSolve - Solves the nonlinear eigensystem.

 32:    Collective on NEP

 34:    Input Parameter:
 35: .  nep - eigensolver context obtained from NEPCreate()

 37:    Options Database Keys:
 38: +  -nep_view - print information about the solver used
 39: -  -nep_plot_eigs - plot computed eigenvalues

 41:    Level: beginner

 43: .seealso: NEPCreate(), NEPSetUp(), NEPDestroy(), NEPSetTolerances()
 44: @*/
 45: PetscErrorCode NEPSolve(NEP nep)
 46: {
 47:   PetscErrorCode    ierr;
 48:   PetscInt          i;
 49:   PetscReal         re,im;
 50:   PetscBool         flg;
 51:   PetscViewer       viewer;
 52:   PetscViewerFormat format;
 53:   PetscDraw         draw;
 54:   PetscDrawSP       drawsp;

 58:   PetscLogEventBegin(NEP_Solve,nep,0,0,0);

 60:   /* call setup */
 61:   NEPSetUp(nep);
 62:   nep->nconv = 0;
 63:   nep->its = 0;
 64:   for (i=0;i<nep->ncv;i++) {
 65:     nep->eig[i]   = 0.0;
 66:     nep->errest[i] = 0.0;
 67:   }
 68:   nep->ktol = 0.1;
 69:   NEPMonitor(nep,nep->its,nep->nconv,nep->eig,nep->errest,nep->ncv);

 71:   DSSetEigenvalueComparison(nep->ds,nep->comparison,nep->comparisonctx);

 73:   (*nep->ops->solve)(nep);

 75:   if (!nep->reason) SETERRQ(PetscObjectComm((PetscObject)nep),PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");

 77:   /* sort eigenvalues according to nep->which parameter */
 78:   NEPSortEigenvalues(nep,nep->nconv,nep->eig,nep->perm);

 80:   PetscLogEventEnd(NEP_Solve,nep,0,0,0);

 82:   /* various viewers */
 83:   PetscOptionsGetViewer(PetscObjectComm((PetscObject)nep),((PetscObject)nep)->prefix,"-nep_view",&viewer,&format,&flg);
 84:   if (flg && !PetscPreLoadingOn) {
 85:     PetscViewerPushFormat(viewer,format);
 86:     NEPView(nep,viewer);
 87:     PetscViewerPopFormat(viewer);
 88:     PetscViewerDestroy(&viewer);
 89:   }

 91:   flg = PETSC_FALSE;
 92:   PetscOptionsGetBool(((PetscObject)nep)->prefix,"-nep_plot_eigs",&flg,NULL);
 93:   if (flg) {
 94:     PetscViewerDrawOpen(PETSC_COMM_SELF,0,"Computed Eigenvalues",PETSC_DECIDE,PETSC_DECIDE,300,300,&viewer);
 95:     PetscViewerDrawGetDraw(viewer,0,&draw);
 96:     PetscDrawSPCreate(draw,1,&drawsp);
 97:     for (i=0;i<nep->nconv;i++) {
 98:       re = PetscRealPart(nep->eig[i]);
 99:       im = PetscImaginaryPart(nep->eig[i]);
100:       PetscDrawSPAddPoint(drawsp,&re,&im);
101:     }
102:     PetscDrawSPDraw(drawsp,PETSC_TRUE);
103:     PetscDrawSPDestroy(&drawsp);
104:     PetscViewerDestroy(&viewer);
105:   }

107:   /* Remove the initial subspace */
108:   nep->nini = 0;
109:   return(0);
110: }

114: PetscErrorCode NEP_KSPSolve(NEP nep,Vec b,Vec x)
115: {
117:   PetscInt       lits;

120:   KSPSolve(nep->ksp,b,x);
121:   KSPGetIterationNumber(nep->ksp,&lits);
122:   nep->linits += lits;
123:   PetscInfo2(nep,"iter=%D, linear solve iterations=%D\n",nep->its,lits);
124:   return(0);
125: }

129: /*@
130:    NEPProjectOperator - Computes the projection of the nonlinear operator.

132:    Collective on NEP

134:    Input Parameters:
135: +  nep - the nonlinear eigensolver context
136: .  j0  - initial index
137: .  j1  - final index
138: -  f   - workspace vector

140:    Notes:
141:    This is available for split operator only.

143:    The nonlinear operator T(lambda) is projected onto span(V), where V is
144:    an orthonormal basis built internally by the solver. The projected
145:    operator is equal to sum_i V'*A_i*V*f_i(lambda), so this function
146:    computes all matrices Ei = V'*A_i*V, and stores them in the extra
147:    matrices inside DS. Only rows/columns in the range [j0,j1-1] are computed,
148:    the previous ones are assumed to be available already.

150:    Level: developer

152: .seealso: NEPSetSplitOperator()
153: @*/
154: PetscErrorCode NEPProjectOperator(NEP nep,PetscInt j0,PetscInt j1,Vec f)
155: {
157:   PetscInt       i,j,k,ld;
158:   PetscScalar    *G,val;
159:   Vec            *V = nep->V;
160:   PetscBool      isherm,set,flg;

167:   if (!nep->split) SETERRQ(PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_WRONGSTATE,"This solver requires a split operator");
168:   DSGetLeadingDimension(nep->ds,&ld);
169:   for (k=0;k<nep->nt;k++) {
170:     DSGetArray(nep->ds,DSMatExtra[k],&G);
171:     MatIsHermitianKnown(nep->A[k],&set,&flg);
172:     isherm = set? flg: PETSC_FALSE;
173:     for (j=j0;j<j1;j++) {
174:       if (!isherm) {
175:         if (j>0) { MatMultHermitianTranspose(nep->A[k],V[j],f); }
176:         VecMDot(f,j,V,G+j*ld);
177:         for (i=0;i<j;i++)
178:           G[j+i*ld] = PetscConj(G[i+j*ld]);
179:       }
180:       MatMult(nep->A[k],V[j],f);
181:       VecDot(f,V[j],&val);
182:       G[j+j*ld] = val;
183:       VecMDot(f,j,V,G+j*ld);
184:       if (isherm) {
185:         for (i=0;i<j;i++)
186:           G[j+i*ld] = PetscConj(G[i+j*ld]);
187:       }
188:     }
189:     DSRestoreArray(nep->ds,DSMatExtra[k],&G);
190:   }
191:   return(0);
192: }

196: /*@
197:    NEPApplyFunction - Applies the nonlinear function T(lambda) to a given vector.

199:    Collective on NEP

201:    Input Parameters:
202: +  nep    - the nonlinear eigensolver context
203: .  lambda - scalar argument
204: .  x      - vector to be multiplied against
205: -  v      - workspace vector

207:    Output Parameters:
208: +  y   - result vector
209: .  A   - Function matrix
210: .  B   - optional preconditioning matrix
211: -  flg - flag indicating matrix structure (see MatStructure enum)

213:    Note:
214:    If the nonlinear operator is represented in split form, the result 
215:    y = T(lambda)*x is computed without building T(lambda) explicitly. In
216:    that case, parameters A, B and flg are not used. Otherwise, the matrix
217:    T(lambda) is built and the effect is the same as a call to
218:    NEPComputeFunction() followed by a MatMult().

220:    Level: developer

222: .seealso: NEPSetSplitOperator(), NEPComputeFunction()
223: @*/
224: PetscErrorCode NEPApplyFunction(NEP nep,PetscScalar lambda,Vec x,Vec v,Vec y,Mat *A,Mat *B,MatStructure *flg)
225: {
227:   PetscInt       i;
228:   PetscScalar    alpha;

236:   if (nep->split) {
237:     VecZeroEntries(y);
238:     for (i=0;i<nep->nt;i++) {
239:       FNEvaluateFunction(nep->f[i],lambda,&alpha);
240:       MatMult(nep->A[i],x,v);
241:       VecAXPY(y,alpha,v);
242:     }
243:   } else {
244:     NEPComputeFunction(nep,lambda,A,B,flg);
245:     MatMult(*A,x,y);
246:   }
247:   return(0);
248: }

252: /*@
253:    NEPApplyJacobian - Applies the nonlinear Jacobian T'(lambda) to a given vector.

255:    Collective on NEP

257:    Input Parameters:
258: +  nep    - the nonlinear eigensolver context
259: .  lambda - scalar argument
260: .  x      - vector to be multiplied against
261: -  v      - workspace vector

263:    Output Parameters:
264: +  y   - result vector
265: .  A   - Jacobian matrix
266: -  flg - flag indicating matrix structure (see MatStructure enum)

268:    Note:
269:    If the nonlinear operator is represented in split form, the result 
270:    y = T'(lambda)*x is computed without building T'(lambda) explicitly. In
271:    that case, parameters A and flg are not used. Otherwise, the matrix
272:    T'(lambda) is built and the effect is the same as a call to
273:    NEPComputeJacobian() followed by a MatMult().

275:    Level: developer

277: .seealso: NEPSetSplitOperator(), NEPComputeJacobian()
278: @*/
279: PetscErrorCode NEPApplyJacobian(NEP nep,PetscScalar lambda,Vec x,Vec v,Vec y,Mat *A,MatStructure *flg)
280: {
282:   PetscInt       i;
283:   PetscScalar    alpha;

291:   if (nep->split) {
292:     VecZeroEntries(y);
293:     for (i=0;i<nep->nt;i++) {
294:       FNEvaluateDerivative(nep->f[i],lambda,&alpha);
295:       MatMult(nep->A[i],x,v);
296:       VecAXPY(y,alpha,v);
297:     }
298:   } else {
299:     NEPComputeJacobian(nep,lambda,A,flg);
300:     MatMult(*A,x,y);
301:   }
302:   return(0);
303: }

307: /*@
308:    NEPGetIterationNumber - Gets the current iteration number. If the
309:    call to NEPSolve() is complete, then it returns the number of iterations
310:    carried out by the solution method.

312:    Not Collective

314:    Input Parameter:
315: .  nep - the nonlinear eigensolver context

317:    Output Parameter:
318: .  its - number of iterations

320:    Level: intermediate

322:    Note:
323:    During the i-th iteration this call returns i-1. If NEPSolve() is
324:    complete, then parameter "its" contains either the iteration number at
325:    which convergence was successfully reached, or failure was detected.
326:    Call NEPGetConvergedReason() to determine if the solver converged or
327:    failed and why.

329: .seealso: NEPGetConvergedReason(), NEPSetTolerances()
330: @*/
331: PetscErrorCode NEPGetIterationNumber(NEP nep,PetscInt *its)
332: {
336:   *its = nep->its;
337:   return(0);
338: }

342: /*@
343:    NEPGetConverged - Gets the number of converged eigenpairs.

345:    Not Collective

347:    Input Parameter:
348: .  nep - the nonlinear eigensolver context

350:    Output Parameter:
351: .  nconv - number of converged eigenpairs

353:    Note:
354:    This function should be called after NEPSolve() has finished.

356:    Level: beginner

358: .seealso: NEPSetDimensions(), NEPSolve()
359: @*/
360: PetscErrorCode NEPGetConverged(NEP nep,PetscInt *nconv)
361: {
365:   *nconv = nep->nconv;
366:   return(0);
367: }

371: /*@C
372:    NEPGetConvergedReason - Gets the reason why the NEPSolve() iteration was
373:    stopped.

375:    Not Collective

377:    Input Parameter:
378: .  nep - the nonlinear eigensolver context

380:    Output Parameter:
381: .  reason - negative value indicates diverged, positive value converged

383:    Possible values for reason:
384: +  NEP_CONVERGED_FNORM_ABS - function norm satisfied absolute tolerance
385: .  NEP_CONVERGED_FNORM_RELATIVE - function norm satisfied relative tolerance
386: .  NEP_CONVERGED_SNORM_RELATIVE - step norm satisfied relative tolerance
387: .  NEP_DIVERGED_LINEAR_SOLVE - inner linear solve failed
388: .  NEP_DIVERGED_FUNCTION_COUNT - reached maximum allowed function evaluations
389: .  NEP_DIVERGED_MAX_IT - required more than its to reach convergence
390: .  NEP_DIVERGED_BREAKDOWN - generic breakdown in method
391: -  NEP_DIVERGED_FNORM_NAN - Inf or NaN detected in function evaluation

393:    Note:
394:    Can only be called after the call to NEPSolve() is complete.

396:    Level: intermediate

398: .seealso: NEPSetTolerances(), NEPSolve(), NEPConvergedReason
399: @*/
400: PetscErrorCode NEPGetConvergedReason(NEP nep,NEPConvergedReason *reason)
401: {
405:   *reason = nep->reason;
406:   return(0);
407: }

411: /*@
412:    NEPGetEigenpair - Gets the i-th solution of the eigenproblem as computed by
413:    NEPSolve(). The solution consists in both the eigenvalue and the eigenvector.

415:    Logically Collective on NEP

417:    Input Parameters:
418: +  nep - nonlinear eigensolver context
419: -  i   - index of the solution

421:    Output Parameters:
422: +  eig - eigenvalue
423: -  V   - eigenvector

425:    Notes:
426:    If PETSc is configured with real scalars, then complex eigenpairs cannot
427:    be obtained. Users should use a complex-scalar configuration. This
428:    behaviour is different to other SLEPc solvers such as EPS.

430:    The index i should be a value between 0 and nconv-1 (see NEPGetConverged()).
431:    Eigenpairs are indexed according to the ordering criterion established
432:    with NEPSetWhichEigenpairs().

434:    Level: beginner

436: .seealso: NEPSolve(), NEPGetConverged(), NEPSetWhichEigenpairs()
437: @*/
438: PetscErrorCode NEPGetEigenpair(NEP nep,PetscInt i,PetscScalar *eig,Vec V)
439: {
440:   PetscInt       k;

447:   if (!nep->eig || !nep->V) SETERRQ(PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_WRONGSTATE,"NEPSolve must be called first");
448:   if (i<0 || i>=nep->nconv) SETERRQ(PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_OUTOFRANGE,"Argument 2 out of range");

450:   if (!nep->perm) k = i;
451:   else k = nep->perm[i];

453:   if (eig) *eig = nep->eig[k];
454:   if (V) { VecCopy(nep->V[k],V); }
455:   return(0);
456: }

460: /*@
461:    NEPGetErrorEstimate - Returns the error estimate associated to the i-th
462:    computed eigenpair.

464:    Not Collective

466:    Input Parameter:
467: +  nep - nonlinear eigensolver context
468: -  i   - index of eigenpair

470:    Output Parameter:
471: .  errest - the error estimate

473:    Notes:
474:    This is the error estimate used internally by the eigensolver. The actual
475:    error bound can be computed with NEPComputeRelativeError().

477:    Level: advanced

479: .seealso: NEPComputeRelativeError()
480: @*/
481: PetscErrorCode NEPGetErrorEstimate(NEP nep,PetscInt i,PetscReal *errest)
482: {
486:   if (!nep->eig) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"NEPSolve must be called first");
487:   if (i<0 || i>=nep->nconv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Argument 2 out of range");
488:   if (nep->perm) i = nep->perm[i];
489:   if (errest) *errest = nep->errest[i];
490:   return(0);
491: }

495: /*
496:    NEPComputeResidualNorm_Private - Computes the norm of the residual vector
497:    associated with an eigenpair.
498: */
499: PetscErrorCode NEPComputeResidualNorm_Private(NEP nep,PetscScalar lambda,Vec x,PetscReal *norm)
500: {
502:   Vec            u;
503:   Mat            T=nep->function;
504:   MatStructure   mats;

507:   VecDuplicate(nep->V[0],&u);
508:   NEPComputeFunction(nep,lambda,&T,&T,&mats);
509:   MatMult(T,x,u);
510:   VecNorm(u,NORM_2,norm);
511:   VecDestroy(&u);
512:   return(0);
513: }

517: /*@
518:    NEPComputeResidualNorm - Computes the norm of the residual vector associated with
519:    the i-th computed eigenpair.

521:    Collective on NEP

523:    Input Parameter:
524: +  nep - the nonlinear eigensolver context
525: -  i   - the solution index

527:    Output Parameter:
528: .  norm - the residual norm, computed as ||T(lambda)x||_2 where lambda is the
529:    eigenvalue and x is the eigenvector.

531:    Notes:
532:    The index i should be a value between 0 and nconv-1 (see NEPGetConverged()).
533:    Eigenpairs are indexed according to the ordering criterion established
534:    with NEPSetWhichEigenpairs().

536:    Level: beginner

538: .seealso: NEPSolve(), NEPGetConverged(), NEPSetWhichEigenpairs()
539: @*/
540: PetscErrorCode NEPComputeResidualNorm(NEP nep,PetscInt i,PetscReal *norm)
541: {
543:   Vec            x;
544:   PetscScalar    lambda;

550:   VecDuplicate(nep->V[0],&x);
551:   NEPGetEigenpair(nep,i,&lambda,x);
552:   NEPComputeResidualNorm_Private(nep,lambda,x,norm);
553:   VecDestroy(&x);
554:   return(0);
555: }

559: /*
560:    NEPComputeRelativeError_Private - Computes the relative error bound
561:    associated with an eigenpair.
562: */
563: PetscErrorCode NEPComputeRelativeError_Private(NEP nep,PetscScalar lambda,Vec x,PetscReal *error)
564: {
566:   PetscReal      norm,er;

569:   NEPComputeResidualNorm_Private(nep,lambda,x,&norm);
570:   VecNorm(x,NORM_2,&er);
571:   if (PetscAbsScalar(lambda) > norm) {
572:     *error = norm/(PetscAbsScalar(lambda)*er);
573:   } else {
574:     *error = norm/er;
575:   }
576:   return(0);
577: }

581: /*@
582:    NEPComputeRelativeError - Computes the relative error bound associated
583:    with the i-th computed eigenpair.

585:    Collective on NEP

587:    Input Parameter:
588: +  nep - the nonlinear eigensolver context
589: -  i   - the solution index

591:    Output Parameter:
592: .  error - the relative error bound, computed as ||T(lambda)x||_2/||lambda*x||_2
593:    where lambda is the eigenvalue and x is the eigenvector.
594:    If lambda=0 the relative error is computed as ||T(lambda)x||_2/||x||_2.

596:    Level: beginner

598: .seealso: NEPSolve(), NEPComputeResidualNorm(), NEPGetErrorEstimate()
599: @*/
600: PetscErrorCode NEPComputeRelativeError(NEP nep,PetscInt i,PetscReal *error)
601: {
603:   Vec            x;
604:   PetscScalar    lambda;

610:   VecDuplicate(nep->V[0],&x);
611:   NEPGetEigenpair(nep,i,&lambda,x);
612:   NEPComputeRelativeError_Private(nep,lambda,x,error);
613:   VecDestroy(&x);
614:   return(0);
615: }

619: /*@
620:    NEPSortEigenvalues - Sorts a list of eigenvalues according to the criterion
621:    specified via NEPSetWhichEigenpairs().

623:    Not Collective

625:    Input Parameters:
626: +  nep - the nonlinear eigensolver context
627: .  n   - number of eigenvalues in the list
628: -  eig - pointer to the array containing the eigenvalues

630:    Output Parameter:
631: .  perm - resulting permutation

633:    Note:
634:    The result is a list of indices in the original eigenvalue array
635:    corresponding to the first nev eigenvalues sorted in the specified
636:    criterion.

638:    Level: developer

640: .seealso: NEPSetWhichEigenpairs()
641: @*/
642: PetscErrorCode NEPSortEigenvalues(NEP nep,PetscInt n,PetscScalar *eig,PetscInt *perm)
643: {
645:   PetscInt       i,j,result,tmp;

651:   for (i=0;i<n;i++) perm[i] = i;
652:   /* insertion sort */
653:   for (i=n-1;i>=0;i--) {
654:     j = i + 1;
655:     while (j<n) {
656:       NEPCompareEigenvalues(nep,eig[perm[i]],eig[perm[j]],&result);
657:       if (result < 0) break;
658:       tmp = perm[j-1]; perm[j-1] = perm[j]; perm[j] = tmp;
659:       j++;
660:     }
661:   }
662:   return(0);
663: }

667: /*@
668:    NEPCompareEigenvalues - Compares two eigenvalues according to a certain criterion.

670:    Not Collective

672:    Input Parameters:
673: +  nep - the nonlinear eigensolver context
674: .  a   - the 1st eigenvalue
675: -  b   - the 2nd eigenvalue

677:    Output Parameter:
678: .  res - result of comparison

680:    Notes:
681:    Returns an integer less than, equal to, or greater than zero if the first
682:    eigenvalue is considered to be respectively less than, equal to, or greater
683:    than the second one.

685:    The criterion of comparison is related to the 'which' parameter set with
686:    NEPSetWhichEigenpairs().

688:    Level: developer

690: .seealso: NEPSortEigenvalues(), NEPSetWhichEigenpairs()
691: @*/
692: PetscErrorCode NEPCompareEigenvalues(NEP nep,PetscScalar a,PetscScalar b,PetscInt *result)
693: {

699:   if (!nep->comparison) SETERRQ(PETSC_COMM_SELF,1,"Undefined eigenvalue comparison function");
700:   (*nep->comparison)(a,0.0,b,0.0,result,nep->comparisonctx);
701:   return(0);
702: }

706: /*@
707:    NEPGetOperationCounters - Gets the total number of function evaluations, dot
708:    products, and linear solve iterations used by the NEP object during the last
709:    NEPSolve() call.

711:    Not Collective

713:    Input Parameter:
714: .  nep - nonlinear eigensolver context

716:    Output Parameter:
717: +  nfuncs - number of function evaluations
718: .  dots   - number of dot product operations
719: -  lits   - number of linear iterations

721:    Notes:
722:    These counters are reset to zero at each successive call to NEPSolve().

724:    Level: intermediate

726: @*/
727: PetscErrorCode NEPGetOperationCounters(NEP nep,PetscInt* nfuncs,PetscInt* dots,PetscInt* lits)
728: {

733:   if (nfuncs) *nfuncs = nep->nfuncs;
734:   if (dots) {
735:     if (!nep->ip) { NEPGetIP(nep,&nep->ip); }
736:     IPGetOperationCounters(nep->ip,dots);
737:   }
738:   if (lits) *lits = nep->linits;
739:   return(0);
740: }

744: /*@
745:    NEPComputeFunction - Computes the function matrix T(lambda) that has been
746:    set with NEPSetFunction().

748:    Collective on NEP and Mat

750:    Input Parameters:
751: +  nep    - the NEP context
752: -  lambda - the scalar argument

754:    Output Parameters:
755: +  A   - Function matrix
756: .  B   - optional preconditioning matrix
757: -  flg - flag indicating matrix structure (see MatStructure enum)

759:    Notes:
760:    NEPComputeFunction() is typically used within nonlinear eigensolvers
761:    implementations, so most users would not generally call this routine
762:    themselves.

764:    Level: developer

766: .seealso: NEPSetFunction(), NEPGetFunction()
767: @*/
768: PetscErrorCode NEPComputeFunction(NEP nep,PetscScalar lambda,Mat *A,Mat *B,MatStructure *flg)
769: {
771:   PetscInt       i;
772:   PetscScalar    alpha;


778:   if (nep->split) {

780:     MatZeroEntries(*A);
781:     for (i=0;i<nep->nt;i++) {
782:       FNEvaluateFunction(nep->f[i],lambda,&alpha);
783:       MatAXPY(*A,alpha,nep->A[i],nep->mstr);
784:     }
785:     if (*A != *B) SETERRQ(PetscObjectComm((PetscObject)nep),1,"Not implemented");

787:   } else {

789:     if (!nep->computefunction) SETERRQ(PetscObjectComm((PetscObject)nep),PETSC_ERR_USER,"Must call NEPSetFunction() first");

791:     *flg = DIFFERENT_NONZERO_PATTERN;
792:     PetscLogEventBegin(NEP_FunctionEval,nep,*A,*B,0);

794:     PetscStackPush("NEP user Function function");
795:     (*nep->computefunction)(nep,lambda,A,B,flg,nep->functionctx);
796:     PetscStackPop;

798:     PetscLogEventEnd(NEP_FunctionEval,nep,*A,*B,0);
799:     nep->nfuncs++;

801:   }
802:   return(0);
803: }

807: /*@
808:    NEPComputeJacobian - Computes the Jacobian matrix T'(lambda) that has been
809:    set with NEPSetJacobian().

811:    Collective on NEP and Mat

813:    Input Parameters:
814: +  nep    - the NEP context
815: -  lambda - the scalar argument

817:    Output Parameters:
818: +  A   - Jacobian matrix
819: -  flg - flag indicating matrix structure (see MatStructure enum)

821:    Notes:
822:    Most users should not need to explicitly call this routine, as it
823:    is used internally within the nonlinear eigensolvers.

825:    Level: developer

827: .seealso: NEPSetJacobian(), NEPGetJacobian()
828: @*/
829: PetscErrorCode NEPComputeJacobian(NEP nep,PetscScalar lambda,Mat *A,MatStructure *flg)
830: {
832:   PetscInt       i;
833:   PetscScalar    alpha;


839:   if (nep->split) {

841:     MatZeroEntries(*A);
842:     for (i=0;i<nep->nt;i++) {
843:       FNEvaluateDerivative(nep->f[i],lambda,&alpha);
844:       MatAXPY(*A,alpha,nep->A[i],nep->mstr);
845:     }

847:   } else {

849:     if (!nep->computejacobian) SETERRQ(PetscObjectComm((PetscObject)nep),PETSC_ERR_USER,"Must call NEPSetJacobian() first");

851:     *flg = DIFFERENT_NONZERO_PATTERN;
852:     PetscLogEventBegin(NEP_JacobianEval,nep,*A,0,0);

854:     PetscStackPush("NEP user Jacobian function");
855:     (*nep->computejacobian)(nep,lambda,A,flg,nep->jacobianctx);
856:     PetscStackPop;

858:     PetscLogEventEnd(NEP_JacobianEval,nep,*A,0,0);

860:   }
861:   return(0);
862: }