LCOV - code coverage report
Current view: top level - nep/interface - nepbasic.c (source / functions) Hit Total Coverage
Test: SLEPc Lines: 370 397 93.2 %
Date: 2024-04-19 00:31:36 Functions: 24 27 88.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       3             :    SLEPc - Scalable Library for Eigenvalue Problem Computations
       4             :    Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain
       5             : 
       6             :    This file is part of SLEPc.
       7             :    SLEPc is distributed under a 2-clause BSD license (see LICENSE).
       8             :    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       9             : */
      10             : /*
      11             :    Basic NEP routines
      12             : */
      13             : 
      14             : #include <slepc/private/nepimpl.h>      /*I "slepcnep.h" I*/
      15             : 
      16             : /* Logging support */
      17             : PetscClassId      NEP_CLASSID = 0;
      18             : PetscLogEvent     NEP_SetUp = 0,NEP_Solve = 0,NEP_Refine = 0,NEP_FunctionEval = 0,NEP_JacobianEval = 0,NEP_Resolvent = 0,NEP_CISS_SVD = 0;
      19             : 
      20             : /* List of registered NEP routines */
      21             : PetscFunctionList NEPList = NULL;
      22             : PetscBool         NEPRegisterAllCalled = PETSC_FALSE;
      23             : 
      24             : /* List of registered NEP monitors */
      25             : PetscFunctionList NEPMonitorList              = NULL;
      26             : PetscFunctionList NEPMonitorCreateList        = NULL;
      27             : PetscFunctionList NEPMonitorDestroyList       = NULL;
      28             : PetscBool         NEPMonitorRegisterAllCalled = PETSC_FALSE;
      29             : 
      30             : /*@
      31             :    NEPCreate - Creates the default NEP context.
      32             : 
      33             :    Collective
      34             : 
      35             :    Input Parameter:
      36             : .  comm - MPI communicator
      37             : 
      38             :    Output Parameter:
      39             : .  outnep - location to put the NEP context
      40             : 
      41             :    Level: beginner
      42             : 
      43             : .seealso: NEPSetUp(), NEPSolve(), NEPDestroy(), NEP
      44             : @*/
      45         143 : PetscErrorCode NEPCreate(MPI_Comm comm,NEP *outnep)
      46             : {
      47         143 :   NEP            nep;
      48             : 
      49         143 :   PetscFunctionBegin;
      50         143 :   PetscAssertPointer(outnep,2);
      51         143 :   *outnep = NULL;
      52         143 :   PetscCall(NEPInitializePackage());
      53         143 :   PetscCall(SlepcHeaderCreate(nep,NEP_CLASSID,"NEP","Nonlinear Eigenvalue Problem","NEP",comm,NEPDestroy,NEPView));
      54             : 
      55         143 :   nep->max_it          = PETSC_DEFAULT;
      56         143 :   nep->nev             = 1;
      57         143 :   nep->ncv             = PETSC_DEFAULT;
      58         143 :   nep->mpd             = PETSC_DEFAULT;
      59         143 :   nep->nini            = 0;
      60         143 :   nep->target          = 0.0;
      61         143 :   nep->tol             = PETSC_DEFAULT;
      62         143 :   nep->conv            = NEP_CONV_REL;
      63         143 :   nep->stop            = NEP_STOP_BASIC;
      64         143 :   nep->which           = (NEPWhich)0;
      65         143 :   nep->problem_type    = (NEPProblemType)0;
      66         143 :   nep->refine          = NEP_REFINE_NONE;
      67         143 :   nep->npart           = 1;
      68         143 :   nep->rtol            = PETSC_DEFAULT;
      69         143 :   nep->rits            = PETSC_DEFAULT;
      70         143 :   nep->scheme          = (NEPRefineScheme)0;
      71         143 :   nep->trackall        = PETSC_FALSE;
      72         143 :   nep->twosided        = PETSC_FALSE;
      73             : 
      74         143 :   nep->computefunction = NULL;
      75         143 :   nep->computejacobian = NULL;
      76         143 :   nep->functionctx     = NULL;
      77         143 :   nep->jacobianctx     = NULL;
      78         143 :   nep->converged       = NEPConvergedRelative;
      79         143 :   nep->convergeduser   = NULL;
      80         143 :   nep->convergeddestroy= NULL;
      81         143 :   nep->stopping        = NEPStoppingBasic;
      82         143 :   nep->stoppinguser    = NULL;
      83         143 :   nep->stoppingdestroy = NULL;
      84         143 :   nep->convergedctx    = NULL;
      85         143 :   nep->stoppingctx     = NULL;
      86         143 :   nep->numbermonitors  = 0;
      87             : 
      88         143 :   nep->ds              = NULL;
      89         143 :   nep->V               = NULL;
      90         143 :   nep->W               = NULL;
      91         143 :   nep->rg              = NULL;
      92         143 :   nep->function        = NULL;
      93         143 :   nep->function_pre    = NULL;
      94         143 :   nep->jacobian        = NULL;
      95         143 :   nep->A               = NULL;
      96         143 :   nep->f               = NULL;
      97         143 :   nep->nt              = 0;
      98         143 :   nep->mstr            = UNKNOWN_NONZERO_PATTERN;
      99         143 :   nep->P               = NULL;
     100         143 :   nep->mstrp           = UNKNOWN_NONZERO_PATTERN;
     101         143 :   nep->IS              = NULL;
     102         143 :   nep->eigr            = NULL;
     103         143 :   nep->eigi            = NULL;
     104         143 :   nep->errest          = NULL;
     105         143 :   nep->perm            = NULL;
     106         143 :   nep->nwork           = 0;
     107         143 :   nep->work            = NULL;
     108         143 :   nep->data            = NULL;
     109             : 
     110         143 :   nep->state           = NEP_STATE_INITIAL;
     111         143 :   nep->nconv           = 0;
     112         143 :   nep->its             = 0;
     113         143 :   nep->n               = 0;
     114         143 :   nep->nloc            = 0;
     115         143 :   nep->nrma            = NULL;
     116         143 :   nep->fui             = (NEPUserInterface)0;
     117         143 :   nep->useds           = PETSC_FALSE;
     118         143 :   nep->resolvent       = NULL;
     119         143 :   nep->reason          = NEP_CONVERGED_ITERATING;
     120             : 
     121         143 :   PetscCall(PetscNew(&nep->sc));
     122         143 :   *outnep = nep;
     123         143 :   PetscFunctionReturn(PETSC_SUCCESS);
     124             : }
     125             : 
     126             : /*@C
     127             :    NEPSetType - Selects the particular solver to be used in the NEP object.
     128             : 
     129             :    Logically Collective
     130             : 
     131             :    Input Parameters:
     132             : +  nep      - the nonlinear eigensolver context
     133             : -  type     - a known method
     134             : 
     135             :    Options Database Key:
     136             : .  -nep_type <method> - Sets the method; use -help for a list
     137             :     of available methods
     138             : 
     139             :    Notes:
     140             :    See "slepc/include/slepcnep.h" for available methods.
     141             : 
     142             :    Normally, it is best to use the NEPSetFromOptions() command and
     143             :    then set the NEP type from the options database rather than by using
     144             :    this routine.  Using the options database provides the user with
     145             :    maximum flexibility in evaluating the different available methods.
     146             :    The NEPSetType() routine is provided for those situations where it
     147             :    is necessary to set the iterative solver independently of the command
     148             :    line or options database.
     149             : 
     150             :    Level: intermediate
     151             : 
     152             : .seealso: NEPType
     153             : @*/
     154         164 : PetscErrorCode NEPSetType(NEP nep,NEPType type)
     155             : {
     156         164 :   PetscErrorCode (*r)(NEP);
     157         164 :   PetscBool      match;
     158             : 
     159         164 :   PetscFunctionBegin;
     160         164 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     161         164 :   PetscAssertPointer(type,2);
     162             : 
     163         164 :   PetscCall(PetscObjectTypeCompare((PetscObject)nep,type,&match));
     164         164 :   if (match) PetscFunctionReturn(PETSC_SUCCESS);
     165             : 
     166         161 :   PetscCall(PetscFunctionListFind(NEPList,type,&r));
     167         161 :   PetscCheck(r,PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown NEP type given: %s",type);
     168             : 
     169         161 :   PetscTryTypeMethod(nep,destroy);
     170         161 :   PetscCall(PetscMemzero(nep->ops,sizeof(struct _NEPOps)));
     171             : 
     172         161 :   nep->state = NEP_STATE_INITIAL;
     173         161 :   PetscCall(PetscObjectChangeTypeName((PetscObject)nep,type));
     174         161 :   PetscCall((*r)(nep));
     175         161 :   PetscFunctionReturn(PETSC_SUCCESS);
     176             : }
     177             : 
     178             : /*@C
     179             :    NEPGetType - Gets the NEP type as a string from the NEP object.
     180             : 
     181             :    Not Collective
     182             : 
     183             :    Input Parameter:
     184             : .  nep - the eigensolver context
     185             : 
     186             :    Output Parameter:
     187             : .  type - name of NEP method
     188             : 
     189             :    Level: intermediate
     190             : 
     191             : .seealso: NEPSetType()
     192             : @*/
     193          32 : PetscErrorCode NEPGetType(NEP nep,NEPType *type)
     194             : {
     195          32 :   PetscFunctionBegin;
     196          32 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     197          32 :   PetscAssertPointer(type,2);
     198          32 :   *type = ((PetscObject)nep)->type_name;
     199          32 :   PetscFunctionReturn(PETSC_SUCCESS);
     200             : }
     201             : 
     202             : /*@C
     203             :    NEPRegister - Adds a method to the nonlinear eigenproblem solver package.
     204             : 
     205             :    Not Collective
     206             : 
     207             :    Input Parameters:
     208             : +  name - name of a new user-defined solver
     209             : -  function - routine to create the solver context
     210             : 
     211             :    Notes:
     212             :    NEPRegister() may be called multiple times to add several user-defined solvers.
     213             : 
     214             :    Example Usage:
     215             : .vb
     216             :     NEPRegister("my_solver",MySolverCreate);
     217             : .ve
     218             : 
     219             :    Then, your solver can be chosen with the procedural interface via
     220             : $     NEPSetType(nep,"my_solver")
     221             :    or at runtime via the option
     222             : $     -nep_type my_solver
     223             : 
     224             :    Level: advanced
     225             : 
     226             : .seealso: NEPRegisterAll()
     227             : @*/
     228         864 : PetscErrorCode NEPRegister(const char *name,PetscErrorCode (*function)(NEP))
     229             : {
     230         864 :   PetscFunctionBegin;
     231         864 :   PetscCall(NEPInitializePackage());
     232         864 :   PetscCall(PetscFunctionListAdd(&NEPList,name,function));
     233         864 :   PetscFunctionReturn(PETSC_SUCCESS);
     234             : }
     235             : 
     236             : /*@C
     237             :    NEPMonitorRegister - Adds NEP monitor routine.
     238             : 
     239             :    Not Collective
     240             : 
     241             :    Input Parameters:
     242             : +  name    - name of a new monitor routine
     243             : .  vtype   - a PetscViewerType for the output
     244             : .  format  - a PetscViewerFormat for the output
     245             : .  monitor - monitor routine
     246             : .  create  - creation routine, or NULL
     247             : -  destroy - destruction routine, or NULL
     248             : 
     249             :    Notes:
     250             :    NEPMonitorRegister() may be called multiple times to add several user-defined monitors.
     251             : 
     252             :    Example Usage:
     253             : .vb
     254             :    NEPMonitorRegister("my_monitor",PETSCVIEWERASCII,PETSC_VIEWER_ASCII_INFO_DETAIL,MyMonitor,NULL,NULL);
     255             : .ve
     256             : 
     257             :    Then, your monitor can be chosen with the procedural interface via
     258             : $      NEPMonitorSetFromOptions(nep,"-nep_monitor_my_monitor","my_monitor",NULL)
     259             :    or at runtime via the option
     260             : $      -nep_monitor_my_monitor
     261             : 
     262             :    Level: advanced
     263             : 
     264             : .seealso: NEPMonitorRegisterAll()
     265             : @*/
     266         864 : PetscErrorCode NEPMonitorRegister(const char name[],PetscViewerType vtype,PetscViewerFormat format,PetscErrorCode (*monitor)(NEP,PetscInt,PetscInt,PetscScalar*,PetscScalar*,PetscReal*,PetscInt,PetscViewerAndFormat*),PetscErrorCode (*create)(PetscViewer,PetscViewerFormat,void*,PetscViewerAndFormat**),PetscErrorCode (*destroy)(PetscViewerAndFormat**))
     267             : {
     268         864 :   char           key[PETSC_MAX_PATH_LEN];
     269             : 
     270         864 :   PetscFunctionBegin;
     271         864 :   PetscCall(NEPInitializePackage());
     272         864 :   PetscCall(SlepcMonitorMakeKey_Internal(name,vtype,format,key));
     273         864 :   PetscCall(PetscFunctionListAdd(&NEPMonitorList,key,monitor));
     274         864 :   if (create)  PetscCall(PetscFunctionListAdd(&NEPMonitorCreateList,key,create));
     275         864 :   if (destroy) PetscCall(PetscFunctionListAdd(&NEPMonitorDestroyList,key,destroy));
     276         864 :   PetscFunctionReturn(PETSC_SUCCESS);
     277             : }
     278             : 
     279             : /*
     280             :    NEPReset_Problem - Destroys the problem matrices.
     281             : */
     282         266 : PetscErrorCode NEPReset_Problem(NEP nep)
     283             : {
     284         266 :   PetscInt       i;
     285             : 
     286         266 :   PetscFunctionBegin;
     287         266 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     288         266 :   PetscCall(MatDestroy(&nep->function));
     289         266 :   PetscCall(MatDestroy(&nep->function_pre));
     290         266 :   PetscCall(MatDestroy(&nep->jacobian));
     291         266 :   if (nep->fui==NEP_USER_INTERFACE_SPLIT) {
     292         117 :     PetscCall(MatDestroyMatrices(nep->nt,&nep->A));
     293         455 :     for (i=0;i<nep->nt;i++) PetscCall(FNDestroy(&nep->f[i]));
     294         117 :     PetscCall(PetscFree(nep->f));
     295         117 :     PetscCall(PetscFree(nep->nrma));
     296         117 :     if (nep->P) PetscCall(MatDestroyMatrices(nep->nt,&nep->P));
     297         117 :     nep->nt = 0;
     298             :   }
     299         266 :   PetscFunctionReturn(PETSC_SUCCESS);
     300             : }
     301             : /*@
     302             :    NEPReset - Resets the NEP context to the initial state (prior to setup)
     303             :    and destroys any allocated Vecs and Mats.
     304             : 
     305             :    Collective
     306             : 
     307             :    Input Parameter:
     308             : .  nep - eigensolver context obtained from NEPCreate()
     309             : 
     310             :    Level: advanced
     311             : 
     312             : .seealso: NEPDestroy()
     313             : @*/
     314         164 : PetscErrorCode NEPReset(NEP nep)
     315             : {
     316         164 :   PetscFunctionBegin;
     317         164 :   if (nep) PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     318           0 :   if (!nep) PetscFunctionReturn(PETSC_SUCCESS);
     319         164 :   PetscTryTypeMethod(nep,reset);
     320         164 :   if (nep->refineksp) PetscCall(KSPReset(nep->refineksp));
     321         164 :   PetscCall(NEPReset_Problem(nep));
     322         164 :   PetscCall(BVDestroy(&nep->V));
     323         164 :   PetscCall(BVDestroy(&nep->W));
     324         164 :   PetscCall(VecDestroyVecs(nep->nwork,&nep->work));
     325         164 :   PetscCall(MatDestroy(&nep->resolvent));
     326         164 :   nep->nwork = 0;
     327         164 :   nep->state = NEP_STATE_INITIAL;
     328         164 :   PetscFunctionReturn(PETSC_SUCCESS);
     329             : }
     330             : 
     331             : /*@C
     332             :    NEPDestroy - Destroys the NEP context.
     333             : 
     334             :    Collective
     335             : 
     336             :    Input Parameter:
     337             : .  nep - eigensolver context obtained from NEPCreate()
     338             : 
     339             :    Level: beginner
     340             : 
     341             : .seealso: NEPCreate(), NEPSetUp(), NEPSolve()
     342             : @*/
     343         143 : PetscErrorCode NEPDestroy(NEP *nep)
     344             : {
     345         143 :   PetscFunctionBegin;
     346         143 :   if (!*nep) PetscFunctionReturn(PETSC_SUCCESS);
     347         143 :   PetscValidHeaderSpecific(*nep,NEP_CLASSID,1);
     348         143 :   if (--((PetscObject)*nep)->refct > 0) { *nep = NULL; PetscFunctionReturn(PETSC_SUCCESS); }
     349         143 :   PetscCall(NEPReset(*nep));
     350         143 :   PetscTryTypeMethod(*nep,destroy);
     351         143 :   if ((*nep)->eigr) PetscCall(PetscFree4((*nep)->eigr,(*nep)->eigi,(*nep)->errest,(*nep)->perm));
     352         143 :   PetscCall(RGDestroy(&(*nep)->rg));
     353         143 :   PetscCall(DSDestroy(&(*nep)->ds));
     354         143 :   PetscCall(KSPDestroy(&(*nep)->refineksp));
     355         143 :   PetscCall(PetscSubcommDestroy(&(*nep)->refinesubc));
     356         143 :   PetscCall(PetscFree((*nep)->sc));
     357             :   /* just in case the initial vectors have not been used */
     358         143 :   PetscCall(SlepcBasisDestroy_Private(&(*nep)->nini,&(*nep)->IS));
     359         143 :   if ((*nep)->convergeddestroy) PetscCall((*(*nep)->convergeddestroy)((*nep)->convergedctx));
     360         143 :   PetscCall(NEPMonitorCancel(*nep));
     361         143 :   PetscCall(PetscHeaderDestroy(nep));
     362         143 :   PetscFunctionReturn(PETSC_SUCCESS);
     363             : }
     364             : 
     365             : /*@
     366             :    NEPSetBV - Associates a basis vectors object to the nonlinear eigensolver.
     367             : 
     368             :    Collective
     369             : 
     370             :    Input Parameters:
     371             : +  nep - eigensolver context obtained from NEPCreate()
     372             : -  bv  - the basis vectors object
     373             : 
     374             :    Note:
     375             :    Use NEPGetBV() to retrieve the basis vectors context (for example,
     376             :    to free it at the end of the computations).
     377             : 
     378             :    Level: advanced
     379             : 
     380             : .seealso: NEPGetBV()
     381             : @*/
     382           0 : PetscErrorCode NEPSetBV(NEP nep,BV bv)
     383             : {
     384           0 :   PetscFunctionBegin;
     385           0 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     386           0 :   PetscValidHeaderSpecific(bv,BV_CLASSID,2);
     387           0 :   PetscCheckSameComm(nep,1,bv,2);
     388           0 :   PetscCall(PetscObjectReference((PetscObject)bv));
     389           0 :   PetscCall(BVDestroy(&nep->V));
     390           0 :   nep->V = bv;
     391           0 :   PetscFunctionReturn(PETSC_SUCCESS);
     392             : }
     393             : 
     394             : /*@
     395             :    NEPGetBV - Obtain the basis vectors object associated to the nonlinear
     396             :    eigensolver object.
     397             : 
     398             :    Not Collective
     399             : 
     400             :    Input Parameters:
     401             : .  nep - eigensolver context obtained from NEPCreate()
     402             : 
     403             :    Output Parameter:
     404             : .  bv - basis vectors context
     405             : 
     406             :    Level: advanced
     407             : 
     408             : .seealso: NEPSetBV()
     409             : @*/
     410         165 : PetscErrorCode NEPGetBV(NEP nep,BV *bv)
     411             : {
     412         165 :   PetscFunctionBegin;
     413         165 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     414         165 :   PetscAssertPointer(bv,2);
     415         165 :   if (!nep->V) {
     416         164 :     PetscCall(BVCreate(PetscObjectComm((PetscObject)nep),&nep->V));
     417         164 :     PetscCall(PetscObjectIncrementTabLevel((PetscObject)nep->V,(PetscObject)nep,0));
     418         164 :     PetscCall(PetscObjectSetOptions((PetscObject)nep->V,((PetscObject)nep)->options));
     419             :   }
     420         165 :   *bv = nep->V;
     421         165 :   PetscFunctionReturn(PETSC_SUCCESS);
     422             : }
     423             : 
     424             : /*@
     425             :    NEPSetRG - Associates a region object to the nonlinear eigensolver.
     426             : 
     427             :    Collective
     428             : 
     429             :    Input Parameters:
     430             : +  nep - eigensolver context obtained from NEPCreate()
     431             : -  rg  - the region object
     432             : 
     433             :    Note:
     434             :    Use NEPGetRG() to retrieve the region context (for example,
     435             :    to free it at the end of the computations).
     436             : 
     437             :    Level: advanced
     438             : 
     439             : .seealso: NEPGetRG()
     440             : @*/
     441           2 : PetscErrorCode NEPSetRG(NEP nep,RG rg)
     442             : {
     443           2 :   PetscFunctionBegin;
     444           2 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     445           2 :   if (rg) {
     446           2 :     PetscValidHeaderSpecific(rg,RG_CLASSID,2);
     447           2 :     PetscCheckSameComm(nep,1,rg,2);
     448             :   }
     449           2 :   PetscCall(PetscObjectReference((PetscObject)rg));
     450           2 :   PetscCall(RGDestroy(&nep->rg));
     451           2 :   nep->rg = rg;
     452           2 :   PetscFunctionReturn(PETSC_SUCCESS);
     453             : }
     454             : 
     455             : /*@
     456             :    NEPGetRG - Obtain the region object associated to the
     457             :    nonlinear eigensolver object.
     458             : 
     459             :    Not Collective
     460             : 
     461             :    Input Parameters:
     462             : .  nep - eigensolver context obtained from NEPCreate()
     463             : 
     464             :    Output Parameter:
     465             : .  rg - region context
     466             : 
     467             :    Level: advanced
     468             : 
     469             : .seealso: NEPSetRG()
     470             : @*/
     471         142 : PetscErrorCode NEPGetRG(NEP nep,RG *rg)
     472             : {
     473         142 :   PetscFunctionBegin;
     474         142 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     475         142 :   PetscAssertPointer(rg,2);
     476         142 :   if (!nep->rg) {
     477         141 :     PetscCall(RGCreate(PetscObjectComm((PetscObject)nep),&nep->rg));
     478         141 :     PetscCall(PetscObjectIncrementTabLevel((PetscObject)nep->rg,(PetscObject)nep,0));
     479         141 :     PetscCall(PetscObjectSetOptions((PetscObject)nep->rg,((PetscObject)nep)->options));
     480             :   }
     481         142 :   *rg = nep->rg;
     482         142 :   PetscFunctionReturn(PETSC_SUCCESS);
     483             : }
     484             : 
     485             : /*@
     486             :    NEPSetDS - Associates a direct solver object to the nonlinear eigensolver.
     487             : 
     488             :    Collective
     489             : 
     490             :    Input Parameters:
     491             : +  nep - eigensolver context obtained from NEPCreate()
     492             : -  ds  - the direct solver object
     493             : 
     494             :    Note:
     495             :    Use NEPGetDS() to retrieve the direct solver context (for example,
     496             :    to free it at the end of the computations).
     497             : 
     498             :    Level: advanced
     499             : 
     500             : .seealso: NEPGetDS()
     501             : @*/
     502           0 : PetscErrorCode NEPSetDS(NEP nep,DS ds)
     503             : {
     504           0 :   PetscFunctionBegin;
     505           0 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     506           0 :   PetscValidHeaderSpecific(ds,DS_CLASSID,2);
     507           0 :   PetscCheckSameComm(nep,1,ds,2);
     508           0 :   PetscCall(PetscObjectReference((PetscObject)ds));
     509           0 :   PetscCall(DSDestroy(&nep->ds));
     510           0 :   nep->ds = ds;
     511           0 :   PetscFunctionReturn(PETSC_SUCCESS);
     512             : }
     513             : 
     514             : /*@
     515             :    NEPGetDS - Obtain the direct solver object associated to the
     516             :    nonlinear eigensolver object.
     517             : 
     518             :    Not Collective
     519             : 
     520             :    Input Parameters:
     521             : .  nep - eigensolver context obtained from NEPCreate()
     522             : 
     523             :    Output Parameter:
     524             : .  ds - direct solver context
     525             : 
     526             :    Level: advanced
     527             : 
     528             : .seealso: NEPSetDS()
     529             : @*/
     530         119 : PetscErrorCode NEPGetDS(NEP nep,DS *ds)
     531             : {
     532         119 :   PetscFunctionBegin;
     533         119 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     534         119 :   PetscAssertPointer(ds,2);
     535         119 :   if (!nep->ds) {
     536         118 :     PetscCall(DSCreate(PetscObjectComm((PetscObject)nep),&nep->ds));
     537         118 :     PetscCall(PetscObjectIncrementTabLevel((PetscObject)nep->ds,(PetscObject)nep,0));
     538         118 :     PetscCall(PetscObjectSetOptions((PetscObject)nep->ds,((PetscObject)nep)->options));
     539             :   }
     540         119 :   *ds = nep->ds;
     541         119 :   PetscFunctionReturn(PETSC_SUCCESS);
     542             : }
     543             : 
     544             : /*@
     545             :    NEPRefineGetKSP - Obtain the ksp object used by the eigensolver
     546             :    object in the refinement phase.
     547             : 
     548             :    Collective
     549             : 
     550             :    Input Parameters:
     551             : .  nep - eigensolver context obtained from NEPCreate()
     552             : 
     553             :    Output Parameter:
     554             : .  ksp - ksp context
     555             : 
     556             :    Level: advanced
     557             : 
     558             : .seealso: NEPSetRefine()
     559             : @*/
     560         147 : PetscErrorCode NEPRefineGetKSP(NEP nep,KSP *ksp)
     561             : {
     562         147 :   MPI_Comm       comm;
     563             : 
     564         147 :   PetscFunctionBegin;
     565         147 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     566         147 :   PetscAssertPointer(ksp,2);
     567         147 :   if (!nep->refineksp) {
     568         143 :     if (nep->npart>1) {
     569             :       /* Split in subcomunicators */
     570           8 :       PetscCall(PetscSubcommCreate(PetscObjectComm((PetscObject)nep),&nep->refinesubc));
     571           8 :       PetscCall(PetscSubcommSetNumber(nep->refinesubc,nep->npart));
     572           8 :       PetscCall(PetscSubcommSetType(nep->refinesubc,PETSC_SUBCOMM_CONTIGUOUS));
     573           8 :       PetscCall(PetscSubcommGetChild(nep->refinesubc,&comm));
     574         135 :     } else PetscCall(PetscObjectGetComm((PetscObject)nep,&comm));
     575         143 :     PetscCall(KSPCreate(comm,&nep->refineksp));
     576         143 :     PetscCall(PetscObjectIncrementTabLevel((PetscObject)nep->refineksp,(PetscObject)nep,0));
     577         143 :     PetscCall(PetscObjectSetOptions((PetscObject)nep->refineksp,((PetscObject)nep)->options));
     578         143 :     PetscCall(KSPSetOptionsPrefix(*ksp,((PetscObject)nep)->prefix));
     579         143 :     PetscCall(KSPAppendOptionsPrefix(*ksp,"nep_refine_"));
     580         285 :     PetscCall(KSPSetTolerances(nep->refineksp,SlepcDefaultTol(nep->rtol),PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT));
     581             :   }
     582         147 :   *ksp = nep->refineksp;
     583         147 :   PetscFunctionReturn(PETSC_SUCCESS);
     584             : }
     585             : 
     586             : /*@
     587             :    NEPSetTarget - Sets the value of the target.
     588             : 
     589             :    Logically Collective
     590             : 
     591             :    Input Parameters:
     592             : +  nep    - eigensolver context
     593             : -  target - the value of the target
     594             : 
     595             :    Options Database Key:
     596             : .  -nep_target <scalar> - the value of the target
     597             : 
     598             :    Notes:
     599             :    The target is a scalar value used to determine the portion of the spectrum
     600             :    of interest. It is used in combination with NEPSetWhichEigenpairs().
     601             : 
     602             :    In the case of complex scalars, a complex value can be provided in the
     603             :    command line with [+/-][realnumber][+/-]realnumberi with no spaces, e.g.
     604             :    -nep_target 1.0+2.0i
     605             : 
     606             :    Level: intermediate
     607             : 
     608             : .seealso: NEPGetTarget(), NEPSetWhichEigenpairs()
     609             : @*/
     610         107 : PetscErrorCode NEPSetTarget(NEP nep,PetscScalar target)
     611             : {
     612         107 :   PetscFunctionBegin;
     613         107 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     614         428 :   PetscValidLogicalCollectiveScalar(nep,target,2);
     615         107 :   nep->target = target;
     616         107 :   PetscFunctionReturn(PETSC_SUCCESS);
     617             : }
     618             : 
     619             : /*@
     620             :    NEPGetTarget - Gets the value of the target.
     621             : 
     622             :    Not Collective
     623             : 
     624             :    Input Parameter:
     625             : .  nep - eigensolver context
     626             : 
     627             :    Output Parameter:
     628             : .  target - the value of the target
     629             : 
     630             :    Note:
     631             :    If the target was not set by the user, then zero is returned.
     632             : 
     633             :    Level: intermediate
     634             : 
     635             : .seealso: NEPSetTarget()
     636             : @*/
     637           1 : PetscErrorCode NEPGetTarget(NEP nep,PetscScalar* target)
     638             : {
     639           1 :   PetscFunctionBegin;
     640           1 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     641           1 :   PetscAssertPointer(target,2);
     642           1 :   *target = nep->target;
     643           1 :   PetscFunctionReturn(PETSC_SUCCESS);
     644             : }
     645             : 
     646             : /*@C
     647             :    NEPSetFunction - Sets the function to compute the nonlinear Function T(lambda)
     648             :    as well as the location to store the matrix.
     649             : 
     650             :    Collective
     651             : 
     652             :    Input Parameters:
     653             : +  nep - the NEP context
     654             : .  A   - Function matrix
     655             : .  B   - preconditioner matrix (usually same as A)
     656             : .  fun - Function evaluation routine (if NULL then NEP retains any
     657             :          previously set value)
     658             : -  ctx - [optional] user-defined context for private data for the Function
     659             :          evaluation routine (may be NULL) (if NULL then NEP retains any
     660             :          previously set value)
     661             : 
     662             :    Calling sequence of fun:
     663             : $  PetscErrorCode fun(NEP nep,PetscScalar lambda,Mat T,Mat P,void *ctx)
     664             : +  nep    - the NEP context
     665             : .  lambda - the scalar argument where T(.) must be evaluated
     666             : .  T      - matrix that will contain T(lambda)
     667             : .  P      - (optional) different matrix to build the preconditioner
     668             : -  ctx    - (optional) user-defined context, as set by NEPSetFunction()
     669             : 
     670             :    Level: beginner
     671             : 
     672             : .seealso: NEPGetFunction(), NEPSetJacobian()
     673             : @*/
     674          47 : PetscErrorCode NEPSetFunction(NEP nep,Mat A,Mat B,PetscErrorCode (*fun)(NEP nep,PetscScalar lambda,Mat T,Mat P,void *ctx),void *ctx)
     675             : {
     676          47 :   PetscFunctionBegin;
     677          47 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     678          47 :   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
     679          47 :   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
     680          47 :   if (A) PetscCheckSameComm(nep,1,A,2);
     681          47 :   if (B) PetscCheckSameComm(nep,1,B,3);
     682             : 
     683          47 :   if (nep->state) PetscCall(NEPReset(nep));
     684          41 :   else if (nep->fui && nep->fui!=NEP_USER_INTERFACE_CALLBACK) PetscCall(NEPReset_Problem(nep));
     685             : 
     686          47 :   if (fun) nep->computefunction = fun;
     687          47 :   if (ctx) nep->functionctx     = ctx;
     688          47 :   if (A) {
     689          47 :     PetscCall(PetscObjectReference((PetscObject)A));
     690          47 :     PetscCall(MatDestroy(&nep->function));
     691          47 :     nep->function = A;
     692             :   }
     693          47 :   if (B) {
     694          47 :     PetscCall(PetscObjectReference((PetscObject)B));
     695          47 :     PetscCall(MatDestroy(&nep->function_pre));
     696          47 :     nep->function_pre = B;
     697             :   }
     698          47 :   nep->fui   = NEP_USER_INTERFACE_CALLBACK;
     699          47 :   nep->state = NEP_STATE_INITIAL;
     700          47 :   PetscFunctionReturn(PETSC_SUCCESS);
     701             : }
     702             : 
     703             : /*@C
     704             :    NEPGetFunction - Returns the Function matrix and optionally the user
     705             :    provided context for evaluating the Function.
     706             : 
     707             :    Not Collective
     708             : 
     709             :    Input Parameter:
     710             : .  nep - the nonlinear eigensolver context
     711             : 
     712             :    Output Parameters:
     713             : +  A   - location to stash Function matrix (or NULL)
     714             : .  B   - location to stash preconditioner matrix (or NULL)
     715             : .  fun - location to put Function function (or NULL)
     716             : -  ctx - location to stash Function context (or NULL)
     717             : 
     718             :    Level: advanced
     719             : 
     720             : .seealso: NEPSetFunction()
     721             : @*/
     722          94 : PetscErrorCode NEPGetFunction(NEP nep,Mat *A,Mat *B,PetscErrorCode (**fun)(NEP,PetscScalar,Mat,Mat,void*),void **ctx)
     723             : {
     724          94 :   PetscFunctionBegin;
     725          94 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     726          94 :   NEPCheckCallback(nep,1);
     727          94 :   if (A)   *A   = nep->function;
     728          94 :   if (B)   *B   = nep->function_pre;
     729          94 :   if (fun) *fun = nep->computefunction;
     730          94 :   if (ctx) *ctx = nep->functionctx;
     731          94 :   PetscFunctionReturn(PETSC_SUCCESS);
     732             : }
     733             : 
     734             : /*@C
     735             :    NEPSetJacobian - Sets the function to compute the Jacobian T'(lambda) as well
     736             :    as the location to store the matrix.
     737             : 
     738             :    Collective
     739             : 
     740             :    Input Parameters:
     741             : +  nep - the NEP context
     742             : .  A   - Jacobian matrix
     743             : .  jac - Jacobian evaluation routine (if NULL then NEP retains any
     744             :          previously set value)
     745             : -  ctx - [optional] user-defined context for private data for the Jacobian
     746             :          evaluation routine (may be NULL) (if NULL then NEP retains any
     747             :          previously set value)
     748             : 
     749             :    Calling sequence of jac:
     750             : $  PetscErrorCode jac(NEP nep,PetscScalar lambda,Mat J,void *ctx)
     751             : +  nep    - the NEP context
     752             : .  lambda - the scalar argument where T'(.) must be evaluated
     753             : .  J      - matrix that will contain T'(lambda)
     754             : -  ctx    - (optional) user-defined context, as set by NEPSetJacobian()
     755             : 
     756             :    Level: beginner
     757             : 
     758             : .seealso: NEPSetFunction(), NEPGetJacobian()
     759             : @*/
     760          44 : PetscErrorCode NEPSetJacobian(NEP nep,Mat A,PetscErrorCode (*jac)(NEP nep,PetscScalar lambda,Mat J,void *ctx),void *ctx)
     761             : {
     762          44 :   PetscFunctionBegin;
     763          44 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     764          44 :   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
     765          44 :   if (A) PetscCheckSameComm(nep,1,A,2);
     766             : 
     767          44 :   if (nep->state) PetscCall(NEPReset(nep));
     768          44 :   else if (nep->fui && nep->fui!=NEP_USER_INTERFACE_CALLBACK) PetscCall(NEPReset_Problem(nep));
     769             : 
     770          44 :   if (jac) nep->computejacobian = jac;
     771          44 :   if (ctx) nep->jacobianctx     = ctx;
     772          44 :   if (A) {
     773          44 :     PetscCall(PetscObjectReference((PetscObject)A));
     774          44 :     PetscCall(MatDestroy(&nep->jacobian));
     775          44 :     nep->jacobian = A;
     776             :   }
     777          44 :   nep->fui   = NEP_USER_INTERFACE_CALLBACK;
     778          44 :   nep->state = NEP_STATE_INITIAL;
     779          44 :   PetscFunctionReturn(PETSC_SUCCESS);
     780             : }
     781             : 
     782             : /*@C
     783             :    NEPGetJacobian - Returns the Jacobian matrix and optionally the user
     784             :    provided routine and context for evaluating the Jacobian.
     785             : 
     786             :    Not Collective
     787             : 
     788             :    Input Parameter:
     789             : .  nep - the nonlinear eigensolver context
     790             : 
     791             :    Output Parameters:
     792             : +  A   - location to stash Jacobian matrix (or NULL)
     793             : .  jac - location to put Jacobian function (or NULL)
     794             : -  ctx - location to stash Jacobian context (or NULL)
     795             : 
     796             :    Level: advanced
     797             : 
     798             : .seealso: NEPSetJacobian()
     799             : @*/
     800           0 : PetscErrorCode NEPGetJacobian(NEP nep,Mat *A,PetscErrorCode (**jac)(NEP,PetscScalar,Mat,void*),void **ctx)
     801             : {
     802           0 :   PetscFunctionBegin;
     803           0 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     804           0 :   NEPCheckCallback(nep,1);
     805           0 :   if (A)   *A   = nep->jacobian;
     806           0 :   if (jac) *jac = nep->computejacobian;
     807           0 :   if (ctx) *ctx = nep->jacobianctx;
     808           0 :   PetscFunctionReturn(PETSC_SUCCESS);
     809             : }
     810             : 
     811             : /*@
     812             :    NEPSetSplitOperator - Sets the operator of the nonlinear eigenvalue problem
     813             :    in split form.
     814             : 
     815             :    Collective
     816             : 
     817             :    Input Parameters:
     818             : +  nep - the nonlinear eigensolver context
     819             : .  nt  - number of terms in the split form
     820             : .  A   - array of matrices
     821             : .  f   - array of functions
     822             : -  str - structure flag for matrices
     823             : 
     824             :    Notes:
     825             :    The nonlinear operator is written as T(lambda) = sum_i A_i*f_i(lambda),
     826             :    for i=1,...,n. The derivative T'(lambda) can be obtained using the
     827             :    derivatives of f_i.
     828             : 
     829             :    The structure flag provides information about A_i's nonzero pattern
     830             :    (see MatStructure enum). If all matrices have the same pattern, then
     831             :    use SAME_NONZERO_PATTERN. If the patterns are different but contained
     832             :    in the pattern of the first one, then use SUBSET_NONZERO_PATTERN. If
     833             :    patterns are known to be different, use DIFFERENT_NONZERO_PATTERN.
     834             :    If set to UNKNOWN_NONZERO_PATTERN, the patterns will be compared to
     835             :    determine if they are equal.
     836             : 
     837             :    This function must be called before NEPSetUp(). If it is called again
     838             :    after NEPSetUp() then the NEP object is reset.
     839             : 
     840             :    Level: beginner
     841             : 
     842             : .seealso: NEPGetSplitOperatorTerm(), NEPGetSplitOperatorInfo(), NEPSetSplitPreconditioner()
     843             : @*/
     844         117 : PetscErrorCode NEPSetSplitOperator(NEP nep,PetscInt nt,Mat A[],FN f[],MatStructure str)
     845             : {
     846         117 :   PetscInt       i,n=0,m,m0=0,mloc,nloc,mloc0=0;
     847             : 
     848         117 :   PetscFunctionBegin;
     849         117 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     850         468 :   PetscValidLogicalCollectiveInt(nep,nt,2);
     851         117 :   PetscCheck(nt>0,PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more terms, you have %" PetscInt_FMT,nt);
     852         117 :   PetscAssertPointer(A,3);
     853         117 :   PetscAssertPointer(f,4);
     854         468 :   PetscValidLogicalCollectiveEnum(nep,str,5);
     855             : 
     856         455 :   for (i=0;i<nt;i++) {
     857         338 :     PetscValidHeaderSpecific(A[i],MAT_CLASSID,3);
     858         338 :     PetscCheckSameComm(nep,1,A[i],3);
     859         338 :     PetscValidHeaderSpecific(f[i],FN_CLASSID,4);
     860         338 :     PetscCheckSameComm(nep,1,f[i],4);
     861         338 :     PetscCall(MatGetSize(A[i],&m,&n));
     862         338 :     PetscCall(MatGetLocalSize(A[i],&mloc,&nloc));
     863         338 :     PetscCheck(m==n,PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_WRONG,"A[%" PetscInt_FMT "] is a non-square matrix (%" PetscInt_FMT " rows, %" PetscInt_FMT " cols)",i,m,n);
     864         338 :     PetscCheck(mloc==nloc,PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_WRONG,"A[%" PetscInt_FMT "] does not have equal row and column local sizes (%" PetscInt_FMT ", %" PetscInt_FMT ")",i,mloc,nloc);
     865         338 :     if (!i) { m0 = m; mloc0 = mloc; }
     866         338 :     PetscCheck(m==m0,PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_INCOMP,"Dimensions of A[%" PetscInt_FMT "] do not match with previous matrices (%" PetscInt_FMT ", %" PetscInt_FMT ")",i,m,m0);
     867         338 :     PetscCheck(mloc==mloc0,PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_INCOMP,"Local dimensions of A[%" PetscInt_FMT "] do not match with previous matrices (%" PetscInt_FMT ", %" PetscInt_FMT ")",i,mloc,mloc0);
     868         338 :     PetscCall(PetscObjectReference((PetscObject)A[i]));
     869         338 :     PetscCall(PetscObjectReference((PetscObject)f[i]));
     870             :   }
     871             : 
     872         117 :   if (nep->state && (n!=nep->n || nloc!=nep->nloc)) PetscCall(NEPReset(nep));
     873         102 :   else PetscCall(NEPReset_Problem(nep));
     874             : 
     875             :   /* allocate space and copy matrices and functions */
     876         117 :   PetscCall(PetscMalloc1(nt,&nep->A));
     877         455 :   for (i=0;i<nt;i++) nep->A[i] = A[i];
     878         117 :   PetscCall(PetscMalloc1(nt,&nep->f));
     879         455 :   for (i=0;i<nt;i++) nep->f[i] = f[i];
     880         117 :   PetscCall(PetscCalloc1(nt,&nep->nrma));
     881         117 :   nep->nt    = nt;
     882         117 :   nep->mstr  = str;
     883         117 :   nep->fui   = NEP_USER_INTERFACE_SPLIT;
     884         117 :   nep->state = NEP_STATE_INITIAL;
     885         117 :   PetscFunctionReturn(PETSC_SUCCESS);
     886             : }
     887             : 
     888             : /*@
     889             :    NEPGetSplitOperatorTerm - Gets the matrices and functions associated with
     890             :    the nonlinear operator in split form.
     891             : 
     892             :    Not Collective
     893             : 
     894             :    Input Parameters:
     895             : +  nep - the nonlinear eigensolver context
     896             : -  k   - the index of the requested term (starting in 0)
     897             : 
     898             :    Output Parameters:
     899             : +  A - the matrix of the requested term
     900             : -  f - the function of the requested term
     901             : 
     902             :    Level: intermediate
     903             : 
     904             : .seealso: NEPSetSplitOperator(), NEPGetSplitOperatorInfo()
     905             : @*/
     906          29 : PetscErrorCode NEPGetSplitOperatorTerm(NEP nep,PetscInt k,Mat *A,FN *f)
     907             : {
     908          29 :   PetscFunctionBegin;
     909          29 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     910         116 :   PetscValidLogicalCollectiveInt(nep,k,2);
     911          29 :   NEPCheckSplit(nep,1);
     912          29 :   PetscCheck(k>=0 && k<nep->nt,PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_OUTOFRANGE,"k must be between 0 and %" PetscInt_FMT,nep->nt-1);
     913          29 :   if (A) *A = nep->A[k];
     914          29 :   if (f) *f = nep->f[k];
     915          29 :   PetscFunctionReturn(PETSC_SUCCESS);
     916             : }
     917             : 
     918             : /*@
     919             :    NEPGetSplitOperatorInfo - Returns the number of terms of the split form of
     920             :    the nonlinear operator, as well as the structure flag for matrices.
     921             : 
     922             :    Not Collective
     923             : 
     924             :    Input Parameter:
     925             : .  nep - the nonlinear eigensolver context
     926             : 
     927             :    Output Parameters:
     928             : +  n   - the number of terms passed in NEPSetSplitOperator()
     929             : -  str - the matrix structure flag passed in NEPSetSplitOperator()
     930             : 
     931             :    Level: intermediate
     932             : 
     933             : .seealso: NEPSetSplitOperator(), NEPGetSplitOperatorTerm()
     934             : @*/
     935          10 : PetscErrorCode NEPGetSplitOperatorInfo(NEP nep,PetscInt *n,MatStructure *str)
     936             : {
     937          10 :   PetscFunctionBegin;
     938          10 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     939          10 :   NEPCheckSplit(nep,1);
     940          10 :   if (n)   *n = nep->nt;
     941          10 :   if (str) *str = nep->mstr;
     942          10 :   PetscFunctionReturn(PETSC_SUCCESS);
     943             : }
     944             : 
     945             : /*@
     946             :    NEPSetSplitPreconditioner - Sets an operator in split form from which
     947             :    to build the preconditioner to be used when solving the nonlinear
     948             :    eigenvalue problem in split form.
     949             : 
     950             :    Collective
     951             : 
     952             :    Input Parameters:
     953             : +  nep  - the nonlinear eigensolver context
     954             : .  ntp  - number of terms in the split preconditioner
     955             : .  P    - array of matrices
     956             : -  strp - structure flag for matrices
     957             : 
     958             :    Notes:
     959             :    The matrix for the preconditioner is expressed as P(lambda) =
     960             :    sum_i P_i*f_i(lambda), for i=1,...,n, where the f_i functions
     961             :    are the same as in NEPSetSplitOperator(). It is not necessary to call
     962             :    this function. If it is not invoked, then the preconditioner is
     963             :    built from T(lambda), i.e., both matrices and functions passed in
     964             :    NEPSetSplitOperator().
     965             : 
     966             :    The structure flag provides information about P_i's nonzero pattern
     967             :    in the same way as in NEPSetSplitOperator().
     968             : 
     969             :    If the functions defining the preconditioner operator were different
     970             :    from the ones given in NEPSetSplitOperator(), then the split form
     971             :    cannot be used. Use the callback interface instead.
     972             : 
     973             :    Use ntp=0 to reset a previously set split preconditioner.
     974             : 
     975             :    Level: advanced
     976             : 
     977             : .seealso: NEPGetSplitPreconditionerTerm(), NEPGetSplitPreconditionerInfo(), NEPSetSplitOperator()
     978             : @*/
     979           7 : PetscErrorCode NEPSetSplitPreconditioner(NEP nep,PetscInt ntp,Mat P[],MatStructure strp)
     980             : {
     981           7 :   PetscInt       i,n=0,m,m0=0,mloc,nloc,mloc0=0;
     982             : 
     983           7 :   PetscFunctionBegin;
     984           7 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
     985          28 :   PetscValidLogicalCollectiveInt(nep,ntp,2);
     986           7 :   PetscCheck(ntp>=0,PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_OUTOFRANGE,"Negative value of ntp = %" PetscInt_FMT,ntp);
     987           7 :   PetscCheck(nep->fui==NEP_USER_INTERFACE_SPLIT,PetscObjectComm((PetscObject)nep),PETSC_ERR_ORDER,"Must call NEPSetSplitOperator first");
     988           7 :   PetscCheck(ntp==0 || nep->nt==ntp,PetscObjectComm((PetscObject)nep),PETSC_ERR_SUP,"The number of terms must be the same as in NEPSetSplitOperator()");
     989           7 :   if (ntp) PetscAssertPointer(P,3);
     990          28 :   PetscValidLogicalCollectiveEnum(nep,strp,4);
     991             : 
     992          28 :   for (i=0;i<ntp;i++) {
     993          21 :     PetscValidHeaderSpecific(P[i],MAT_CLASSID,3);
     994          21 :     PetscCheckSameComm(nep,1,P[i],3);
     995          21 :     PetscCall(MatGetSize(P[i],&m,&n));
     996          21 :     PetscCall(MatGetLocalSize(P[i],&mloc,&nloc));
     997          21 :     PetscCheck(m==n,PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_WRONG,"P[%" PetscInt_FMT "] is a non-square matrix (%" PetscInt_FMT " rows, %" PetscInt_FMT " cols)",i,m,n);
     998          21 :     PetscCheck(mloc==nloc,PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_WRONG,"P[%" PetscInt_FMT "] does not have equal row and column local sizes (%" PetscInt_FMT ", %" PetscInt_FMT ")",i,mloc,nloc);
     999          21 :     if (!i) { m0 = m; mloc0 = mloc; }
    1000          21 :     PetscCheck(m==m0,PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_INCOMP,"Dimensions of P[%" PetscInt_FMT "] do not match with previous matrices (%" PetscInt_FMT ", %" PetscInt_FMT ")",i,m,m0);
    1001          21 :     PetscCheck(mloc==mloc0,PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_INCOMP,"Local dimensions of P[%" PetscInt_FMT "] do not match with previous matrices (%" PetscInt_FMT ", %" PetscInt_FMT ")",i,mloc,mloc0);
    1002          21 :     PetscCall(PetscObjectReference((PetscObject)P[i]));
    1003             :   }
    1004             : 
    1005           7 :   PetscCheck(!nep->state,PetscObjectComm((PetscObject)nep),PETSC_ERR_ORDER,"To call this function after NEPSetUp(), you must call NEPSetSplitOperator() again");
    1006           7 :   if (nep->P) PetscCall(MatDestroyMatrices(nep->nt,&nep->P));
    1007             : 
    1008             :   /* allocate space and copy matrices */
    1009           7 :   if (ntp) {
    1010           7 :     PetscCall(PetscMalloc1(ntp,&nep->P));
    1011          28 :     for (i=0;i<ntp;i++) nep->P[i] = P[i];
    1012             :   }
    1013           7 :   nep->mstrp = strp;
    1014           7 :   nep->state = NEP_STATE_INITIAL;
    1015           7 :   PetscFunctionReturn(PETSC_SUCCESS);
    1016             : }
    1017             : 
    1018             : /*@
    1019             :    NEPGetSplitPreconditionerTerm - Gets the matrices associated with
    1020             :    the split preconditioner.
    1021             : 
    1022             :    Not Collective
    1023             : 
    1024             :    Input Parameters:
    1025             : +  nep - the nonlinear eigensolver context
    1026             : -  k   - the index of the requested term (starting in 0)
    1027             : 
    1028             :    Output Parameter:
    1029             : .  P  - the matrix of the requested term
    1030             : 
    1031             :    Level: advanced
    1032             : 
    1033             : .seealso: NEPSetSplitPreconditioner(), NEPGetSplitPreconditionerInfo()
    1034             : @*/
    1035           7 : PetscErrorCode NEPGetSplitPreconditionerTerm(NEP nep,PetscInt k,Mat *P)
    1036             : {
    1037           7 :   PetscFunctionBegin;
    1038           7 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
    1039          28 :   PetscValidLogicalCollectiveInt(nep,k,2);
    1040           7 :   PetscAssertPointer(P,3);
    1041           7 :   NEPCheckSplit(nep,1);
    1042           7 :   PetscCheck(k>=0 && k<nep->nt,PetscObjectComm((PetscObject)nep),PETSC_ERR_ARG_OUTOFRANGE,"k must be between 0 and %" PetscInt_FMT,nep->nt-1);
    1043           7 :   PetscCheck(nep->P,PetscObjectComm((PetscObject)nep),PETSC_ERR_ORDER,"You have not called NEPSetSplitPreconditioner()");
    1044           7 :   *P = nep->P[k];
    1045           7 :   PetscFunctionReturn(PETSC_SUCCESS);
    1046             : }
    1047             : 
    1048             : /*@
    1049             :    NEPGetSplitPreconditionerInfo - Returns the number of terms of the split
    1050             :    preconditioner, as well as the structure flag for matrices.
    1051             : 
    1052             :    Not Collective
    1053             : 
    1054             :    Input Parameter:
    1055             : .  nep - the nonlinear eigensolver context
    1056             : 
    1057             :    Output Parameters:
    1058             : +  n    - the number of terms passed in NEPSetSplitPreconditioner()
    1059             : -  strp - the matrix structure flag passed in NEPSetSplitPreconditioner()
    1060             : 
    1061             :    Level: advanced
    1062             : 
    1063             : .seealso: NEPSetSplitPreconditioner(), NEPGetSplitPreconditionerTerm()
    1064             : @*/
    1065           7 : PetscErrorCode NEPGetSplitPreconditionerInfo(NEP nep,PetscInt *n,MatStructure *strp)
    1066             : {
    1067           7 :   PetscFunctionBegin;
    1068           7 :   PetscValidHeaderSpecific(nep,NEP_CLASSID,1);
    1069           7 :   NEPCheckSplit(nep,1);
    1070           7 :   if (n)    *n    = nep->P? nep->nt: 0;
    1071           7 :   if (strp) *strp = nep->mstrp;
    1072           7 :   PetscFunctionReturn(PETSC_SUCCESS);
    1073             : }

Generated by: LCOV version 1.14