Subversion Repositories slepc-dev

Rev

Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1324 slepc 1
/*                      
2
 
3
   SLEPc singular value solver: "cyclic"
4
 
1325 slepc 5
   Method: Uses a Hermitian eigensolver for H(A) = [ 0  A ; A^T 0 ]
1324 slepc 6
 
1397 slepc 7
   Last update: Jun 2007
1324 slepc 8
 
1376 slepc 9
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1672 slepc 10
   SLEPc - Scalable Library for Eigenvalue Problem Computations
2575 eromero 11
   Copyright (c) 2002-2011, Universitat Politecnica de Valencia, Spain
1376 slepc 12
 
1672 slepc 13
   This file is part of SLEPc.
14
 
15
   SLEPc is free software: you can redistribute it and/or modify it under  the
16
   terms of version 3 of the GNU Lesser General Public License as published by
17
   the Free Software Foundation.
18
 
19
   SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
20
   WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
21
   FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
22
   more details.
23
 
24
   You  should have received a copy of the GNU Lesser General  Public  License
25
   along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
1376 slepc 26
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1324 slepc 27
*/
1376 slepc 28
 
2729 jroman 29
#include <slepc-private/svdimpl.h>                /*I "slepcsvd.h" I*/
30
#include <slepc-private/epsimpl.h>                /*I "slepceps.h" I*/
1324 slepc 31
 
32
typedef struct {
2216 jroman 33
  PetscBool explicitmatrix;
34
  EPS       eps;
35
  PetscBool setfromoptionscalled;
36
  Mat       mat;
37
  Vec       x1,x2,y1,y2;
1324 slepc 38
} SVD_CYCLIC;
39
 
40
#undef __FUNCT__  
2324 jroman 41
#define __FUNCT__ "ShellMatMult_Cyclic"
2331 jroman 42
static PetscErrorCode ShellMatMult_Cyclic(Mat B,Vec x,Vec y)
1324 slepc 43
{
2334 jroman 44
  PetscErrorCode    ierr;
45
  SVD               svd;
46
  SVD_CYCLIC        *cyclic;
47
  const PetscScalar *px;
48
  PetscScalar       *py;
49
  PetscInt          m;
1324 slepc 50
 
51
  PetscFunctionBegin;
52
  ierr = MatShellGetContext(B,(void**)&svd);CHKERRQ(ierr);
2350 jroman 53
  cyclic = (SVD_CYCLIC*)svd->data;
1324 slepc 54
  ierr = SVDMatGetLocalSize(svd,&m,PETSC_NULL);CHKERRQ(ierr);
2334 jroman 55
  ierr = VecGetArrayRead(x,&px);CHKERRQ(ierr);
1324 slepc 56
  ierr = VecGetArray(y,&py);CHKERRQ(ierr);
57
  ierr = VecPlaceArray(cyclic->x1,px);CHKERRQ(ierr);
58
  ierr = VecPlaceArray(cyclic->x2,px+m);CHKERRQ(ierr);
59
  ierr = VecPlaceArray(cyclic->y1,py);CHKERRQ(ierr);
60
  ierr = VecPlaceArray(cyclic->y2,py+m);CHKERRQ(ierr);
61
  ierr = SVDMatMult(svd,PETSC_FALSE,cyclic->x2,cyclic->y1);CHKERRQ(ierr);
62
  ierr = SVDMatMult(svd,PETSC_TRUE,cyclic->x1,cyclic->y2);CHKERRQ(ierr);        
63
  ierr = VecResetArray(cyclic->x1);CHKERRQ(ierr);
64
  ierr = VecResetArray(cyclic->x2);CHKERRQ(ierr);
65
  ierr = VecResetArray(cyclic->y1);CHKERRQ(ierr);
66
  ierr = VecResetArray(cyclic->y2);CHKERRQ(ierr);
2334 jroman 67
  ierr = VecRestoreArrayRead(x,&px);CHKERRQ(ierr);
1324 slepc 68
  ierr = VecRestoreArray(y,&py);CHKERRQ(ierr);
69
  PetscFunctionReturn(0);
70
}
71
 
72
#undef __FUNCT__  
2324 jroman 73
#define __FUNCT__ "ShellMatGetDiagonal_Cyclic"
74
static PetscErrorCode ShellMatGetDiagonal_Cyclic(Mat B,Vec diag)
1324 slepc 75
{
76
  PetscErrorCode ierr;
77
 
78
  PetscFunctionBegin;
79
  ierr = VecSet(diag,0.0);CHKERRQ(ierr);
80
  PetscFunctionReturn(0);
81
}
82
 
83
#undef __FUNCT__  
2324 jroman 84
#define __FUNCT__ "SVDSetUp_Cyclic"
85
PetscErrorCode SVDSetUp_Cyclic(SVD svd)
1324 slepc 86
{
2334 jroman 87
  PetscErrorCode    ierr;
2350 jroman 88
  SVD_CYCLIC        *cyclic = (SVD_CYCLIC*)svd->data;
2410 jroman 89
  PetscInt          M,N,m,n,i,isl;
2334 jroman 90
  const PetscScalar *isa;
2343 jroman 91
  PetscScalar       *va;
2334 jroman 92
  PetscBool         trackall;
2410 jroman 93
  Vec               v;
2334 jroman 94
  Mat               Zm,Zn;
1324 slepc 95
 
96
  PetscFunctionBegin;
97
  ierr = SVDMatGetSize(svd,&M,&N);CHKERRQ(ierr);
98
  ierr = SVDMatGetLocalSize(svd,&m,&n);CHKERRQ(ierr);
2520 jroman 99
  if (!cyclic->mat) {
100
    if (cyclic->explicitmatrix) {
101
      if (!svd->AT) SETERRQ(((PetscObject)svd)->comm,PETSC_ERR_SUP,"Cannot use explicit cyclic matrix with implicit transpose");
102
      ierr = MatCreate(((PetscObject)svd)->comm,&Zm);CHKERRQ(ierr);
103
      ierr = MatSetSizes(Zm,m,m,M,M);CHKERRQ(ierr);
104
      ierr = MatSetFromOptions(Zm);CHKERRQ(ierr);
2717 jroman 105
      ierr = MatSetUp(Zm);CHKERRQ(ierr);
2520 jroman 106
      ierr = MatAssemblyBegin(Zm,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
107
      ierr = MatAssemblyEnd(Zm,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
108
      ierr = MatCreate(((PetscObject)svd)->comm,&Zn);CHKERRQ(ierr);
109
      ierr = MatSetSizes(Zn,n,n,N,N);CHKERRQ(ierr);
110
      ierr = MatSetFromOptions(Zn);CHKERRQ(ierr);
2717 jroman 111
      ierr = MatSetUp(Zn);CHKERRQ(ierr);
2520 jroman 112
      ierr = MatAssemblyBegin(Zn,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
113
      ierr = MatAssemblyEnd(Zn,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
114
      ierr = SlepcMatTile(0.0,Zm,1.0,svd->A,1.0,svd->AT,0.0,Zn,&cyclic->mat);CHKERRQ(ierr);
115
      ierr = MatDestroy(&Zm);CHKERRQ(ierr);
116
      ierr = MatDestroy(&Zn);CHKERRQ(ierr);
117
    } else {
118
      ierr = VecCreateMPIWithArray(((PetscObject)svd)->comm,m,M,PETSC_NULL,&cyclic->x1);CHKERRQ(ierr);
119
      ierr = VecCreateMPIWithArray(((PetscObject)svd)->comm,n,N,PETSC_NULL,&cyclic->x2);CHKERRQ(ierr);
120
      ierr = VecCreateMPIWithArray(((PetscObject)svd)->comm,m,M,PETSC_NULL,&cyclic->y1);CHKERRQ(ierr);
121
      ierr = VecCreateMPIWithArray(((PetscObject)svd)->comm,n,N,PETSC_NULL,&cyclic->y2);CHKERRQ(ierr);
122
      ierr = MatCreateShell(((PetscObject)svd)->comm,m+n,m+n,M+N,M+N,svd,&cyclic->mat);CHKERRQ(ierr);
123
      ierr = MatShellSetOperation(cyclic->mat,MATOP_MULT,(void(*)(void))ShellMatMult_Cyclic);CHKERRQ(ierr);  
124
      ierr = MatShellSetOperation(cyclic->mat,MATOP_GET_DIAGONAL,(void(*)(void))ShellMatGetDiagonal_Cyclic);CHKERRQ(ierr);  
125
    }
1324 slepc 126
  }
127
 
128
  ierr = EPSSetOperators(cyclic->eps,cyclic->mat,PETSC_NULL);CHKERRQ(ierr);
129
  ierr = EPSSetProblemType(cyclic->eps,EPS_HEP);CHKERRQ(ierr);
1406 slepc 130
  ierr = EPSSetWhichEigenpairs(cyclic->eps,svd->which == SVD_LARGEST ? EPS_LARGEST_REAL : EPS_SMALLEST_MAGNITUDE);CHKERRQ(ierr);
1575 slepc 131
  ierr = EPSSetDimensions(cyclic->eps,svd->nsv,svd->ncv,svd->mpd);CHKERRQ(ierr);
1324 slepc 132
  ierr = EPSSetTolerances(cyclic->eps,svd->tol,svd->max_it);CHKERRQ(ierr);
2055 eromero 133
  /* Transfer the trackall option from svd to eps */
134
  ierr = SVDGetTrackAll(svd,&trackall);CHKERRQ(ierr);
135
  ierr = EPSSetTrackAll(cyclic->eps,trackall);CHKERRQ(ierr);
2079 eromero 136
  /* Transfer the initial subspace from svd to eps */
137
  if (svd->nini < 0) {
138
    for (i=0; i<-svd->nini; i++) {
139
      ierr = MatGetVecs(cyclic->mat,&v,PETSC_NULL);CHKERRQ(ierr);
140
      ierr = VecGetArray(v,&va);CHKERRQ(ierr);
2334 jroman 141
      ierr = VecGetArrayRead(svd->IS[i],&isa);CHKERRQ(ierr);
2079 eromero 142
      ierr = VecGetSize(svd->IS[i],&isl);CHKERRQ(ierr);
143
      if (isl == m) {
144
        ierr = PetscMemcpy(va,isa,sizeof(PetscScalar)*m);CHKERRQ(ierr);
145
        ierr = PetscMemzero(&va[m],sizeof(PetscScalar)*n);CHKERRQ(ierr);
146
      } else if (isl == n) {
147
        ierr = PetscMemzero(va,sizeof(PetscScalar)*m);CHKERRQ(ierr);
148
        ierr = PetscMemcpy(&va[m],isa,sizeof(PetscScalar)*n);CHKERRQ(ierr);
149
      } else {
2214 jroman 150
        SETERRQ(((PetscObject)svd)->comm,PETSC_ERR_SUP,"Size of the initial subspace vectors should match to some dimension of A");
2079 eromero 151
      }
152
      ierr = VecRestoreArray(v,&va);CHKERRQ(ierr);
2334 jroman 153
      ierr = VecRestoreArrayRead(svd->IS[i],&isa);CHKERRQ(ierr);
2305 jroman 154
      ierr = VecDestroy(&svd->IS[i]);CHKERRQ(ierr);
2079 eromero 155
      svd->IS[i] = v;
156
    }
157
    ierr = EPSSetInitialSpace(cyclic->eps,-svd->nini,svd->IS);CHKERRQ(ierr);
158
    for (i=0; i<-svd->nini; i++) {
2305 jroman 159
      ierr = VecDestroy(&svd->IS[i]);CHKERRQ(ierr);
2079 eromero 160
    }
161
    ierr = PetscFree(svd->IS);CHKERRQ(ierr);
162
    svd->nini = 0;
163
  }
2177 jroman 164
  if (cyclic->setfromoptionscalled) {
2024 eromero 165
    ierr = EPSSetFromOptions(cyclic->eps);CHKERRQ(ierr);
166
    cyclic->setfromoptionscalled = PETSC_FALSE;
167
  }
1324 slepc 168
  ierr = EPSSetUp(cyclic->eps);CHKERRQ(ierr);
1575 slepc 169
  ierr = EPSGetDimensions(cyclic->eps,PETSC_NULL,&svd->ncv,&svd->mpd);CHKERRQ(ierr);
2390 jroman 170
  svd->ncv = PetscMin(svd->ncv,PetscMin(M,N));
1324 slepc 171
  ierr = EPSGetTolerances(cyclic->eps,&svd->tol,&svd->max_it);CHKERRQ(ierr);
172
 
1605 slepc 173
  if (svd->ncv != svd->n) {
2410 jroman 174
    ierr = VecDestroyVecs(svd->n,&svd->U);CHKERRQ(ierr);
175
    ierr = VecDuplicateVecs(svd->tl,svd->ncv,&svd->U);CHKERRQ(ierr);
1324 slepc 176
  }
177
  PetscFunctionReturn(0);
178
}
179
 
180
#undef __FUNCT__  
2324 jroman 181
#define __FUNCT__ "SVDSolve_Cyclic"
182
PetscErrorCode SVDSolve_Cyclic(SVD svd)
1324 slepc 183
{
2334 jroman 184
  PetscErrorCode    ierr;
2350 jroman 185
  SVD_CYCLIC        *cyclic = (SVD_CYCLIC*)svd->data;
2334 jroman 186
  PetscInt          i,j,M,N,m,n;
187
  PetscScalar       sigma;
188
  const PetscScalar *px;
189
  Vec               x,x1,x2;
1324 slepc 190
 
191
  PetscFunctionBegin;
192
  ierr = EPSSolve(cyclic->eps);CHKERRQ(ierr);
193
  ierr = EPSGetConverged(cyclic->eps,&svd->nconv);CHKERRQ(ierr);
194
  ierr = EPSGetIterationNumber(cyclic->eps,&svd->its);CHKERRQ(ierr);
195
  ierr = EPSGetConvergedReason(cyclic->eps,(EPSConvergedReason*)&svd->reason);CHKERRQ(ierr);
196
 
197
  ierr = MatGetVecs(cyclic->mat,&x,PETSC_NULL);CHKERRQ(ierr);
2297 jroman 198
  ierr = SVDMatGetSize(svd,&M,&N);CHKERRQ(ierr);
199
  ierr = SVDMatGetLocalSize(svd,&m,&n);CHKERRQ(ierr);
200
  ierr = VecCreateMPIWithArray(((PetscObject)svd)->comm,m,M,PETSC_NULL,&x1);CHKERRQ(ierr);
201
  ierr = VecCreateMPIWithArray(((PetscObject)svd)->comm,n,N,PETSC_NULL,&x2);CHKERRQ(ierr);
202
  for (i=0,j=0;i<svd->nconv;i++) {
203
    ierr = EPSGetEigenpair(cyclic->eps,i,&sigma,PETSC_NULL,x,PETSC_NULL);CHKERRQ(ierr);
204
    if (PetscRealPart(sigma) > 0.0) {
205
      svd->sigma[j] = PetscRealPart(sigma);
2334 jroman 206
      ierr = VecGetArrayRead(x,&px);CHKERRQ(ierr);
2297 jroman 207
      ierr = VecPlaceArray(x1,px);CHKERRQ(ierr);
208
      ierr = VecPlaceArray(x2,px+m);CHKERRQ(ierr);
209
      ierr = VecCopy(x1,svd->U[j]);CHKERRQ(ierr);
2473 jroman 210
      ierr = VecScale(svd->U[j],1.0/PetscSqrtReal(2.0));CHKERRQ(ierr);
2297 jroman 211
      ierr = VecCopy(x2,svd->V[j]);CHKERRQ(ierr);
2473 jroman 212
      ierr = VecScale(svd->V[j],1.0/PetscSqrtReal(2.0));CHKERRQ(ierr);
2297 jroman 213
      ierr = VecResetArray(x1);CHKERRQ(ierr);
214
      ierr = VecResetArray(x2);CHKERRQ(ierr);
2334 jroman 215
      ierr = VecRestoreArrayRead(x,&px);CHKERRQ(ierr);
2297 jroman 216
      j++;
1324 slepc 217
    }
218
  }
219
  svd->nconv = j;
220
 
2305 jroman 221
  ierr = VecDestroy(&x);CHKERRQ(ierr);
222
  ierr = VecDestroy(&x1);CHKERRQ(ierr);
223
  ierr = VecDestroy(&x2);CHKERRQ(ierr);
1324 slepc 224
  PetscFunctionReturn(0);
225
}
226
 
227
#undef __FUNCT__  
2324 jroman 228
#define __FUNCT__ "SVDMonitor_Cyclic"
2382 jroman 229
static PetscErrorCode SVDMonitor_Cyclic(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,void *ctx)
1324 slepc 230
{
2054 eromero 231
  PetscInt       i,j;
232
  SVD            svd = (SVD)ctx;
233
  PetscScalar    er,ei;
234
  PetscErrorCode ierr;
1324 slepc 235
 
236
  PetscFunctionBegin;
237
  nconv = 0;
2605 eromero 238
  for (i=0,j=0;i<PetscMin(nest,svd->ncv);i++) {
2054 eromero 239
    er = eigr[i]; ei = eigi[i];
2331 jroman 240
    ierr = STBackTransform(eps->OP,1,&er,&ei);CHKERRQ(ierr);
2054 eromero 241
    if (PetscRealPart(er) > 0.0) {
242
      svd->sigma[j] = PetscRealPart(er);
1324 slepc 243
      svd->errest[j] = errest[i];
244
      if (errest[i] < svd->tol) nconv++;
245
      j++;
246
    }
247
  }
248
  nest = j;
2313 jroman 249
  ierr = SVDMonitor(svd,its,nconv,svd->sigma,svd->errest,nest);CHKERRQ(ierr);
1324 slepc 250
  PetscFunctionReturn(0);
251
}
252
 
253
#undef __FUNCT__  
2324 jroman 254
#define __FUNCT__ "SVDSetFromOptions_Cyclic"
255
PetscErrorCode SVDSetFromOptions_Cyclic(SVD svd)
1324 slepc 256
{
257
  PetscErrorCode ierr;
2216 jroman 258
  PetscBool      set,val;
2350 jroman 259
  SVD_CYCLIC     *cyclic = (SVD_CYCLIC*)svd->data;
1324 slepc 260
  ST             st;
261
 
262
  PetscFunctionBegin;
2388 jroman 263
  cyclic->setfromoptionscalled = PETSC_TRUE;
2384 jroman 264
  ierr = PetscOptionsHead("SVD Cyclic Options");CHKERRQ(ierr);
2216 jroman 265
  ierr = PetscOptionsBool("-svd_cyclic_explicitmatrix","Use cyclic explicit matrix","SVDCyclicSetExplicitMatrix",cyclic->explicitmatrix,&val,&set);CHKERRQ(ierr);
1923 jroman 266
  if (set) {
267
    ierr = SVDCyclicSetExplicitMatrix(svd,val);CHKERRQ(ierr);
268
  }
2297 jroman 269
  if (!cyclic->explicitmatrix) {
1324 slepc 270
    /* use as default an ST with shell matrix and Jacobi */
271
    ierr = EPSGetST(cyclic->eps,&st);CHKERRQ(ierr);
1940 jroman 272
    ierr = STSetMatMode(st,ST_MATMODE_SHELL);CHKERRQ(ierr);
1324 slepc 273
  }
2384 jroman 274
  ierr = PetscOptionsTail();CHKERRQ(ierr);
1324 slepc 275
  PetscFunctionReturn(0);
276
}
277
 
278
EXTERN_C_BEGIN
279
#undef __FUNCT__  
2324 jroman 280
#define __FUNCT__ "SVDCyclicSetExplicitMatrix_Cyclic"
281
PetscErrorCode SVDCyclicSetExplicitMatrix_Cyclic(SVD svd,PetscBool explicitmatrix)
1324 slepc 282
{
2350 jroman 283
  SVD_CYCLIC *cyclic = (SVD_CYCLIC*)svd->data;
1324 slepc 284
 
285
  PetscFunctionBegin;
1370 slepc 286
  cyclic->explicitmatrix = explicitmatrix;
1324 slepc 287
  PetscFunctionReturn(0);
288
}
1370 slepc 289
EXTERN_C_END
1324 slepc 290
 
291
#undef __FUNCT__
292
#define __FUNCT__ "SVDCyclicSetExplicitMatrix"
293
/*@
1325 slepc 294
   SVDCyclicSetExplicitMatrix - Indicate if the eigensolver operator
1324 slepc 295
   H(A) = [ 0  A ; A^T 0 ] must be computed explicitly.
296
 
2328 jroman 297
   Logically Collective on SVD
1324 slepc 298
 
299
   Input Parameters:
300
+  svd      - singular value solver
1325 slepc 301
-  explicit - boolean flag indicating if H(A) is built explicitly
1324 slepc 302
 
303
   Options Database Key:
304
.  -svd_cyclic_explicitmatrix <boolean> - Indicates the boolean flag
305
 
1325 slepc 306
   Level: advanced
1324 slepc 307
 
308
.seealso: SVDCyclicGetExplicitMatrix()
309
@*/
2216 jroman 310
PetscErrorCode SVDCyclicSetExplicitMatrix(SVD svd,PetscBool explicitmatrix)
1324 slepc 311
{
2221 jroman 312
  PetscErrorCode ierr;
1324 slepc 313
 
314
  PetscFunctionBegin;
2213 jroman 315
  PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
2326 jroman 316
  PetscValidLogicalCollectiveBool(svd,explicitmatrix,2);
2221 jroman 317
  ierr = PetscTryMethod(svd,"SVDCyclicSetExplicitMatrix_C",(SVD,PetscBool),(svd,explicitmatrix));CHKERRQ(ierr);
1324 slepc 318
  PetscFunctionReturn(0);
319
}
320
 
321
EXTERN_C_BEGIN
322
#undef __FUNCT__  
2324 jroman 323
#define __FUNCT__ "SVDCyclicGetExplicitMatrix_Cyclic"
324
PetscErrorCode SVDCyclicGetExplicitMatrix_Cyclic(SVD svd,PetscBool *explicitmatrix)
1324 slepc 325
{
2350 jroman 326
  SVD_CYCLIC *cyclic = (SVD_CYCLIC*)svd->data;
1324 slepc 327
 
328
  PetscFunctionBegin;
1370 slepc 329
  *explicitmatrix = cyclic->explicitmatrix;
1324 slepc 330
  PetscFunctionReturn(0);
331
}
1370 slepc 332
EXTERN_C_END
1324 slepc 333
 
334
#undef __FUNCT__
335
#define __FUNCT__ "SVDCyclicGetExplicitMatrix"
2061 eromero 336
/*@
1325 slepc 337
   SVDCyclicGetExplicitMatrix - Returns the flag indicating if H(A) is built explicitly
338
 
2328 jroman 339
   Not Collective
1324 slepc 340
 
341
   Input Parameter:
342
.  svd  - singular value solver
343
 
344
   Output Parameter:
345
.  explicit - the mode flag
346
 
1325 slepc 347
   Level: advanced
1324 slepc 348
 
349
.seealso: SVDCyclicSetExplicitMatrix()
350
@*/
2216 jroman 351
PetscErrorCode SVDCyclicGetExplicitMatrix(SVD svd,PetscBool *explicitmatrix)
1324 slepc 352
{
2221 jroman 353
  PetscErrorCode ierr;
1324 slepc 354
 
355
  PetscFunctionBegin;
2213 jroman 356
  PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
2326 jroman 357
  PetscValidPointer(explicitmatrix,2);
2221 jroman 358
  ierr = PetscTryMethod(svd,"SVDCyclicGetExplicitMatrix_C",(SVD,PetscBool*),(svd,explicitmatrix));CHKERRQ(ierr);
1324 slepc 359
  PetscFunctionReturn(0);
360
}
361
 
362
EXTERN_C_BEGIN
363
#undef __FUNCT__  
2324 jroman 364
#define __FUNCT__ "SVDCyclicSetEPS_Cyclic"
365
PetscErrorCode SVDCyclicSetEPS_Cyclic(SVD svd,EPS eps)
1324 slepc 366
{
367
  PetscErrorCode  ierr;
2350 jroman 368
  SVD_CYCLIC      *cyclic = (SVD_CYCLIC*)svd->data;
1324 slepc 369
 
370
  PetscFunctionBegin;
371
  ierr = PetscObjectReference((PetscObject)eps);CHKERRQ(ierr);
2308 jroman 372
  ierr = EPSDestroy(&cyclic->eps);CHKERRQ(ierr);  
1324 slepc 373
  cyclic->eps = eps;
2327 jroman 374
  ierr = PetscLogObjectParent(svd,cyclic->eps);CHKERRQ(ierr);
1324 slepc 375
  svd->setupcalled = 0;
376
  PetscFunctionReturn(0);
377
}
378
EXTERN_C_END
379
 
380
#undef __FUNCT__  
381
#define __FUNCT__ "SVDCyclicSetEPS"
382
/*@
1325 slepc 383
   SVDCyclicSetEPS - Associate an eigensolver object (EPS) to the
1324 slepc 384
   singular value solver.
385
 
386
   Collective on SVD
387
 
388
   Input Parameters:
389
+  svd - singular value solver
390
-  eps - the eigensolver object
391
 
392
   Level: advanced
393
 
394
.seealso: SVDCyclicGetEPS()
395
@*/
396
PetscErrorCode SVDCyclicSetEPS(SVD svd,EPS eps)
397
{
2221 jroman 398
  PetscErrorCode ierr;
1324 slepc 399
 
400
  PetscFunctionBegin;
2213 jroman 401
  PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
2221 jroman 402
  PetscValidHeaderSpecific(eps,EPS_CLASSID,2);
2326 jroman 403
  PetscCheckSameComm(svd,1,eps,2);
2221 jroman 404
  ierr = PetscTryMethod(svd,"SVDCyclicSetEPS_C",(SVD,EPS),(svd,eps));CHKERRQ(ierr);
1324 slepc 405
  PetscFunctionReturn(0);
406
}
407
 
408
EXTERN_C_BEGIN
409
#undef __FUNCT__  
2324 jroman 410
#define __FUNCT__ "SVDCyclicGetEPS_Cyclic"
411
PetscErrorCode SVDCyclicGetEPS_Cyclic(SVD svd,EPS *eps)
1324 slepc 412
{
2350 jroman 413
  SVD_CYCLIC *cyclic = (SVD_CYCLIC*)svd->data;
1324 slepc 414
 
415
  PetscFunctionBegin;
416
  *eps = cyclic->eps;
417
  PetscFunctionReturn(0);
418
}
419
EXTERN_C_END
420
 
421
#undef __FUNCT__  
422
#define __FUNCT__ "SVDCyclicGetEPS"
2061 eromero 423
/*@
1324 slepc 424
   SVDCyclicGetEPS - Retrieve the eigensolver object (EPS) associated
425
   to the singular value solver.
426
 
427
   Not Collective
428
 
1325 slepc 429
   Input Parameter:
1324 slepc 430
.  svd - singular value solver
431
 
432
   Output Parameter:
433
.  eps - the eigensolver object
434
 
435
   Level: advanced
436
 
437
.seealso: SVDCyclicSetEPS()
438
@*/
439
PetscErrorCode SVDCyclicGetEPS(SVD svd,EPS *eps)
440
{
2221 jroman 441
  PetscErrorCode ierr;
1324 slepc 442
 
443
  PetscFunctionBegin;
2213 jroman 444
  PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
2326 jroman 445
  PetscValidPointer(eps,2);
2221 jroman 446
  ierr = PetscTryMethod(svd,"SVDCyclicGetEPS_C",(SVD,EPS*),(svd,eps));CHKERRQ(ierr);
1324 slepc 447
  PetscFunctionReturn(0);
448
}
449
 
450
#undef __FUNCT__  
2324 jroman 451
#define __FUNCT__ "SVDView_Cyclic"
452
PetscErrorCode SVDView_Cyclic(SVD svd,PetscViewer viewer)
1324 slepc 453
{
2317 jroman 454
  PetscErrorCode ierr;
2350 jroman 455
  SVD_CYCLIC     *cyclic = (SVD_CYCLIC*)svd->data;
1324 slepc 456
 
457
  PetscFunctionBegin;
2367 jroman 458
  ierr = PetscViewerASCIIPrintf(viewer,"  Cyclic: %s matrix\n",cyclic->explicitmatrix?"explicit":"implicit");CHKERRQ(ierr);
459
  ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1324 slepc 460
  ierr = EPSView(cyclic->eps,viewer);CHKERRQ(ierr);
2367 jroman 461
  ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1324 slepc 462
  PetscFunctionReturn(0);
463
}
464
 
465
#undef __FUNCT__  
2350 jroman 466
#define __FUNCT__ "SVDReset_Cyclic"
467
PetscErrorCode SVDReset_Cyclic(SVD svd)
1324 slepc 468
{
2317 jroman 469
  PetscErrorCode ierr;
2350 jroman 470
  SVD_CYCLIC     *cyclic = (SVD_CYCLIC*)svd->data;
1324 slepc 471
 
472
  PetscFunctionBegin;
2350 jroman 473
  ierr = EPSReset(cyclic->eps);CHKERRQ(ierr);
2305 jroman 474
  ierr = MatDestroy(&cyclic->mat);CHKERRQ(ierr);
475
  ierr = VecDestroy(&cyclic->x1);CHKERRQ(ierr);
476
  ierr = VecDestroy(&cyclic->x2);CHKERRQ(ierr);
477
  ierr = VecDestroy(&cyclic->y1);CHKERRQ(ierr);
478
  ierr = VecDestroy(&cyclic->y2);CHKERRQ(ierr);
2350 jroman 479
  PetscFunctionReturn(0);
480
}
481
 
482
#undef __FUNCT__  
483
#define __FUNCT__ "SVDDestroy_Cyclic"
484
PetscErrorCode SVDDestroy_Cyclic(SVD svd)
485
{
486
  PetscErrorCode ierr;
487
  SVD_CYCLIC     *cyclic = (SVD_CYCLIC*)svd->data;
488
 
489
  PetscFunctionBegin;
490
  ierr = EPSDestroy(&cyclic->eps);CHKERRQ(ierr);
1396 slepc 491
  ierr = PetscFree(svd->data);CHKERRQ(ierr);
1925 jroman 492
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDCyclicSetEPS_C","",PETSC_NULL);CHKERRQ(ierr);
493
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDCyclicGetEPS_C","",PETSC_NULL);CHKERRQ(ierr);
494
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDCyclicSetExplicitMatrix_C","",PETSC_NULL);CHKERRQ(ierr);
495
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDCyclicGetExplicitMatrix_C","",PETSC_NULL);CHKERRQ(ierr);
1324 slepc 496
  PetscFunctionReturn(0);
497
}
498
 
499
EXTERN_C_BEGIN
500
#undef __FUNCT__  
2324 jroman 501
#define __FUNCT__ "SVDCreate_Cyclic"
502
PetscErrorCode SVDCreate_Cyclic(SVD svd)
1324 slepc 503
{
2317 jroman 504
  PetscErrorCode ierr;
505
  SVD_CYCLIC     *cyclic;
1324 slepc 506
 
507
  PetscFunctionBegin;
2329 jroman 508
  ierr = PetscNewLog(svd,SVD_CYCLIC,&cyclic);CHKERRQ(ierr);
1324 slepc 509
  svd->data                      = (void *)cyclic;
2324 jroman 510
  svd->ops->solve                = SVDSolve_Cyclic;
511
  svd->ops->setup                = SVDSetUp_Cyclic;
512
  svd->ops->setfromoptions       = SVDSetFromOptions_Cyclic;
513
  svd->ops->destroy              = SVDDestroy_Cyclic;
2350 jroman 514
  svd->ops->reset                = SVDReset_Cyclic;
2324 jroman 515
  svd->ops->view                 = SVDView_Cyclic;
516
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDCyclicSetEPS_C","SVDCyclicSetEPS_Cyclic",SVDCyclicSetEPS_Cyclic);CHKERRQ(ierr);
517
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDCyclicGetEPS_C","SVDCyclicGetEPS_Cyclic",SVDCyclicGetEPS_Cyclic);CHKERRQ(ierr);
518
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDCyclicSetExplicitMatrix_C","SVDCyclicSetExplicitMatrix_Cyclic",SVDCyclicSetExplicitMatrix_Cyclic);CHKERRQ(ierr);
519
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDCyclicGetExplicitMatrix_C","SVDCyclicGetExplicitMatrix_Cyclic",SVDCyclicGetExplicitMatrix_Cyclic);CHKERRQ(ierr);
1324 slepc 520
 
1422 slepc 521
  ierr = EPSCreate(((PetscObject)svd)->comm,&cyclic->eps);CHKERRQ(ierr);
522
  ierr = EPSSetOptionsPrefix(cyclic->eps,((PetscObject)svd)->prefix);CHKERRQ(ierr);
1324 slepc 523
  ierr = EPSAppendOptionsPrefix(cyclic->eps,"svd_");CHKERRQ(ierr);
1532 slepc 524
  ierr = PetscObjectIncrementTabLevel((PetscObject)cyclic->eps,(PetscObject)svd,1);CHKERRQ(ierr);  
2327 jroman 525
  ierr = PetscLogObjectParent(svd,cyclic->eps);CHKERRQ(ierr);
2449 eromero 526
  if (!svd->ip) { ierr = SVDGetIP(svd,&svd->ip);CHKERRQ(ierr); }
1345 slepc 527
  ierr = EPSSetIP(cyclic->eps,svd->ip);CHKERRQ(ierr);
1324 slepc 528
  ierr = EPSSetWhichEigenpairs(cyclic->eps,EPS_LARGEST_REAL);CHKERRQ(ierr);
2324 jroman 529
  ierr = EPSMonitorSet(cyclic->eps,SVDMonitor_Cyclic,svd,PETSC_NULL);CHKERRQ(ierr);
1370 slepc 530
  cyclic->explicitmatrix = PETSC_FALSE;
1324 slepc 531
  cyclic->mat = PETSC_NULL;
532
  cyclic->x1 = PETSC_NULL;
533
  cyclic->x2 = PETSC_NULL;
534
  cyclic->y1 = PETSC_NULL;
535
  cyclic->y2 = PETSC_NULL;
2024 eromero 536
  cyclic->setfromoptionscalled = PETSC_FALSE;
1324 slepc 537
  PetscFunctionReturn(0);
538
}
539
EXTERN_C_END