Actual source code: stset.c

  1: /*
  2:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3:    SLEPc - Scalable Library for Eigenvalue Problem Computations
  4:    Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain

  6:    This file is part of SLEPc.
  7:    SLEPc is distributed under a 2-clause BSD license (see LICENSE).
  8:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  9: */
 10: /*
 11:    Routines to set ST methods and options
 12: */

 14: #include <slepc/private/stimpl.h>

 16: PetscBool         STRegisterAllCalled = PETSC_FALSE;
 17: PetscFunctionList STList = NULL;

 19: /*@
 20:    STSetType - Selects the type of spectral transformation.

 22:    Logically Collective

 24:    Input Parameters:
 25: +  st   - the spectral transformation context.
 26: -  type - a known type

 28:    Options Database Key:
 29: .  -st_type \<type\> - sets the `ST` type

 31:    Notes:
 32:    Normally, it is best to call the `EPSSetFromOptions()` function and
 33:    then set the `ST` type from the options database rather than by using
 34:    this routine.  Using the options database provides the user with
 35:    maximum flexibility in evaluating the different transformations.

 37:    Level: beginner

 39: .seealso: [](ch:st), `STGetType()`, `EPSSetType()`, `EPSSetFromOptions()`

 41: @*/
 42: PetscErrorCode STSetType(ST st,STType type)
 43: {
 44:   PetscErrorCode (*r)(ST);
 45:   PetscBool      match;

 47:   PetscFunctionBegin;
 49:   PetscAssertPointer(type,2);

 51:   PetscCall(PetscObjectTypeCompare((PetscObject)st,type,&match));
 52:   if (match) PetscFunctionReturn(PETSC_SUCCESS);
 53:   STCheckNotSeized(st,1);

 55:   PetscCall(PetscFunctionListFind(STList,type,&r));
 56:   PetscCheck(r,PetscObjectComm((PetscObject)st),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested ST type %s",type);

 58:   PetscTryTypeMethod(st,destroy);
 59:   PetscCall(PetscMemzero(st->ops,sizeof(struct _STOps)));

 61:   st->state   = ST_STATE_INITIAL;
 62:   st->opready = PETSC_FALSE;
 63:   PetscCall(PetscObjectChangeTypeName((PetscObject)st,type));
 64:   PetscCall((*r)(st));
 65:   PetscFunctionReturn(PETSC_SUCCESS);
 66: }

 68: /*@
 69:    STGetType - Gets the `ST` type name (as a string) from the `ST` context.

 71:    Not Collective

 73:    Input Parameter:
 74: .  st - the spectral transformation context

 76:    Output Parameter:
 77: .  type - name of the spectral transformation

 79:    Level: intermediate

 81: .seealso: [](ch:st), `STSetType()`

 83: @*/
 84: PetscErrorCode STGetType(ST st,STType *type)
 85: {
 86:   PetscFunctionBegin;
 88:   PetscAssertPointer(type,2);
 89:   *type = ((PetscObject)st)->type_name;
 90:   PetscFunctionReturn(PETSC_SUCCESS);
 91: }

 93: /*@
 94:    STSetFromOptions - Sets `ST` options from the options database.

 96:    Collective

 98:    Input Parameter:
 99: .  st - the spectral transformation context

101:    Note:
102:    To see all options, run your program with the `-help` option.

104:    Level: beginner

106: .seealso: [](ch:st), `STSetOptionsPrefix()`
107: @*/
108: PetscErrorCode STSetFromOptions(ST st)
109: {
110:   PetscScalar    s;
111:   char           type[256];
112:   PetscBool      flg,bval;
113:   STMatMode      mode;
114:   MatStructure   mstr;

116:   PetscFunctionBegin;
118:   PetscCall(STRegisterAll());
119:   PetscObjectOptionsBegin((PetscObject)st);
120:     PetscCall(PetscOptionsFList("-st_type","Spectral transformation","STSetType",STList,(char*)(((PetscObject)st)->type_name?((PetscObject)st)->type_name:STSHIFT),type,sizeof(type),&flg));
121:     if (flg) PetscCall(STSetType(st,type));
122:     else if (!((PetscObject)st)->type_name) PetscCall(STSetType(st,STSHIFT));

124:     PetscCall(PetscOptionsScalar("-st_shift","Value of the shift","STSetShift",st->sigma,&s,&flg));
125:     if (flg) PetscCall(STSetShift(st,s));

127:     PetscCall(PetscOptionsEnum("-st_matmode","Matrix mode for transformed matrices","STSetMatMode",STMatModes,(PetscEnum)st->matmode,(PetscEnum*)&mode,&flg));
128:     if (flg) PetscCall(STSetMatMode(st,mode));

130:     PetscCall(PetscOptionsEnum("-st_matstructure","Relation of the sparsity pattern of the matrices","STSetMatStructure",MatStructures,(PetscEnum)st->str,(PetscEnum*)&mstr,&flg));
131:     if (flg) PetscCall(STSetMatStructure(st,mstr));

133:     PetscCall(PetscOptionsBool("-st_transform","Whether transformed matrices are computed or not","STSetTransform",st->transform,&bval,&flg));
134:     if (flg) PetscCall(STSetTransform(st,bval));

136:     PetscTryTypeMethod(st,setfromoptions,PetscOptionsObject);
137:     PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)st,PetscOptionsObject));
138:   PetscOptionsEnd();

140:   if (st->usesksp) {
141:     PetscCall(STSetDefaultKSP(st));
142:     PetscCall(KSPSetFromOptions(st->ksp));
143:   }
144:   PetscFunctionReturn(PETSC_SUCCESS);
145: }

147: /*@
148:    STSetMatStructure - Sets an internal `MatStructure` attribute to
149:    indicate which is the relation of the sparsity pattern of all `ST` matrices.

151:    Logically Collective

153:    Input Parameters:
154: +  st  - the spectral transformation context
155: -  str - either `SAME_NONZERO_PATTERN`, `DIFFERENT_NONZERO_PATTERN`,
156:          `SUBSET_NONZERO_PATTERN`, or `UNKNOWN_NONZERO_PATTERN`

158:    Options Database Key:
159: .  -st_matstructure \<str\> - the structure flag, one of `same`, `different`, `subset`, `unknown`

161:    Notes:
162:    If the sparsity pattern of the second matrix is equal or a subset of the
163:    pattern of the first matrix then it is recommended to set this attribute
164:    for efficiency reasons (in particular, for internal `MatAXPY()` operations).
165:    If not set, the default is `UNKNOWN_NONZERO_PATTERN`, in which case the patterns
166:    will be compared to determine if they are equal.

168:    This function has no effect in the case of standard eigenproblems.

170:    In case of polynomial eigenproblems, the flag applies to all matrices
171:    relative to the first one.

173:    Level: advanced

175: .seealso: [](ch:st), `STSetMatrices()`, `MatAXPY()`
176: @*/
177: PetscErrorCode STSetMatStructure(ST st,MatStructure str)
178: {
179:   PetscFunctionBegin;
182:   switch (str) {
183:     case SAME_NONZERO_PATTERN:
184:     case DIFFERENT_NONZERO_PATTERN:
185:     case SUBSET_NONZERO_PATTERN:
186:     case UNKNOWN_NONZERO_PATTERN:
187:       st->str = str;
188:       break;
189:     default:
190:       SETERRQ(PetscObjectComm((PetscObject)st),PETSC_ERR_ARG_OUTOFRANGE,"Invalid matrix structure flag");
191:   }
192:   PetscFunctionReturn(PETSC_SUCCESS);
193: }

195: /*@
196:    STGetMatStructure - Gets the internal `MatStructure` attribute to
197:    indicate which is the relation of the sparsity pattern of the matrices.

199:    Not Collective

201:    Input Parameter:
202: .  st  - the spectral transformation context

204:    Output Parameter:
205: .  str - either `SAME_NONZERO_PATTERN`, `DIFFERENT_NONZERO_PATTERN`,
206:          `SUBSET_NONZERO_PATTERN`, or `UNKNOWN_NONZERO_PATTERN`

208:    Level: advanced

210: .seealso: [](ch:st), `STSetMatStructure()`, `STSetMatrices()`, `MatAXPY()`
211: @*/
212: PetscErrorCode STGetMatStructure(ST st,MatStructure *str)
213: {
214:   PetscFunctionBegin;
216:   PetscAssertPointer(str,2);
217:   *str = st->str;
218:   PetscFunctionReturn(PETSC_SUCCESS);
219: }

221: /*@
222:    STSetMatMode - Sets a flag to indicate how the transformed matrices are
223:    being stored in the spectral transformations.

225:    Logically Collective

227:    Input Parameters:
228: +  st - the spectral transformation context
229: -  mode - the mode

231:    Options Database Key:
232: .  -st_matmode \<mode\> - set the mode, one of `copy`, `inplace`, `shell`

234:    Notes:
235:    By default (`ST_MATMODE_COPY`), a copy of matrix $A$ is made and then
236:    this copy is modified explicitly, e.g., $A \leftarrow A - \sigma B$.

238:    With `ST_MATMODE_INPLACE`, the original matrix $A$ is modified at `STSetUp()`
239:    and changes are reverted at the end of the computations. With respect to
240:    the previous one, this mode avoids a copy of matrix $A$. However, a
241:    drawback is that the recovered matrix might be slightly different
242:    from the original one (due to roundoff).

244:    With `ST_MATMODE_SHELL`, the solver works with an implicit shell
245:    matrix that represents the shifted matrix. This mode is the most efficient
246:    in creating the shifted matrix but it places serious limitations to the
247:    linear solves performed in each iteration of the eigensolver (typically,
248:    only iterative solvers with Jacobi preconditioning can be used).

250:    In the two first modes the efficiency of the computation can be controlled
251:    with `STSetMatStructure()`.

253:    Level: intermediate

255: .seealso: [](ch:st), `STSetMatrices()`, `STSetMatStructure()`, `STGetMatMode()`, `STMatMode`
256: @*/
257: PetscErrorCode STSetMatMode(ST st,STMatMode mode)
258: {
259:   PetscFunctionBegin;
262:   if (st->matmode != mode) {
263:     STCheckNotSeized(st,1);
264:     st->matmode = mode;
265:     st->state   = ST_STATE_INITIAL;
266:     st->opready = PETSC_FALSE;
267:   }
268:   PetscFunctionReturn(PETSC_SUCCESS);
269: }

271: /*@
272:    STGetMatMode - Gets a flag that indicates how the transformed matrices
273:    are stored in spectral transformations.

275:    Not Collective

277:    Input Parameter:
278: .  st - the spectral transformation context

280:    Output Parameter:
281: .  mode - the mode flag

283:    Level: intermediate

285: .seealso: [](ch:st), `STSetMatMode()`, `STMatMode`
286: @*/
287: PetscErrorCode STGetMatMode(ST st,STMatMode *mode)
288: {
289:   PetscFunctionBegin;
291:   PetscAssertPointer(mode,2);
292:   *mode = st->matmode;
293:   PetscFunctionReturn(PETSC_SUCCESS);
294: }

296: /*@
297:    STSetTransform - Sets a flag to indicate whether the transformed matrices are
298:    computed or not.

300:    Logically Collective

302:    Input Parameters:
303: +  st  - the spectral transformation context
304: -  flg - the boolean flag

306:    Options Database Key:
307: .  -st_transform - toggle the computation of matrices

309:    Notes:
310:    This flag is intended for the case of polynomial eigenproblems solved
311:    via linearization. If this flag is off (default) the spectral transformation
312:    is applied to the linearization (handled by the eigensolver), otherwise
313:    it is applied to the original problem.

315:    Level: developer

317: .seealso: [](ch:st), `STMatSolve()`, `STMatMult()`, `STSetMatStructure()`, `STGetTransform()`
318: @*/
319: PetscErrorCode STSetTransform(ST st,PetscBool flg)
320: {
321:   PetscFunctionBegin;
324:   if (st->transform != flg) {
325:     st->transform = flg;
326:     st->state     = ST_STATE_INITIAL;
327:     st->opready   = PETSC_FALSE;
328:   }
329:   PetscFunctionReturn(PETSC_SUCCESS);
330: }

332: /*@
333:    STGetTransform - Gets a flag that indicates whether the transformed
334:    matrices are computed or not.

336:    Not Collective

338:    Input Parameter:
339: .  st - the spectral transformation context

341:    Output Parameter:
342: .  flg - the flag

344:    Level: developer

346: .seealso: [](ch:st), `STSetTransform()`
347: @*/
348: PetscErrorCode STGetTransform(ST st,PetscBool *flg)
349: {
350:   PetscFunctionBegin;
352:   PetscAssertPointer(flg,2);
353:   *flg = st->transform;
354:   PetscFunctionReturn(PETSC_SUCCESS);
355: }

357: /*@
358:    STSetStructured - Sets a flag to indicate that the application of the
359:    operator must be done taking into account its structure.

361:    Logically Collective

363:    Input Parameters:
364: +  st  - the spectral transformation context
365: -  flg - the boolean flag

367:    Note:
368:    This flag is intended for the case of structured eigenproblems. It is set
369:    internally by the solver, the user should not modify its value.

371:    Level: developer

373: .seealso: [](ch:st), `STApply()`, `STGetStructured()`
374: @*/
375: PetscErrorCode STSetStructured(ST st,PetscBool flg)
376: {
377:   PetscFunctionBegin;
380:   if (st->structured != flg) {
381:     st->structured = flg;
382:     st->state      = ST_STATE_INITIAL;
383:     st->opready    = PETSC_FALSE;
384:   }
385:   PetscFunctionReturn(PETSC_SUCCESS);
386: }

388: /*@
389:    STGetStructured - Gets a flag that indicates if the application of the
390:    operator is done using its structure.

392:    Not Collective

394:    Input Parameter:
395: .  st - the spectral transformation context

397:    Output Parameter:
398: .  flg - the flag

400:    Level: developer

402: .seealso: [](ch:st), `STSetStructured()`
403: @*/
404: PetscErrorCode STGetStructured(ST st,PetscBool *flg)
405: {
406:   PetscFunctionBegin;
408:   PetscAssertPointer(flg,2);
409:   *flg = st->structured;
410:   PetscFunctionReturn(PETSC_SUCCESS);
411: }