Subversion Repositories slepc-dev

Rev

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

Rev Author Line No. Line
1376 slepc 1
/*
2
       This file implements a wrapper to the TRLAN package
6 dsic.upv.es!jroman 3
 
1376 slepc 4
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1672 slepc 5
   SLEPc - Scalable Library for Eigenvalue Problem Computations
2575 eromero 6
   Copyright (c) 2002-2011, Universitat Politecnica de Valencia, Spain
1376 slepc 7
 
1672 slepc 8
   This file is part of SLEPc.
9
 
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.
13
 
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.
18
 
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/>.
1376 slepc 21
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6 dsic.upv.es!jroman 22
*/
1376 slepc 23
 
2729 jroman 24
#include <slepc-private/epsimpl.h>          /*I "slepceps.h" I*/
2283 jroman 25
#include <../src/eps/impls/external/trlan/trlanp.h>
6 dsic.upv.es!jroman 26
 
1947 jroman 27
PetscErrorCode EPSSolve_TRLAN(EPS);
28
 
6 dsic.upv.es!jroman 29
/* Nasty global variable to access EPS data from TRLan_ */
30
static EPS globaleps;
31
 
32
#undef __FUNCT__  
33
#define __FUNCT__ "EPSSetUp_TRLAN"
476 dsic.upv.es!antodo 34
PetscErrorCode EPSSetUp_TRLAN(EPS eps)
6 dsic.upv.es!jroman 35
{
476 dsic.upv.es!antodo 36
  PetscErrorCode ierr;
37
  EPS_TRLAN      *tr = (EPS_TRLAN *)eps->data;
6 dsic.upv.es!jroman 38
 
39
  PetscFunctionBegin;
2585 jroman 40
  tr->maxlan = PetscBLASIntCast(PetscMax(7,eps->nev+PetscMin(eps->nev,6)));
260 dsic.upv.es!antodo 41
  if (eps->ncv) {
2214 jroman 42
    if (eps->ncv<eps->nev) SETERRQ(((PetscObject)eps)->comm,1,"The value of ncv must be at least nev");
260 dsic.upv.es!antodo 43
  }
2585 jroman 44
  else eps->ncv = tr->maxlan;
2499 jroman 45
  if (eps->mpd) { ierr = PetscInfo(eps,"Warning: parameter mpd ignored\n");CHKERRQ(ierr); }
1928 jroman 46
  if (!eps->max_it) eps->max_it = PetscMax(1000,eps->n);
260 dsic.upv.es!antodo 47
 
2762 jroman 48
  if (!eps->ishermitian) SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"Requested method is only available for Hermitian problems");
6 dsic.upv.es!jroman 49
 
2762 jroman 50
  if (eps->isgeneralized) SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"Requested method is not available for generalized problems");
6 dsic.upv.es!jroman 51
 
1942 jroman 52
  if (!eps->which) eps->which = EPS_LARGEST_REAL;
2762 jroman 53
  if (eps->which!=EPS_LARGEST_REAL && eps->which!=EPS_SMALLEST_REAL && eps->which!=EPS_TARGET_REAL) SETERRQ(((PetscObject)eps)->comm,1,"Wrong value of eps->which");
1942 jroman 54
 
6 dsic.upv.es!jroman 55
  tr->restart = 0;
1646 slepc 56
  if (tr->maxlan+1-eps->ncv<=0) { tr->lwork = PetscBLASIntCast(tr->maxlan*(tr->maxlan+10)); }
1928 jroman 57
  else { tr->lwork = PetscBLASIntCast(eps->nloc*(tr->maxlan+1-eps->ncv) + tr->maxlan*(tr->maxlan+10)); }
6 dsic.upv.es!jroman 58
  ierr = PetscMalloc(tr->lwork*sizeof(PetscReal),&tr->work);CHKERRQ(ierr);
59
 
2499 jroman 60
  if (eps->extraction) { ierr = PetscInfo(eps,"Warning: extraction type ignored\n");CHKERRQ(ierr); }
1426 slepc 61
 
1596 slepc 62
  ierr = EPSAllocateSolution(eps);CHKERRQ(ierr);
1947 jroman 63
 
64
  /* dispatch solve method */
2214 jroman 65
  if (eps->leftvecs) SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"Left vectors not supported in this solver");
1947 jroman 66
  eps->ops->solve = EPSSolve_TRLAN;
6 dsic.upv.es!jroman 67
  PetscFunctionReturn(0);
68
}
69
 
70
#undef __FUNCT__  
71
#define __FUNCT__ "MatMult_TRLAN"
1509 slepc 72
static PetscBLASInt MatMult_TRLAN(PetscBLASInt *n,PetscBLASInt *m,PetscReal *xin,PetscBLASInt *ldx,PetscReal *yout,PetscBLASInt *ldy)
6 dsic.upv.es!jroman 73
{
1089 slepc 74
  PetscErrorCode ierr;
75
  Vec            x,y;
2317 jroman 76
  PetscBLASInt   i;
6 dsic.upv.es!jroman 77
 
78
  PetscFunctionBegin;
2761 jroman 79
  ierr = VecCreateMPIWithArray(((PetscObject)globaleps)->comm,1,*n,PETSC_DECIDE,PETSC_NULL,&x);CHKERRQ(ierr);
80
  ierr = VecCreateMPIWithArray(((PetscObject)globaleps)->comm,1,*n,PETSC_DECIDE,PETSC_NULL,&y);CHKERRQ(ierr);
6 dsic.upv.es!jroman 81
  for (i=0;i<*m;i++) {
82
    ierr = VecPlaceArray(x,(PetscScalar*)xin+i*(*ldx));CHKERRQ(ierr);
83
    ierr = VecPlaceArray(y,(PetscScalar*)yout+i*(*ldy));CHKERRQ(ierr);
84
    ierr = STApply(globaleps->OP,x,y);CHKERRQ(ierr);
1755 antodo 85
    ierr = IPOrthogonalize(globaleps->ip,0,PETSC_NULL,globaleps->nds,PETSC_NULL,globaleps->DS,y,PETSC_NULL,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
850 dsic.upv.es!antodo 86
    ierr = VecResetArray(x);CHKERRQ(ierr);
2316 jroman 87
    ierr = VecResetArray(y);CHKERRQ(ierr);
6 dsic.upv.es!jroman 88
  }
2305 jroman 89
  ierr = VecDestroy(&x);CHKERRQ(ierr);
90
  ierr = VecDestroy(&y);CHKERRQ(ierr);
6 dsic.upv.es!jroman 91
  PetscFunctionReturn(0);
92
}
93
 
94
#undef __FUNCT__  
95
#define __FUNCT__ "EPSSolve_TRLAN"
476 dsic.upv.es!antodo 96
PetscErrorCode EPSSolve_TRLAN(EPS eps)
6 dsic.upv.es!jroman 97
{
1089 slepc 98
  PetscErrorCode ierr;
1928 jroman 99
  PetscInt       i;
2331 jroman 100
  PetscBLASInt   ipar[32],n,lohi,stat,ncv;
2316 jroman 101
  EPS_TRLAN      *tr = (EPS_TRLAN *)eps->data;  
102
  PetscScalar    *pV;
6 dsic.upv.es!jroman 103
 
104
  PetscFunctionBegin;
1646 slepc 105
  ncv = PetscBLASIntCast(eps->ncv);
1928 jroman 106
  n = PetscBLASIntCast(eps->nloc);
6 dsic.upv.es!jroman 107
 
2161 jroman 108
  if (eps->which==EPS_LARGEST_REAL || eps->which==EPS_TARGET_REAL) lohi = 1;
92 dsic.upv.es!antodo 109
  else if (eps->which==EPS_SMALLEST_REAL) lohi = -1;
2214 jroman 110
  else SETERRQ(((PetscObject)eps)->comm,1,"Wrong value of eps->which");
6 dsic.upv.es!jroman 111
 
112
  globaleps = eps;
113
 
114
  ipar[0]  = 0;            /* stat: error flag */
115
  ipar[1]  = lohi;         /* smallest (lohi<0) or largest eigenvalues (lohi>0) */
1646 slepc 116
  ipar[2]  = PetscBLASIntCast(eps->nev); /* number of desired eigenpairs */
6 dsic.upv.es!jroman 117
  ipar[3]  = 0;            /* number of eigenpairs already converged */
118
  ipar[4]  = tr->maxlan;   /* maximum Lanczos basis size */
119
  ipar[5]  = tr->restart;  /* restarting scheme */
1646 slepc 120
  ipar[6]  = PetscBLASIntCast(eps->max_it); /* maximum number of MATVECs */
121
  ipar[7]  = PetscBLASIntCast(MPI_Comm_c2f(((PetscObject)eps)->comm)); /* communicator */
6 dsic.upv.es!jroman 122
  ipar[8]  = 0;            /* verboseness */
123
  ipar[9]  = 99;           /* Fortran IO unit number used to write log messages */
124
  ipar[10] = 1;            /* use supplied starting vector */
125
  ipar[11] = 0;            /* checkpointing flag */
126
  ipar[12] = 98;           /* Fortran IO unit number used to write checkpoint files */
127
  ipar[13] = 0;            /* number of flops per matvec per PE (not used) */
128
  tr->work[0] = eps->tol;  /* relative tolerance on residual norms */
129
 
130
  for (i=0;i<eps->ncv;i++) eps->eigr[i]=0.0;
1170 slepc 131
  ierr = EPSGetStartVector(eps,0,eps->V[0],PETSC_NULL);CHKERRQ(ierr);
6 dsic.upv.es!jroman 132
  ierr = VecGetArray(eps->V[0],&pV);CHKERRQ(ierr);
133
 
2331 jroman 134
  TRLan_(MatMult_TRLAN,ipar,&n,&ncv,eps->eigr,pV,&n,tr->work,&tr->lwork);
6 dsic.upv.es!jroman 135
 
2331 jroman 136
  ierr = VecRestoreArray(eps->V[0],&pV);CHKERRQ(ierr);
6 dsic.upv.es!jroman 137
 
138
  stat        = ipar[0];
139
  eps->nconv  = ipar[3];
140
  eps->its    = ipar[25];
141
  eps->reason = EPS_CONVERGED_TOL;
142
 
2762 jroman 143
  if (stat!=0) SETERRQ1(((PetscObject)eps)->comm,PETSC_ERR_LIB,"Error in TRLAN (code=%d)",stat);
6 dsic.upv.es!jroman 144
  PetscFunctionReturn(0);
145
}
146
 
147
#undef __FUNCT__  
2348 jroman 148
#define __FUNCT__ "EPSReset_TRLAN"
149
PetscErrorCode EPSReset_TRLAN(EPS eps)
6 dsic.upv.es!jroman 150
{
476 dsic.upv.es!antodo 151
  PetscErrorCode ierr;
152
  EPS_TRLAN      *tr = (EPS_TRLAN *)eps->data;
6 dsic.upv.es!jroman 153
 
154
  PetscFunctionBegin;
1040 slepc 155
  ierr = PetscFree(tr->work);CHKERRQ(ierr);
1596 slepc 156
  ierr = EPSFreeSolution(eps);CHKERRQ(ierr);
6 dsic.upv.es!jroman 157
  PetscFunctionReturn(0);
158
}
159
 
2348 jroman 160
#undef __FUNCT__  
161
#define __FUNCT__ "EPSDestroy_TRLAN"
162
PetscErrorCode EPSDestroy_TRLAN(EPS eps)
163
{
164
  PetscErrorCode ierr;
165
 
166
  PetscFunctionBegin;
167
  ierr = PetscFree(eps->data);CHKERRQ(ierr);
168
  PetscFunctionReturn(0);
169
}
170
 
6 dsic.upv.es!jroman 171
EXTERN_C_BEGIN
172
#undef __FUNCT__  
173
#define __FUNCT__ "EPSCreate_TRLAN"
476 dsic.upv.es!antodo 174
PetscErrorCode EPSCreate_TRLAN(EPS eps)
6 dsic.upv.es!jroman 175
{
476 dsic.upv.es!antodo 176
  PetscErrorCode ierr;
6 dsic.upv.es!jroman 177
 
178
  PetscFunctionBegin;
2329 jroman 179
  ierr = PetscNewLog(eps,EPS_TRLAN,&eps->data);CHKERRQ(ierr);
503 dsic.upv.es!antodo 180
  eps->ops->setup                = EPSSetUp_TRLAN;
6 dsic.upv.es!jroman 181
  eps->ops->destroy              = EPSDestroy_TRLAN;
2348 jroman 182
  eps->ops->reset                = EPSReset_TRLAN;
177 dsic.upv.es!antodo 183
  eps->ops->backtransform        = EPSBackTransform_Default;
503 dsic.upv.es!antodo 184
  eps->ops->computevectors       = EPSComputeVectors_Default;
6 dsic.upv.es!jroman 185
  PetscFunctionReturn(0);
186
}
187
EXTERN_C_END