Actual source code: setup.c

  1: /*
  2:       EPS routines related to problem setup.
  3: */
 4:  #include src/eps/epsimpl.h

  8: /*@
  9:    EPSSetUp - Sets up all the internal data structures necessary for the
 10:    execution of the eigensolver. Then calls STSetUp() for any set-up
 11:    operations associated to the ST object.

 13:    Collective on EPS

 15:    Input Parameter:
 16: .  eps   - eigenproblem solver context

 18:    Level: advanced

 20:    Notes:
 21:    This function need not be called explicitly in most cases, since EPSSolve()
 22:    calls it. It can be useful when one wants to measure the set-up time 
 23:    separately from the solve time.

 25:    This function sets a random initial vector if none has been provided.

 27: .seealso: EPSCreate(), EPSSolve(), EPSDestroy(), STSetUp()
 28: @*/
 29: PetscErrorCode EPSSetUp(EPS eps)
 30: {
 31:   PetscErrorCode ierr;
 32:   int            i;
 33:   Vec            v0;
 34:   Mat            A,B;
 35: 

 39:   if (eps->setupcalled) return(0);

 41:   PetscLogEventBegin(EPS_SetUp,eps,0,0,0);

 43:   /* Set default solver type */
 44:   if (!eps->type_name) {
 45:     EPSSetType(eps,EPSARNOLDI);
 46:   }

 48:   STGetOperators(eps->OP,&A,&B);
 49:   /* Set default problem type */
 50:   if (!eps->problem_type) {
 51:     if (B==PETSC_NULL) {
 52:       EPSSetProblemType(eps,EPS_NHEP);
 53:     }
 54:     else {
 55:       EPSSetProblemType(eps,EPS_GNHEP);
 56:     }
 57:   } else if ((B && !eps->isgeneralized) || (!B && eps->isgeneralized)) {
 58:     SETERRQ(0,"Warning: Inconsistent EPS state");
 59:   }
 60: 
 61:   /* Check if the EPS initial vector has been set */
 62:   EPSGetInitialVector(eps,&v0);
 63:   if (!eps->vec_initial_set && !v0) {
 64:     MatGetVecs(A,&v0,PETSC_NULL);
 65:     SlepcVecSetRandom(v0);
 66:     eps->vec_initial = v0;
 67:   }

 69:   (*eps->ops->setup)(eps);
 70:   STSetUp(eps->OP);

 72:   /* DSV is equal to the columns of DS followed by the ones in V */
 73:   if (eps->DSV) { PetscFree(eps->DSV); }
 74:   PetscMalloc((eps->ncv+eps->nds)*sizeof(Vec),&eps->DSV);
 75:   for (i = 0; i < eps->nds; i++) eps->DSV[i] = eps->DS[i];
 76:   for (i = 0; i < eps->ncv; i++) eps->DSV[i+eps->nds] = eps->V[i];
 77: 
 78:   if (eps->nds>0) {
 79:     if (!eps->ds_ortho) {
 80:       /* orthonormalize vectors in DS if necessary */
 81:       EPSQRDecomposition(eps,eps->DS,0,eps->nds,PETSC_NULL,0);
 82:     }
 83:     EPSOrthogonalize(eps,eps->nds,eps->DS,eps->vec_initial,PETSC_NULL,PETSC_NULL,PETSC_NULL);
 84:   }

 86:   STCheckNullSpace(eps->OP,eps->nds,eps->DS);
 87: 
 88:   PetscLogEventEnd(EPS_SetUp,eps,0,0,0);
 89:   eps->setupcalled = 1;
 90:   return(0);
 91: }

 95: /*@
 96:    EPSSetInitialVector - Sets the initial vector from which the 
 97:    eigensolver starts to iterate.

 99:    Collective on EPS and Vec

101:    Input Parameters:
102: +  eps - the eigensolver context
103: -  vec - the vector

105:    Level: intermediate

107: .seealso: EPSGetInitialVector()

109: @*/
110: PetscErrorCode EPSSetInitialVector(EPS eps,Vec vec)
111: {
112:   PetscErrorCode ierr;
113: 
118:   if (eps->vec_initial) {
119:     VecDestroy(eps->vec_initial);
120:   }
121:   eps->vec_initial = vec;
122:   PetscObjectReference((PetscObject)eps->vec_initial);
123:   eps->vec_initial_set = PETSC_TRUE;
124:   return(0);
125: }

129: /*@
130:    EPSGetInitialVector - Gets the initial vector associated with the 
131:    eigensolver; if the vector was not set it will return a 0 pointer or
132:    a vector randomly generated by EPSSetUp().

134:    Not collective, but vector is shared by all processors that share the EPS

136:    Input Parameter:
137: .  eps - the eigensolver context

139:    Output Parameter:
140: .  vec - the vector

142:    Level: intermediate

144: .seealso: EPSSetInitialVector()

146: @*/
147: PetscErrorCode EPSGetInitialVector(EPS eps,Vec *vec)
148: {
151:   *vec = eps->vec_initial;
152:   return(0);
153: }

157: /*@
158:    EPSSetOperators - Sets the matrices associated with the eigenvalue problem.

160:    Collective on EPS and Mat

162:    Input Parameters:
163: +  eps - the eigenproblem solver context
164: .  A  - the matrix associated with the eigensystem
165: -  B  - the second matrix in the case of generalized eigenproblems

167:    Notes: 
168:    To specify a standard eigenproblem, use PETSC_NULL for parameter B.

170:    Level: beginner

172: .seealso: EPSSolve(), EPSGetST(), STGetOperators()
173: @*/
174: PetscErrorCode EPSSetOperators(EPS eps,Mat A,Mat B)
175: {
176:   PetscErrorCode ierr;
177:   int            m,n;


184:   /* Check for square matrices */
185:   MatGetSize(A,&m,&n);
186:   if (m!=n) { SETERRQ(1,"A is a non-square matrix"); }
187:   if (B) {
188:     MatGetSize(B,&m,&n);
189:     if (m!=n) { SETERRQ(1,"B is a non-square matrix"); }
190:   }

192:   STSetOperators(eps->OP,A,B);
193:   eps->setupcalled = 0;  /* so that next solve call will call setup */
194:   if (!eps->vec_initial_set && eps->vec_initial) {
195:     VecDestroy(eps->vec_initial);
196:     eps->vec_initial = PETSC_NULL;
197:   }

199:   return(0);
200: }

204: /*@
205:    EPSAttachDeflationSpace - Add vectors to the basis of the deflation space.

207:    Not Collective

209:    Input Parameter:
210: +  eps   - the eigenproblem solver context
211: .  n     - number of vectors to add
212: .  ds    - set of basis vectors of the deflation space
213: -  ortho - PETSC_TRUE if basis vectors of deflation space are orthonormal

215:    Notes:
216:    When a deflation space is given, the eigensolver seeks the eigensolution
217:    in the restriction of the problem to the orthogonal complement of this
218:    space. This can be used for instance in the case that an invariant 
219:    subspace is known beforehand (such as the nullspace of the matrix).

221:    The basis vectors can be provided all at once or incrementally with
222:    several calls to EPSAttachDeflationSpace().

224:    Use a value of PETSC_TRUE for parameter ortho if all the vectors passed
225:    in are known to be mutually orthonormal.

227:    Level: intermediate

229: .seealso: EPSRemoveDeflationSpace()
230: @*/
231: PetscErrorCode EPSAttachDeflationSpace(EPS eps,int n,Vec *ds,PetscTruth ortho)
232: {
233:   PetscErrorCode ierr;
234:   int            i;
235:   Vec            *tvec;
236: 
239:   tvec = eps->DS;
240:   if (n+eps->nds > 0) {
241:      PetscMalloc((n+eps->nds)*sizeof(Vec), &eps->DS);
242:   }
243:   if (eps->nds > 0) {
244:     for (i=0; i<eps->nds; i++) eps->DS[i] = tvec[i];
245:     PetscFree(tvec);
246:   }
247:   for (i=0; i<n; i++) {
248:     VecDuplicate(ds[i],&eps->DS[i + eps->nds]);
249:     VecCopy(ds[i],eps->DS[i + eps->nds]);
250:   }
251:   eps->nds += n;
252:   if (!ortho) eps->ds_ortho = PETSC_FALSE;
253:   eps->setupcalled = 0;
254:   return(0);
255: }

259: /*@
260:    EPSRemoveDeflationSpace - Removes the deflation space.

262:    Not Collective

264:    Input Parameter:
265: .  eps   - the eigenproblem solver context

267:    Level: intermediate

269: .seealso: EPSAttachDeflationSpace()
270: @*/
271: PetscErrorCode EPSRemoveDeflationSpace(EPS eps)
272: {
273:   PetscErrorCode ierr;
274: 
277:   if (eps->nds > 0) {
278:     VecDestroyVecs(eps->DS, eps->nds);
279:   }
280:   eps->ds_ortho = PETSC_TRUE;
281:   eps->setupcalled = 0;
282:   return(0);
283: }