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
6
   Copyright (c) 2002-2009, Universidad 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
 
6 dsic.upv.es!jroman 24
#include "src/eps/impls/trlan/trlanp.h"
25
 
26
/* Nasty global variable to access EPS data from TRLan_ */
27
static EPS globaleps;
28
 
29
#undef __FUNCT__  
30
#define __FUNCT__ "EPSSetUp_TRLAN"
476 dsic.upv.es!antodo 31
PetscErrorCode EPSSetUp_TRLAN(EPS eps)
6 dsic.upv.es!jroman 32
{
476 dsic.upv.es!antodo 33
  PetscErrorCode ierr;
1089 slepc 34
  PetscInt       n;
476 dsic.upv.es!antodo 35
  EPS_TRLAN      *tr = (EPS_TRLAN *)eps->data;
6 dsic.upv.es!jroman 36
 
37
  PetscFunctionBegin;
1386 slepc 38
  ierr = VecGetSize(eps->vec_initial,&n);CHKERRQ(ierr);
260 dsic.upv.es!antodo 39
  if (eps->ncv) {
40
    if (eps->ncv<eps->nev) SETERRQ(1,"The value of ncv must be at least nev");
41
  }
42
  else eps->ncv = eps->nev;
1579 slepc 43
  if (eps->mpd) PetscInfo(eps,"Warning: parameter mpd ignored\n");
1220 slepc 44
  if (!eps->max_it) eps->max_it = PetscMax(1000,n);
260 dsic.upv.es!antodo 45
 
6 dsic.upv.es!jroman 46
  if (!eps->ishermitian)
47
    SETERRQ(PETSC_ERR_SUP,"Requested method is only available for Hermitian problems");
48
 
49
  if (eps->isgeneralized)
50
    SETERRQ(PETSC_ERR_SUP,"Requested method is not available for generalized problems");
51
 
52
  tr->restart = 0;
1386 slepc 53
  ierr = VecGetLocalSize(eps->vec_initial,&n); CHKERRQ(ierr);
1646 slepc 54
  tr->maxlan = PetscBLASIntCast(eps->nev+PetscMin(eps->nev,6));
55
  if (tr->maxlan+1-eps->ncv<=0) { tr->lwork = PetscBLASIntCast(tr->maxlan*(tr->maxlan+10)); }
56
  else { tr->lwork = PetscBLASIntCast(n*(tr->maxlan+1-eps->ncv) + tr->maxlan*(tr->maxlan+10)); }
6 dsic.upv.es!jroman 57
  ierr = PetscMalloc(tr->lwork*sizeof(PetscReal),&tr->work);CHKERRQ(ierr);
58
 
1560 slepc 59
  if (eps->extraction) {
60
     ierr = PetscInfo(eps,"Warning: extraction type ignored\n");CHKERRQ(ierr);
1426 slepc 61
  }
62
 
1596 slepc 63
  ierr = EPSAllocateSolution(eps);CHKERRQ(ierr);
1345 slepc 64
  ierr = EPSDefaultGetWork(eps,1);CHKERRQ(ierr);
6 dsic.upv.es!jroman 65
  PetscFunctionReturn(0);
66
}
67
 
68
#undef __FUNCT__  
69
#define __FUNCT__ "MatMult_TRLAN"
1509 slepc 70
static PetscBLASInt MatMult_TRLAN(PetscBLASInt *n,PetscBLASInt *m,PetscReal *xin,PetscBLASInt *ldx,PetscReal *yout,PetscBLASInt *ldy)
6 dsic.upv.es!jroman 71
{
1089 slepc 72
  PetscErrorCode ierr;
73
  Vec            x,y;
1509 slepc 74
  PetscBLASInt            i;
6 dsic.upv.es!jroman 75
 
76
  PetscFunctionBegin;
1422 slepc 77
  ierr = VecCreateMPIWithArray(((PetscObject)globaleps)->comm,*n,PETSC_DECIDE,PETSC_NULL,&x);CHKERRQ(ierr);
78
  ierr = VecCreateMPIWithArray(((PetscObject)globaleps)->comm,*n,PETSC_DECIDE,PETSC_NULL,&y);CHKERRQ(ierr);
6 dsic.upv.es!jroman 79
  for (i=0;i<*m;i++) {
80
    ierr = VecPlaceArray(x,(PetscScalar*)xin+i*(*ldx));CHKERRQ(ierr);
81
    ierr = VecPlaceArray(y,(PetscScalar*)yout+i*(*ldy));CHKERRQ(ierr);
82
    ierr = STApply(globaleps->OP,x,y);CHKERRQ(ierr);
1538 slepc 83
    ierr = IPOrthogonalize(globaleps->ip,globaleps->nds,PETSC_NULL,globaleps->DS,y,PETSC_NULL,PETSC_NULL,PETSC_NULL,globaleps->work[0],PETSC_NULL);CHKERRQ(ierr);
850 dsic.upv.es!antodo 84
    ierr = VecResetArray(x);CHKERRQ(ierr);
85
    ierr = VecResetArray(y);CHKERRQ(ierr);     
6 dsic.upv.es!jroman 86
  }
1170 slepc 87
  ierr = VecDestroy(x);CHKERRQ(ierr);
88
  ierr = VecDestroy(y);CHKERRQ(ierr);
6 dsic.upv.es!jroman 89
  PetscFunctionReturn(0);
90
}
91
 
92
#undef __FUNCT__  
93
#define __FUNCT__ "EPSSolve_TRLAN"
476 dsic.upv.es!antodo 94
PetscErrorCode EPSSolve_TRLAN(EPS eps)
6 dsic.upv.es!jroman 95
{
1089 slepc 96
  PetscErrorCode ierr;
1513 slepc 97
  PetscInt       i,nn;
1646 slepc 98
  PetscBLASInt   ipar[32], n, lohi, stat, ncv;
1089 slepc 99
  EPS_TRLAN      *tr = (EPS_TRLAN *)eps->data;     
100
  PetscScalar    *pV;                              
6 dsic.upv.es!jroman 101
 
102
  PetscFunctionBegin;
103
 
1646 slepc 104
  ncv = PetscBLASIntCast(eps->ncv);
1386 slepc 105
  ierr = VecGetLocalSize(eps->vec_initial,&nn); CHKERRQ(ierr);
1646 slepc 106
  n = PetscBLASIntCast(nn);
6 dsic.upv.es!jroman 107
 
92 dsic.upv.es!antodo 108
  if (eps->which==EPS_LARGEST_REAL) lohi = 1;
109
  else if (eps->which==EPS_SMALLEST_REAL) lohi = -1;
110
  else SETERRQ(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
 
1509 slepc 134
  TRLan_ ( MatMult_TRLAN, ipar, &n, &ncv, eps->eigr, pV, &n, tr->work, &tr->lwork );
6 dsic.upv.es!jroman 135
 
136
  ierr = VecRestoreArray( eps->V[0], &pV );CHKERRQ(ierr);
137
 
138
  stat        = ipar[0];
139
  eps->nconv  = ipar[3];
140
  eps->its    = ipar[25];
141
  eps->reason = EPS_CONVERGED_TOL;
142
 
143
  if (stat!=0) { SETERRQ1(PETSC_ERR_LIB,"Error in TRLAN (code=%d)",stat);}
144
 
145
  PetscFunctionReturn(0);
146
}
147
 
148
#undef __FUNCT__  
149
#define __FUNCT__ "EPSDestroy_TRLAN"
476 dsic.upv.es!antodo 150
PetscErrorCode EPSDestroy_TRLAN(EPS eps)
6 dsic.upv.es!jroman 151
{
476 dsic.upv.es!antodo 152
  PetscErrorCode ierr;
153
  EPS_TRLAN      *tr = (EPS_TRLAN *)eps->data;
6 dsic.upv.es!jroman 154
 
155
  PetscFunctionBegin;
25 dsic.upv.es!jroman 156
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
1040 slepc 157
  ierr = PetscFree(tr->work);CHKERRQ(ierr);
158
  ierr = PetscFree(eps->data);CHKERRQ(ierr);
1596 slepc 159
  ierr = EPSFreeSolution(eps);CHKERRQ(ierr);
6 dsic.upv.es!jroman 160
  PetscFunctionReturn(0);
161
}
162
 
163
EXTERN_C_BEGIN
164
#undef __FUNCT__  
165
#define __FUNCT__ "EPSCreate_TRLAN"
476 dsic.upv.es!antodo 166
PetscErrorCode EPSCreate_TRLAN(EPS eps)
6 dsic.upv.es!jroman 167
{
476 dsic.upv.es!antodo 168
  PetscErrorCode ierr;
169
  EPS_TRLAN      *trlan;
6 dsic.upv.es!jroman 170
 
171
  PetscFunctionBegin;
172
  ierr = PetscNew(EPS_TRLAN,&trlan);CHKERRQ(ierr);
173
  PetscLogObjectMemory(eps,sizeof(EPS_TRLAN));
174
  eps->data                      = (void *) trlan;
175
  eps->ops->solve                = EPSSolve_TRLAN;
503 dsic.upv.es!antodo 176
  eps->ops->setup                = EPSSetUp_TRLAN;
6 dsic.upv.es!jroman 177
  eps->ops->destroy              = EPSDestroy_TRLAN;
177 dsic.upv.es!antodo 178
  eps->ops->backtransform        = EPSBackTransform_Default;
503 dsic.upv.es!antodo 179
  eps->ops->computevectors       = EPSComputeVectors_Default;
104 dsic.upv.es!antodo 180
  eps->which = EPS_LARGEST_REAL;
6 dsic.upv.es!jroman 181
  PetscFunctionReturn(0);
182
}
183
EXTERN_C_END