Actual source code: nepsolve.c

slepc-3.7.0 2016-05-16
Report Typos and Errors
  1: /*
  2:       NEP routines related to the solution process.

  4:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  5:    SLEPc - Scalable Library for Eigenvalue Problem Computations
  6:    Copyright (c) 2002-2016, 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: PetscErrorCode NEPComputeVectors(NEP nep)
 30: {

 34:   NEPCheckSolved(nep,1);
 35:   switch (nep->state) {
 36:   case NEP_STATE_SOLVED:
 37:     if (nep->ops->computevectors) {
 38:       (*nep->ops->computevectors)(nep);
 39:     }
 40:     break;
 41:   default:
 42:     break;
 43:   }
 44:   nep->state = NEP_STATE_EIGENVECTORS;
 45:   return(0);
 46: }

 50: /*@
 51:    NEPSolve - Solves the nonlinear eigensystem.

 53:    Collective on NEP

 55:    Input Parameter:
 56: .  nep - eigensolver context obtained from NEPCreate()

 58:    Options Database Keys:
 59: +  -nep_view - print information about the solver used
 60: .  -nep_view_vectors binary - save the computed eigenvectors to the default binary viewer
 61: .  -nep_view_values - print computed eigenvalues
 62: .  -nep_converged_reason - print reason for convergence, and number of iterations
 63: .  -nep_error_absolute - print absolute errors of each eigenpair
 64: -  -nep_error_relative - print relative errors of each eigenpair

 66:    Level: beginner

 68: .seealso: NEPCreate(), NEPSetUp(), NEPDestroy(), NEPSetTolerances()
 69: @*/
 70: PetscErrorCode NEPSolve(NEP nep)
 71: {
 73:   PetscInt       i;

 77:   if (nep->state>=NEP_STATE_SOLVED) return(0);
 78:   PetscLogEventBegin(NEP_Solve,nep,0,0,0);

 80:   /* call setup */
 81:   NEPSetUp(nep);
 82:   nep->nconv = 0;
 83:   nep->its = 0;
 84:   for (i=0;i<nep->ncv;i++) {
 85:     nep->eigr[i]   = 0.0;
 86:     nep->eigi[i]   = 0.0;
 87:     nep->errest[i] = 0.0;
 88:     nep->perm[i]   = i;
 89:   }
 90:   NEPViewFromOptions(nep,NULL,"-nep_view_pre");

 92:   (*nep->ops->solve)(nep);
 93:   nep->state = NEP_STATE_SOLVED;

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

 97:   if (nep->refine==NEP_REFINE_SIMPLE && nep->rits>0 && nep->nconv>0) {
 98:     NEPComputeVectors(nep);
 99:     NEPNewtonRefinementSimple(nep,&nep->rits,nep->rtol,nep->nconv);
100:     nep->state = NEP_STATE_EIGENVECTORS;
101:   }

103:   /* sort eigenvalues according to nep->which parameter */
104:   SlepcSortEigenvalues(nep->sc,nep->nconv,nep->eigr,nep->eigi,nep->perm);
105:   PetscLogEventEnd(NEP_Solve,nep,0,0,0);

107:   /* various viewers */
108:   NEPViewFromOptions(nep,NULL,"-nep_view");
109:   NEPReasonViewFromOptions(nep);
110:   NEPErrorViewFromOptions(nep);
111:   NEPValuesViewFromOptions(nep);
112:   NEPVectorsViewFromOptions(nep);

114:   /* Remove the initial subspace */
115:   nep->nini = 0;
116:   return(0);
117: }

121: /*@
122:    NEPProjectOperator - Computes the projection of the nonlinear operator.

124:    Collective on NEP

126:    Input Parameters:
127: +  nep - the nonlinear eigensolver context
128: .  j0  - initial index
129: -  j1  - final index

131:    Notes:
132:    This is available for split operator only.

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

141:    Level: developer

143: .seealso: NEPSetSplitOperator()
144: @*/
145: PetscErrorCode NEPProjectOperator(NEP nep,PetscInt j0,PetscInt j1)
146: {
148:   PetscInt       k;
149:   Mat            G;

155:   NEPCheckProblem(nep,1);
156:   NEPCheckSplit(nep,1);
157:   BVSetActiveColumns(nep->V,j0,j1);
158:   for (k=0;k<nep->nt;k++) {
159:     DSGetMat(nep->ds,DSMatExtra[k],&G);
160:     BVMatProject(nep->V,nep->A[k],nep->V,G);
161:     DSRestoreMat(nep->ds,DSMatExtra[k],&G);
162:   }
163:   return(0);
164: }

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

171:    Collective on NEP

173:    Input Parameters:
174: +  nep    - the nonlinear eigensolver context
175: .  lambda - scalar argument
176: .  x      - vector to be multiplied against
177: -  v      - workspace vector (used only in the case of split form)

179:    Output Parameters:
180: +  y   - result vector
181: .  A   - Function matrix
182: -  B   - optional preconditioning matrix

184:    Note:
185:    If the nonlinear operator is represented in split form, the result 
186:    y = T(lambda)*x is computed without building T(lambda) explicitly. In
187:    that case, parameters A and B are not used. Otherwise, the matrix
188:    T(lambda) is built and the effect is the same as a call to
189:    NEPComputeFunction() followed by a MatMult().

191:    Level: developer

193: .seealso: NEPSetSplitOperator(), NEPComputeFunction()
194: @*/
195: PetscErrorCode NEPApplyFunction(NEP nep,PetscScalar lambda,Vec x,Vec v,Vec y,Mat A,Mat B)
196: {
198:   PetscInt       i;
199:   PetscScalar    alpha;


210:   if (nep->fui==NEP_USER_INTERFACE_SPLIT) {
211:     VecSet(y,0.0);
212:     for (i=0;i<nep->nt;i++) {
213:       FNEvaluateFunction(nep->f[i],lambda,&alpha);
214:       MatMult(nep->A[i],x,v);
215:       VecAXPY(y,alpha,v);
216:     }
217:   } else {
218:     NEPComputeFunction(nep,lambda,A,B);
219:     MatMult(A,x,y);
220:   }
221:   return(0);
222: }

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

229:    Collective on NEP

231:    Input Parameters:
232: +  nep    - the nonlinear eigensolver context
233: .  lambda - scalar argument
234: .  x      - vector to be multiplied against
235: -  v      - workspace vector (used only in the case of split form)

237:    Output Parameters:
238: +  y   - result vector
239: -  A   - Jacobian matrix

241:    Note:
242:    If the nonlinear operator is represented in split form, the result 
243:    y = T'(lambda)*x is computed without building T'(lambda) explicitly. In
244:    that case, parameter A is not used. Otherwise, the matrix
245:    T'(lambda) is built and the effect is the same as a call to
246:    NEPComputeJacobian() followed by a MatMult().

248:    Level: developer

250: .seealso: NEPSetSplitOperator(), NEPComputeJacobian()
251: @*/
252: PetscErrorCode NEPApplyJacobian(NEP nep,PetscScalar lambda,Vec x,Vec v,Vec y,Mat A)
253: {
255:   PetscInt       i;
256:   PetscScalar    alpha;


266:   if (nep->fui==NEP_USER_INTERFACE_SPLIT) {
267:     VecSet(y,0.0);
268:     for (i=0;i<nep->nt;i++) {
269:       FNEvaluateDerivative(nep->f[i],lambda,&alpha);
270:       MatMult(nep->A[i],x,v);
271:       VecAXPY(y,alpha,v);
272:     }
273:   } else {
274:     NEPComputeJacobian(nep,lambda,A);
275:     MatMult(A,x,y);
276:   }
277:   return(0);
278: }

282: /*@
283:    NEPGetIterationNumber - Gets the current iteration number. If the
284:    call to NEPSolve() is complete, then it returns the number of iterations
285:    carried out by the solution method.

287:    Not Collective

289:    Input Parameter:
290: .  nep - the nonlinear eigensolver context

292:    Output Parameter:
293: .  its - number of iterations

295:    Level: intermediate

297:    Note:
298:    During the i-th iteration this call returns i-1. If NEPSolve() is
299:    complete, then parameter "its" contains either the iteration number at
300:    which convergence was successfully reached, or failure was detected.
301:    Call NEPGetConvergedReason() to determine if the solver converged or
302:    failed and why.

304: .seealso: NEPGetConvergedReason(), NEPSetTolerances()
305: @*/
306: PetscErrorCode NEPGetIterationNumber(NEP nep,PetscInt *its)
307: {
311:   *its = nep->its;
312:   return(0);
313: }

317: /*@
318:    NEPGetConverged - Gets the number of converged eigenpairs.

320:    Not Collective

322:    Input Parameter:
323: .  nep - the nonlinear eigensolver context

325:    Output Parameter:
326: .  nconv - number of converged eigenpairs

328:    Note:
329:    This function should be called after NEPSolve() has finished.

331:    Level: beginner

333: .seealso: NEPSetDimensions(), NEPSolve()
334: @*/
335: PetscErrorCode NEPGetConverged(NEP nep,PetscInt *nconv)
336: {
340:   NEPCheckSolved(nep,1);
341:   *nconv = nep->nconv;
342:   return(0);
343: }

347: /*@
348:    NEPGetConvergedReason - Gets the reason why the NEPSolve() iteration was
349:    stopped.

351:    Not Collective

353:    Input Parameter:
354: .  nep - the nonlinear eigensolver context

356:    Output Parameter:
357: .  reason - negative value indicates diverged, positive value converged

359:    Possible values for reason:
360: +  NEP_CONVERGED_TOL - converged up to tolerance
361: .  NEP_CONVERGED_USER - converged due to a user-defined condition
362: .  NEP_DIVERGED_ITS - required more than max_it iterations to reach convergence
363: .  NEP_DIVERGED_BREAKDOWN - generic breakdown in method
364: -  NEP_DIVERGED_LINEAR_SOLVE - inner linear solve failed

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

369:    Level: intermediate

371: .seealso: NEPSetTolerances(), NEPSolve(), NEPConvergedReason
372: @*/
373: PetscErrorCode NEPGetConvergedReason(NEP nep,NEPConvergedReason *reason)
374: {
378:   NEPCheckSolved(nep,1);
379:   *reason = nep->reason;
380:   return(0);
381: }

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

389:    Logically Collective on NEP

391:    Input Parameters:
392: +  nep - nonlinear eigensolver context
393: -  i   - index of the solution

395:    Output Parameters:
396: +  eigr - real part of eigenvalue
397: .  eigi - imaginary part of eigenvalue
398: .  Vr   - real part of eigenvector
399: -  Vi   - imaginary part of eigenvector

401:    Notes:
402:    It is allowed to pass NULL for Vr and Vi, if the eigenvector is not
403:    required. Otherwise, the caller must provide valid Vec objects, i.e.,
404:    they must be created by the calling program with e.g. MatCreateVecs().

406:    If the eigenvalue is real, then eigi and Vi are set to zero. If PETSc is
407:    configured with complex scalars the eigenvalue is stored
408:    directly in eigr (eigi is set to zero) and the eigenvector in Vr (Vi is
409:    set to zero). In both cases, the user can pass NULL in eigi and Vi.

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

415:    Level: beginner

417: .seealso: NEPSolve(), NEPGetConverged(), NEPSetWhichEigenpairs()
418: @*/
419: PetscErrorCode NEPGetEigenpair(NEP nep,PetscInt i,PetscScalar *eigr,PetscScalar *eigi,Vec Vr,Vec Vi)
420: {
421:   PetscInt       k;

429:   NEPCheckSolved(nep,1);
430:   if (i<0 || i>=nep->nconv) SETERRQ(PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_OUTOFRANGE,"Argument 2 out of range");

432:   NEPComputeVectors(nep);
433:   k = nep->perm[i];

435:   /* eigenvalue */
436: #if defined(PETSC_USE_COMPLEX)
437:   if (eigr) *eigr = nep->eigr[k];
438:   if (eigi) *eigi = 0;
439: #else
440:   if (eigr) *eigr = nep->eigr[k];
441:   if (eigi) *eigi = nep->eigi[k];
442: #endif

444:   /* eigenvector */
445: #if defined(PETSC_USE_COMPLEX)
446:   if (Vr) { BVCopyVec(nep->V,k,Vr); }
447:   if (Vi) { VecSet(Vi,0.0); }
448: #else
449:   if (nep->eigi[k]>0) { /* first value of conjugate pair */
450:     if (Vr) { BVCopyVec(nep->V,k,Vr); }
451:     if (Vi) { BVCopyVec(nep->V,k+1,Vi); }
452:   } else if (nep->eigi[k]<0) { /* second value of conjugate pair */
453:     if (Vr) { BVCopyVec(nep->V,k-1,Vr); }
454:     if (Vi) {
455:       BVCopyVec(nep->V,k,Vi);
456:       VecScale(Vi,-1.0);
457:     }
458:   } else { /* real eigenvalue */
459:     if (Vr) { BVCopyVec(nep->V,k,Vr); }
460:     if (Vi) { VecSet(Vi,0.0); }
461:   }
462: #endif
463:   return(0);
464: }

468: /*@
469:    NEPGetErrorEstimate - Returns the error estimate associated to the i-th
470:    computed eigenpair.

472:    Not Collective

474:    Input Parameter:
475: +  nep - nonlinear eigensolver context
476: -  i   - index of eigenpair

478:    Output Parameter:
479: .  errest - the error estimate

481:    Notes:
482:    This is the error estimate used internally by the eigensolver. The actual
483:    error bound can be computed with NEPComputeRelativeError().

485:    Level: advanced

487: .seealso: NEPComputeRelativeError()
488: @*/
489: PetscErrorCode NEPGetErrorEstimate(NEP nep,PetscInt i,PetscReal *errest)
490: {
494:   NEPCheckSolved(nep,1);
495:   if (i<0 || i>=nep->nconv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Argument 2 out of range");
496:   if (errest) *errest = nep->errest[nep->perm[i]];
497:   return(0);
498: }

502: /*
503:    NEPComputeResidualNorm_Private - Computes the norm of the residual vector
504:    associated with an eigenpair.

506:    Input Parameters:
507:      lambda - eigenvalue
508:      x      - eigenvector
509:      w      - array of work vectors (two vectors in split form, one vector otherwise)
510: */
511: PetscErrorCode NEPComputeResidualNorm_Private(NEP nep,PetscScalar lambda,Vec x,Vec *w,PetscReal *norm)
512: {
514:   Vec            y,z=NULL;

517:   y = w[0];
518:   if (nep->fui==NEP_USER_INTERFACE_SPLIT) z = w[1];
519:   NEPApplyFunction(nep,lambda,x,z,y,nep->function,nep->function_pre);
520:   VecNorm(y,NORM_2,norm);
521:   return(0);
522: }

526: /*@
527:    NEPComputeError - Computes the error (based on the residual norm) associated
528:    with the i-th computed eigenpair.

530:    Collective on NEP

532:    Input Parameter:
533: +  nep  - the nonlinear eigensolver context
534: .  i    - the solution index
535: -  type - the type of error to compute

537:    Output Parameter:
538: .  error - the error

540:    Notes:
541:    The error can be computed in various ways, all of them based on the residual
542:    norm computed as ||T(lambda)x||_2 where lambda is the eigenvalue and x is the
543:    eigenvector.

545:    Level: beginner

547: .seealso: NEPErrorType, NEPSolve(), NEPGetErrorEstimate()
548: @*/
549: PetscErrorCode NEPComputeError(NEP nep,PetscInt i,NEPErrorType type,PetscReal *error)
550: {
552:   Vec            xr,xi=NULL;
553:   PetscInt       j,nwork,issplit=0;
554:   PetscScalar    kr,ki,s;
555:   PetscReal      er,z=0.0;
556:   PetscBool      flg;

563:   NEPCheckSolved(nep,1);

565:   /* allocate work vectors */
566: #if defined(PETSC_USE_COMPLEX)
567:   nwork = 2;
568: #else
569:   nwork = 3;
570: #endif
571:   if (nep->fui==NEP_USER_INTERFACE_SPLIT) {
572:     issplit = 1;
573:     nwork++;  /* need an extra work vector for NEPComputeResidualNorm_Private */
574:   }
575:   NEPSetWorkVecs(nep,nwork);
576:   xr = nep->work[issplit+1];
577: #if !defined(PETSC_USE_COMPLEX)
578:   xi = nep->work[issplit+2];
579: #endif

581:   /* compute residual norms */
582:   NEPGetEigenpair(nep,i,&kr,&ki,xr,xi);
583: #if !defined(PETSC_USE_COMPLEX)
584:   if (ki) SETERRQ(PETSC_COMM_SELF,1,"Not implemented for complex eigenvalues with real scalars");
585: #endif
586:   NEPComputeResidualNorm_Private(nep,kr,xr,nep->work,error);
587:   VecNorm(xr,NORM_2,&er);

589:   /* compute error */
590:   switch (type) {
591:     case NEP_ERROR_ABSOLUTE:
592:       break;
593:     case NEP_ERROR_RELATIVE:
594:       *error /= PetscAbsScalar(kr)*er;
595:       break;
596:     case NEP_ERROR_BACKWARD:
597:       if (nep->fui!=NEP_USER_INTERFACE_SPLIT) {
598:         *error = 0.0;
599:         PetscInfo(nep,"Backward error only available in split form\n");
600:         break;
601:       }
602:       /* initialization of matrix norms */
603:       if (!nep->nrma[0]) {
604:         for (j=0;j<nep->nt;j++) {
605:           MatHasOperation(nep->A[j],MATOP_NORM,&flg);
606:           if (!flg) SETERRQ(PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_WRONG,"The computation of backward errors requires a matrix norm operation");
607:           MatNorm(nep->A[j],NORM_INFINITY,&nep->nrma[j]);
608:         }
609:       }
610:       for (j=0;j<nep->nt;j++) {
611:         FNEvaluateFunction(nep->f[j],kr,&s);
612:         z = z + nep->nrma[j]*PetscAbsScalar(s);
613:       }
614:       *error /= z;
615:       break;
616:     default:
617:       SETERRQ(PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_OUTOFRANGE,"Invalid error type");
618:   }
619:   return(0);
620: }

624: /*@
625:    NEPComputeFunction - Computes the function matrix T(lambda) that has been
626:    set with NEPSetFunction().

628:    Collective on NEP and Mat

630:    Input Parameters:
631: +  nep    - the NEP context
632: -  lambda - the scalar argument

634:    Output Parameters:
635: +  A   - Function matrix
636: -  B   - optional preconditioning matrix

638:    Notes:
639:    NEPComputeFunction() is typically used within nonlinear eigensolvers
640:    implementations, so most users would not generally call this routine
641:    themselves.

643:    Level: developer

645: .seealso: NEPSetFunction(), NEPGetFunction()
646: @*/
647: PetscErrorCode NEPComputeFunction(NEP nep,PetscScalar lambda,Mat A,Mat B)
648: {
650:   PetscInt       i;
651:   PetscScalar    alpha;

655:   NEPCheckProblem(nep,1);
656:   switch (nep->fui) {
657:   case NEP_USER_INTERFACE_CALLBACK:
658:     if (!nep->computefunction) SETERRQ(PetscObjectComm((PetscObject)nep),PETSC_ERR_USER,"Must call NEPSetFunction() first");
659:     PetscLogEventBegin(NEP_FunctionEval,nep,A,B,0);
660:     PetscStackPush("NEP user Function function");
661:     (*nep->computefunction)(nep,lambda,A,B,nep->functionctx);
662:     PetscStackPop;
663:     PetscLogEventEnd(NEP_FunctionEval,nep,A,B,0);
664:     break;
665:   case NEP_USER_INTERFACE_SPLIT:
666:     MatZeroEntries(A);
667:     for (i=0;i<nep->nt;i++) {
668:       FNEvaluateFunction(nep->f[i],lambda,&alpha);
669:       MatAXPY(A,alpha,nep->A[i],nep->mstr);
670:     }
671:     if (A != B) SETERRQ(PetscObjectComm((PetscObject)nep),1,"Not implemented");
672:     break;
673:   case NEP_USER_INTERFACE_DERIVATIVES:
674:     PetscLogEventBegin(NEP_DerivativesEval,nep,A,B,0);
675:     PetscStackPush("NEP user Derivatives function");
676:     (*nep->computederivatives)(nep,lambda,0,A,nep->derivativesctx);
677:     PetscStackPop;
678:     PetscLogEventEnd(NEP_DerivativesEval,nep,A,B,0);
679:     break;
680:   }
681:   return(0);
682: }

686: /*@
687:    NEPComputeJacobian - Computes the Jacobian matrix T'(lambda) that has been
688:    set with NEPSetJacobian().

690:    Collective on NEP and Mat

692:    Input Parameters:
693: +  nep    - the NEP context
694: -  lambda - the scalar argument

696:    Output Parameters:
697: .  A   - Jacobian matrix

699:    Notes:
700:    Most users should not need to explicitly call this routine, as it
701:    is used internally within the nonlinear eigensolvers.

703:    Level: developer

705: .seealso: NEPSetJacobian(), NEPGetJacobian()
706: @*/
707: PetscErrorCode NEPComputeJacobian(NEP nep,PetscScalar lambda,Mat A)
708: {
710:   PetscInt       i;
711:   PetscScalar    alpha;

715:   NEPCheckProblem(nep,1);
716:   switch (nep->fui) {
717:   case NEP_USER_INTERFACE_CALLBACK:
718:     if (!nep->computejacobian) SETERRQ(PetscObjectComm((PetscObject)nep),PETSC_ERR_USER,"Must call NEPSetJacobian() first");
719:     PetscLogEventBegin(NEP_JacobianEval,nep,A,0,0);
720:     PetscStackPush("NEP user Jacobian function");
721:     (*nep->computejacobian)(nep,lambda,A,nep->jacobianctx);
722:     PetscStackPop;
723:     PetscLogEventEnd(NEP_JacobianEval,nep,A,0,0);
724:     break;
725:   case NEP_USER_INTERFACE_SPLIT:
726:     MatZeroEntries(A);
727:     for (i=0;i<nep->nt;i++) {
728:       FNEvaluateDerivative(nep->f[i],lambda,&alpha);
729:       MatAXPY(A,alpha,nep->A[i],nep->mstr);
730:     }
731:     break;
732:   case NEP_USER_INTERFACE_DERIVATIVES:
733:     PetscLogEventBegin(NEP_DerivativesEval,nep,A,0,0);
734:     PetscStackPush("NEP user Derivatives function");
735:     (*nep->computederivatives)(nep,lambda,1,A,nep->derivativesctx);
736:     PetscStackPop;
737:     PetscLogEventEnd(NEP_DerivativesEval,nep,A,0,0);
738:     break;
739:   }
740:   return(0);
741: }