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:    Note:
 79:    `type` should not be retained for later use as it will be an invalid pointer
 80:    if the `STType` of `st` is changed.

 82:    Level: intermediate

 84: .seealso: [](ch:st), `STSetType()`, `PetscObjectTypeCompare()`, `PetscObjectTypeCompareAny()`
 85: @*/
 86: PetscErrorCode STGetType(ST st,STType *type)
 87: {
 88:   PetscFunctionBegin;
 90:   PetscAssertPointer(type,2);
 91:   *type = ((PetscObject)st)->type_name;
 92:   PetscFunctionReturn(PETSC_SUCCESS);
 93: }

 95: /*@
 96:    STSetFromOptions - Sets `ST` options from the options database.

 98:    Collective

100:    Input Parameter:
101: .  st - the spectral transformation context

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

106:    Level: beginner

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

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

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

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

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

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

138:     PetscTryTypeMethod(st,setfromoptions,PetscOptionsObject);
139:     PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)st,PetscOptionsObject));
140:   PetscOptionsEnd();

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

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

153:    Logically Collective

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

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

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

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

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

175:    Level: advanced

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

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

201:    Not Collective

203:    Input Parameter:
204: .  st  - the spectral transformation context

206:    Output Parameter:
207: .  str - either `SAME_NONZERO_PATTERN`, `DIFFERENT_NONZERO_PATTERN`,
208:          `SUBSET_NONZERO_PATTERN`, or `UNKNOWN_NONZERO_PATTERN`

210:    Level: advanced

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

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

227:    Logically Collective

229:    Input Parameters:
230: +  st - the spectral transformation context
231: -  mode - the mode

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

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

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

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

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

255:    Level: intermediate

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

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

277:    Not Collective

279:    Input Parameter:
280: .  st - the spectral transformation context

282:    Output Parameter:
283: .  mode - the mode flag

285:    Level: intermediate

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

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

302:    Logically Collective

304:    Input Parameters:
305: +  st  - the spectral transformation context
306: -  flg - the boolean flag

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

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

317:    Level: developer

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

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

338:    Not Collective

340:    Input Parameter:
341: .  st - the spectral transformation context

343:    Output Parameter:
344: .  flg - the flag

346:    Level: developer

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

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

363:    Logically Collective

365:    Input Parameters:
366: +  st  - the spectral transformation context
367: -  flg - the boolean flag

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

373:    Level: developer

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

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

394:    Not Collective

396:    Input Parameter:
397: .  st - the spectral transformation context

399:    Output Parameter:
400: .  flg - the flag

402:    Level: developer

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