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()`
 40: @*/
 41: PetscErrorCode STSetType(ST st,STType type)
 42: {
 43:   PetscErrorCode (*r)(ST);
 44:   PetscBool      match;

 46:   PetscFunctionBegin;
 48:   PetscAssertPointer(type,2);

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

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

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

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

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

 70:    Not Collective

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

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

 78:    Level: intermediate

 80: .seealso: [](ch:st), `STSetType()`
 81: @*/
 82: PetscErrorCode STGetType(ST st,STType *type)
 83: {
 84:   PetscFunctionBegin;
 86:   PetscAssertPointer(type,2);
 87:   *type = ((PetscObject)st)->type_name;
 88:   PetscFunctionReturn(PETSC_SUCCESS);
 89: }

 91: /*@
 92:    STSetFromOptions - Sets `ST` options from the options database.

 94:    Collective

 96:    Input Parameter:
 97: .  st - the spectral transformation context

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

102:    Level: beginner

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

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

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

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

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

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

134:     PetscTryTypeMethod(st,setfromoptions,PetscOptionsObject);
135:     PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)st,PetscOptionsObject));
136:   PetscOptionsEnd();

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

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

149:    Logically Collective

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

156:    Options Database Key:
157: .  -st_matstructure (same|different|subset|unknown) - set the structure flag

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

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

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

171:    Level: advanced

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

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

197:    Not Collective

199:    Input Parameter:
200: .  st  - the spectral transformation context

202:    Output Parameter:
203: .  str - either `SAME_NONZERO_PATTERN`, `DIFFERENT_NONZERO_PATTERN`,
204:          `SUBSET_NONZERO_PATTERN`, or `UNKNOWN_NONZERO_PATTERN`

206:    Level: advanced

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

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

223:    Logically Collective

225:    Input Parameters:
226: +  st - the spectral transformation context
227: -  mode - the mode

229:    Options Database Key:
230: .  -st_matmode (copy|inplace|shell) - set the mode

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

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

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

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

251:    Level: intermediate

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

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

273:    Not Collective

275:    Input Parameter:
276: .  st - the spectral transformation context

278:    Output Parameter:
279: .  mode - the mode flag

281:    Level: intermediate

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

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

298:    Logically Collective

300:    Input Parameters:
301: +  st  - the spectral transformation context
302: -  flg - the boolean flag

304:    Options Database Key:
305: .  -st_transform (true|false) - toggle the computation of matrices

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

313:    Level: developer

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

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

334:    Not Collective

336:    Input Parameter:
337: .  st - the spectral transformation context

339:    Output Parameter:
340: .  flg - the flag

342:    Level: developer

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

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

359:    Logically Collective

361:    Input Parameters:
362: +  st  - the spectral transformation context
363: -  flg - the boolean flag

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

369:    Level: developer

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

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

390:    Not Collective

392:    Input Parameter:
393: .  st - the spectral transformation context

395:    Output Parameter:
396: .  flg - the flag

398:    Level: developer

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