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