Subversion Repositories slepc-dev

Rev

Go to most recent revision | 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
2116 eromero 6
   Copyright (c) 2002-2010, 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
 
1705 jroman 24
#include "src/eps/impls/external/trlan/trlanp.h"
6 dsic.upv.es!jroman 25
 
1947 jroman 26
PetscErrorCode EPSSolve_TRLAN(EPS);
27
 
6 dsic.upv.es!jroman 28
/* Nasty global variable to access EPS data from TRLan_ */
29
static EPS globaleps;
30
 
31
#undef __FUNCT__  
32
#define __FUNCT__ "EPSSetUp_TRLAN"
476 dsic.upv.es!antodo 33
PetscErrorCode EPSSetUp_TRLAN(EPS eps)
6 dsic.upv.es!jroman 34
{
476 dsic.upv.es!antodo 35
  PetscErrorCode ierr;
36
  EPS_TRLAN      *tr = (EPS_TRLAN *)eps->data;
6 dsic.upv.es!jroman 37
 
38
  PetscFunctionBegin;
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");
1928 jroman 44
  if (!eps->max_it) eps->max_it = PetscMax(1000,eps->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
 
1942 jroman 52
  if (!eps->which) eps->which = EPS_LARGEST_REAL;
2161 jroman 53
  if (eps->which!=EPS_LARGEST_REAL && eps->which!=EPS_SMALLEST_REAL && eps->which!=EPS_TARGET_REAL)
1942 jroman 54
    SETERRQ(1,"Wrong value of eps->which");
55
 
6 dsic.upv.es!jroman 56
  tr->restart = 0;
1646 slepc 57
  tr->maxlan = PetscBLASIntCast(eps->nev+PetscMin(eps->nev,6));
58
  if (tr->maxlan+1-eps->ncv<=0) { tr->lwork = PetscBLASIntCast(tr->maxlan*(tr->maxlan+10)); }
1928 jroman 59
  else { tr->lwork = PetscBLASIntCast(eps->nloc*(tr->maxlan+1-eps->ncv) + tr->maxlan*(tr->maxlan+10)); }
6 dsic.upv.es!jroman 60
  ierr = PetscMalloc(tr->lwork*sizeof(PetscReal),&tr->work);CHKERRQ(ierr);
61
 
1560 slepc 62
  if (eps->extraction) {
63
     ierr = PetscInfo(eps,"Warning: extraction type ignored\n");CHKERRQ(ierr);
1426 slepc 64
  }
65
 
1596 slepc 66
  ierr = EPSAllocateSolution(eps);CHKERRQ(ierr);
1947 jroman 67
 
68
  /* dispatch solve method */
69
  if (eps->leftvecs) SETERRQ(PETSC_ERR_SUP,"Left vectors not supported in this solver");
70
  eps->ops->solve = EPSSolve_TRLAN;
6 dsic.upv.es!jroman 71
  PetscFunctionReturn(0);
72
}
73
 
74
#undef __FUNCT__  
75
#define __FUNCT__ "MatMult_TRLAN"
1509 slepc 76
static PetscBLASInt MatMult_TRLAN(PetscBLASInt *n,PetscBLASInt *m,PetscReal *xin,PetscBLASInt *ldx,PetscReal *yout,PetscBLASInt *ldy)
6 dsic.upv.es!jroman 77
{
1089 slepc 78
  PetscErrorCode ierr;
79
  Vec            x,y;
1509 slepc 80
  PetscBLASInt            i;
6 dsic.upv.es!jroman 81
 
82
  PetscFunctionBegin;
1422 slepc 83
  ierr = VecCreateMPIWithArray(((PetscObject)globaleps)->comm,*n,PETSC_DECIDE,PETSC_NULL,&x);CHKERRQ(ierr);
84
  ierr = VecCreateMPIWithArray(((PetscObject)globaleps)->comm,*n,PETSC_DECIDE,PETSC_NULL,&y);CHKERRQ(ierr);
6 dsic.upv.es!jroman 85
  for (i=0;i<*m;i++) {
86
    ierr = VecPlaceArray(x,(PetscScalar*)xin+i*(*ldx));CHKERRQ(ierr);
87
    ierr = VecPlaceArray(y,(PetscScalar*)yout+i*(*ldy));CHKERRQ(ierr);
88
    ierr = STApply(globaleps->OP,x,y);CHKERRQ(ierr);
1755 antodo 89
    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 90
    ierr = VecResetArray(x);CHKERRQ(ierr);
91
    ierr = VecResetArray(y);CHKERRQ(ierr);     
6 dsic.upv.es!jroman 92
  }
1170 slepc 93
  ierr = VecDestroy(x);CHKERRQ(ierr);
94
  ierr = VecDestroy(y);CHKERRQ(ierr);
6 dsic.upv.es!jroman 95
  PetscFunctionReturn(0);
96
}
97
 
98
#undef __FUNCT__  
99
#define __FUNCT__ "EPSSolve_TRLAN"
476 dsic.upv.es!antodo 100
PetscErrorCode EPSSolve_TRLAN(EPS eps)
6 dsic.upv.es!jroman 101
{
1089 slepc 102
  PetscErrorCode ierr;
1928 jroman 103
  PetscInt       i;
1646 slepc 104
  PetscBLASInt   ipar[32], n, lohi, stat, ncv;
1089 slepc 105
  EPS_TRLAN      *tr = (EPS_TRLAN *)eps->data;     
106
  PetscScalar    *pV;                              
6 dsic.upv.es!jroman 107
 
108
  PetscFunctionBegin;
109
 
1646 slepc 110
  ncv = PetscBLASIntCast(eps->ncv);
1928 jroman 111
  n = PetscBLASIntCast(eps->nloc);
6 dsic.upv.es!jroman 112
 
2161 jroman 113
  if (eps->which==EPS_LARGEST_REAL || eps->which==EPS_TARGET_REAL) lohi = 1;
92 dsic.upv.es!antodo 114
  else if (eps->which==EPS_SMALLEST_REAL) lohi = -1;
115
  else SETERRQ(1,"Wrong value of eps->which");
6 dsic.upv.es!jroman 116
 
117
  globaleps = eps;
118
 
119
  ipar[0]  = 0;            /* stat: error flag */
120
  ipar[1]  = lohi;         /* smallest (lohi<0) or largest eigenvalues (lohi>0) */
1646 slepc 121
  ipar[2]  = PetscBLASIntCast(eps->nev); /* number of desired eigenpairs */
6 dsic.upv.es!jroman 122
  ipar[3]  = 0;            /* number of eigenpairs already converged */
123
  ipar[4]  = tr->maxlan;   /* maximum Lanczos basis size */
124
  ipar[5]  = tr->restart;  /* restarting scheme */
1646 slepc 125
  ipar[6]  = PetscBLASIntCast(eps->max_it); /* maximum number of MATVECs */
126
  ipar[7]  = PetscBLASIntCast(MPI_Comm_c2f(((PetscObject)eps)->comm)); /* communicator */
6 dsic.upv.es!jroman 127
  ipar[8]  = 0;            /* verboseness */
128
  ipar[9]  = 99;           /* Fortran IO unit number used to write log messages */
129
  ipar[10] = 1;            /* use supplied starting vector */
130
  ipar[11] = 0;            /* checkpointing flag */
131
  ipar[12] = 98;           /* Fortran IO unit number used to write checkpoint files */
132
  ipar[13] = 0;            /* number of flops per matvec per PE (not used) */
133
  tr->work[0] = eps->tol;  /* relative tolerance on residual norms */
134
 
135
  for (i=0;i<eps->ncv;i++) eps->eigr[i]=0.0;
1170 slepc 136
  ierr = EPSGetStartVector(eps,0,eps->V[0],PETSC_NULL);CHKERRQ(ierr);
6 dsic.upv.es!jroman 137
  ierr = VecGetArray(eps->V[0],&pV);CHKERRQ(ierr);
138
 
1509 slepc 139
  TRLan_ ( MatMult_TRLAN, ipar, &n, &ncv, eps->eigr, pV, &n, tr->work, &tr->lwork );
6 dsic.upv.es!jroman 140
 
141
  ierr = VecRestoreArray( eps->V[0], &pV );CHKERRQ(ierr);
142
 
143
  stat        = ipar[0];
144
  eps->nconv  = ipar[3];
145
  eps->its    = ipar[25];
146
  eps->reason = EPS_CONVERGED_TOL;
147
 
148
  if (stat!=0) { SETERRQ1(PETSC_ERR_LIB,"Error in TRLAN (code=%d)",stat);}
149
 
150
  PetscFunctionReturn(0);
151
}
152
 
153
#undef __FUNCT__  
154
#define __FUNCT__ "EPSDestroy_TRLAN"
476 dsic.upv.es!antodo 155
PetscErrorCode EPSDestroy_TRLAN(EPS eps)
6 dsic.upv.es!jroman 156
{
476 dsic.upv.es!antodo 157
  PetscErrorCode ierr;
158
  EPS_TRLAN      *tr = (EPS_TRLAN *)eps->data;
6 dsic.upv.es!jroman 159
 
160
  PetscFunctionBegin;
25 dsic.upv.es!jroman 161
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
1040 slepc 162
  ierr = PetscFree(tr->work);CHKERRQ(ierr);
163
  ierr = PetscFree(eps->data);CHKERRQ(ierr);
1596 slepc 164
  ierr = EPSFreeSolution(eps);CHKERRQ(ierr);
6 dsic.upv.es!jroman 165
  PetscFunctionReturn(0);
166
}
167
 
168
EXTERN_C_BEGIN
169
#undef __FUNCT__  
170
#define __FUNCT__ "EPSCreate_TRLAN"
476 dsic.upv.es!antodo 171
PetscErrorCode EPSCreate_TRLAN(EPS eps)
6 dsic.upv.es!jroman 172
{
476 dsic.upv.es!antodo 173
  PetscErrorCode ierr;
174
  EPS_TRLAN      *trlan;
6 dsic.upv.es!jroman 175
 
176
  PetscFunctionBegin;
177
  ierr = PetscNew(EPS_TRLAN,&trlan);CHKERRQ(ierr);
178
  PetscLogObjectMemory(eps,sizeof(EPS_TRLAN));
179
  eps->data                      = (void *) trlan;
503 dsic.upv.es!antodo 180
  eps->ops->setup                = EPSSetUp_TRLAN;
6 dsic.upv.es!jroman 181
  eps->ops->destroy              = EPSDestroy_TRLAN;
177 dsic.upv.es!antodo 182
  eps->ops->backtransform        = EPSBackTransform_Default;
503 dsic.upv.es!antodo 183
  eps->ops->computevectors       = EPSComputeVectors_Default;
6 dsic.upv.es!jroman 184
  PetscFunctionReturn(0);
185
}
186
EXTERN_C_END