1: /*
2: MFN routines related to problem setup.
4: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5: SLEPc - Scalable Library for Eigenvalue Problem Computations
6: Copyright (c) 2002-2016, Universitat Politecnica de Valencia, Spain
8: This file is part of SLEPc.
10: SLEPc is free software: you can redistribute it and/or modify it under the
11: terms of version 3 of the GNU Lesser General Public License as published by
12: the Free Software Foundation.
14: SLEPc is distributed in the hope that it will be useful, but WITHOUT ANY
15: WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16: FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
17: more details.
19: You should have received a copy of the GNU Lesser General Public License
20: along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
21: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
22: */
24: #include <slepc/private/mfnimpl.h> /*I "slepcmfn.h" I*/
28: /*@
29: MFNSetUp - Sets up all the internal data structures necessary for the
30: execution of the matrix function solver.
32: Collective on MFN 34: Input Parameter:
35: . mfn - matrix function context
37: Notes:
38: This function need not be called explicitly in most cases, since MFNSolve()
39: calls it. It can be useful when one wants to measure the set-up time
40: separately from the solve time.
42: Level: developer
44: .seealso: MFNCreate(), MFNSolve(), MFNDestroy()
45: @*/
46: PetscErrorCode MFNSetUp(MFN mfn) 47: {
49: PetscInt N;
54: /* reset the convergence flag from the previous solves */
55: mfn->reason = MFN_CONVERGED_ITERATING;
57: if (mfn->setupcalled) return(0);
58: PetscLogEventBegin(MFN_SetUp,mfn,0,0,0);
60: /* Set default solver type (MFNSetFromOptions was not called) */
61: if (!((PetscObject)mfn)->type_name) {
62: MFNSetType(mfn,MFNKRYLOV);
63: }
64: if (!mfn->fn) { MFNGetFN(mfn,&mfn->fn); }
65: if (!((PetscObject)mfn->fn)->type_name) {
66: FNSetFromOptions(mfn->fn);
67: }
69: /* Check problem dimensions */
70: if (!mfn->A) SETERRQ(PetscObjectComm((PetscObject)mfn),PETSC_ERR_ARG_WRONGSTATE,"MFNSetOperator must be called first");
71: MatGetSize(mfn->A,&N,NULL);
72: if (mfn->ncv > N) mfn->ncv = N;
74: /* call specific solver setup */
75: (*mfn->ops->setup)(mfn);
77: /* set tolerance if not yet set */
78: if (mfn->tol==PETSC_DEFAULT) mfn->tol = SLEPC_DEFAULT_TOL;
80: PetscLogEventEnd(MFN_SetUp,mfn,0,0,0);
81: mfn->setupcalled = 1;
82: return(0);
83: }
87: /*@
88: MFNSetOperator - Sets the matrix for which the matrix function is to be computed.
90: Collective on MFN and Mat
92: Input Parameters:
93: + mfn - the matrix function context
94: - A - the problem matrix
96: Notes:
97: It must be called before MFNSetUp(). If it is called again after MFNSetUp() then
98: the MFN object is reset.
100: Level: beginner
102: .seealso: MFNSolve(), MFNSetUp(), MFNReset()
103: @*/
104: PetscErrorCode MFNSetOperator(MFN mfn,Mat A)105: {
107: PetscInt m,n;
114: MatGetSize(A,&m,&n);
115: if (m!=n) SETERRQ(PetscObjectComm((PetscObject)mfn),PETSC_ERR_ARG_WRONG,"A is a non-square matrix");
116: if (mfn->setupcalled) { MFNReset(mfn); }
117: PetscObjectReference((PetscObject)A);
118: MatDestroy(&mfn->A);
119: mfn->A = A;
120: return(0);
121: }
125: /*@
126: MFNGetOperator - Gets the matrix associated with the MFN object.
128: Collective on MFN and Mat
130: Input Parameter:
131: . mfn - the MFN context
133: Output Parameters:
134: . A - the matrix for which the matrix function is to be computed
136: Level: intermediate
138: .seealso: MFNSolve(), MFNSetOperator()
139: @*/
140: PetscErrorCode MFNGetOperator(MFN mfn,Mat *A)141: {
145: *A = mfn->A;
146: return(0);
147: }
151: /*@
152: MFNAllocateSolution - Allocate memory storage for common variables such
153: as the basis vectors.
155: Collective on MFN157: Input Parameters:
158: + mfn - eigensolver context
159: - extra - number of additional positions, used for methods that require a
160: working basis slightly larger than ncv
162: Developers Note:
163: This is PETSC_EXTERN because it may be required by user plugin MFN164: implementations.
166: Level: developer
167: @*/
168: PetscErrorCode MFNAllocateSolution(MFN mfn,PetscInt extra)169: {
171: PetscInt oldsize,requested;
172: Vec t;
175: requested = mfn->ncv + extra;
177: /* oldsize is zero if this is the first time setup is called */
178: BVGetSizes(mfn->V,NULL,NULL,&oldsize);
180: /* allocate basis vectors */
181: if (!mfn->V) { MFNGetBV(mfn,&mfn->V); }
182: if (!oldsize) {
183: if (!((PetscObject)(mfn->V))->type_name) {
184: BVSetType(mfn->V,BVSVEC);
185: }
186: MatCreateVecs(mfn->A,&t,NULL);
187: BVSetSizesFromVec(mfn->V,t,requested);
188: VecDestroy(&t);
189: } else {
190: BVResize(mfn->V,requested,PETSC_FALSE);
191: }
192: return(0);
193: }