Subversion Repositories slepc-dev

Rev

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

Rev Author Line No. Line
1619 slepc 1
/*
2
  SLEPc eigensolver: "davidson"
3
 
4
  Step: test for restarting, updateV, restartV
5
 
6
*/
7
 
1985 eromero 8
#include "davidson.h"
1619 slepc 9
 
10
PetscTruth dvd_isrestarting_fullV(dvdDashboard *d);
2021 eromero 11
PetscErrorCode dvd_managementV_basic_d(dvdDashboard *d);
12
PetscErrorCode dvd_updateV_extrapol(dvdDashboard *d);
1795 eromero 13
PetscErrorCode dvd_updateV_conv_gen(dvdDashboard *d);
14
PetscErrorCode dvd_updateV_restart_gen(dvdDashboard *d);
15
PetscErrorCode dvd_updateV_update_gen(dvdDashboard *d);
2018 eromero 16
PetscErrorCode dvd_updateV_testConv(dvdDashboard *d, PetscInt s, PetscInt pre,
17
                                    PetscInt e, Vec *auxV, PetscScalar *auxS,
18
                                    PetscInt *nConv);
1795 eromero 19
PetscErrorCode dvd_updateV_restartV_aux(Vec *V, PetscInt size_V,
20
                                        PetscScalar *U, PetscInt ldU,
21
                                        PetscScalar *pX, PetscInt ldpX,
22
                                        PetscInt cpX, PetscScalar *oldpX,
23
                                        PetscInt ldoldpX, PetscInt roldpX,
24
                                        PetscInt coldpX, PetscScalar *auxS,
25
                                        PetscInt size_auxS,
26
                                        PetscInt *new_size_V);
27
PetscErrorCode dvd_updateV_YtWx(PetscScalar *S, PetscInt ldS,
1883 eromero 28
                                Vec *Y, PetscInt cY, Vec *y, PetscInt cy,
29
                                Vec *W, PetscInt cW, PetscScalar *x,
30
                                PetscInt ldx,
31
                                PetscInt rx, PetscInt cx, Vec *auxV);
1619 slepc 32
typedef struct {
33
  PetscInt bs,      /* common number of approximated eigenpairs obtained */
34
    real_max_size_V,
35
                    /* real max size of V */
1743 eromero 36
    min_size_V,     /* restart with this number of eigenvectors */
2023 eromero 37
    plusk,          /* when restart, save plusk vectors from last iteration */
38
    mpd;            /* max size of the searching subspace */
1795 eromero 39
  Vec *real_V,      /* real start vectors V */
40
    *new_cY;        /* new left converged eigenvectors from the last iter */
1619 slepc 41
  void
42
    *old_updateV_data;
43
                    /* old updateV data */
44
  isRestarting_type
45
    old_isRestarting;
46
                    /* old isRestarting */
1743 eromero 47
  PetscScalar
1795 eromero 48
    *oldU,          /* previous projected right igenvectors */
49
    *oldV;          /* previous projected left eigenvectors */
1743 eromero 50
  PetscInt
51
    ldoldU,         /* leading dimension of oldU */
1795 eromero 52
    size_oldU,      /* size of oldU */
53
    size_new_cY;    /* size of new_cY */
1619 slepc 54
} dvdManagV_basic;
55
 
56
#undef __FUNCT__  
57
#define __FUNCT__ "dvd_managementV_basic"
2021 eromero 58
PetscErrorCode dvd_managementV_basic(dvdDashboard *d, dvdBlackboard *b,
2023 eromero 59
                                     PetscInt bs, PetscInt max_size_V,
60
                                     PetscInt mpd, PetscInt min_size_V,
61
                                     PetscInt plusk, PetscTruth harm)
1619 slepc 62
{
63
  PetscErrorCode  ierr;
64
  dvdManagV_basic *data;
1960 eromero 65
  PetscInt        i;
1619 slepc 66
 
67
  PetscFunctionBegin;
68
 
69
  /* Setting configuration constrains */
2023 eromero 70
  mpd = PetscMin(mpd, max_size_V);
71
  min_size_V = PetscMin(min_size_V, mpd-bs);
72
  b->max_size_X = PetscMax(b->max_size_X, PetscMax(bs, min_size_V));
1820 eromero 73
  b->max_size_auxV = PetscMax(PetscMax(b->max_size_auxV,
2023 eromero 74
                                       b->max_size_X /* updateV_conv_gen */ ),
1820 eromero 75
                                       2 /* testConv */ );
76
  b->max_size_auxS = PetscMax(PetscMax(PetscMax(b->max_size_auxS,
2023 eromero 77
                              max_size_V*b->max_size_X /* YtWx */ ),
1820 eromero 78
                              max_size_V*2 /* SlepcDenseOrth  */ ),
79
                              max_size_V*b->max_size_X /* testConv:res_0 */ );
2023 eromero 80
  b->max_size_V = mpd;
1795 eromero 81
  b->own_vecs+= max_size_V*(harm==PETSC_TRUE?2:1);      /* V, W? */
2023 eromero 82
  b->own_scalars+= max_size_V*2 /* eigr, eigr */ +
83
                   max_size_V /* nR */   +
84
                   max_size_V /* nX */   +
85
                   max_size_V /* errest */ +
1795 eromero 86
                   2*b->max_size_V*b->max_size_V*(harm==PETSC_TRUE?2:1)
2023 eromero 87
                                               /* MTX,MTY?,oldU,oldV? */;
1735 eromero 88
//  b->max_size_oldX = plusk;
1619 slepc 89
 
90
  /* Setup the step */
91
  if (b->state >= DVD_STATE_CONF) {
92
    ierr = PetscMalloc(sizeof(dvdManagV_basic), &data); CHKERRQ(ierr);
93
    data->real_max_size_V = max_size_V;
1735 eromero 94
    data->min_size_V = min_size_V;
1619 slepc 95
    data->real_V = b->free_vecs; b->free_vecs+= max_size_V;
96
    data->bs = bs;
1743 eromero 97
    data->plusk = plusk;
1820 eromero 98
    data->new_cY = PETSC_NULL;
99
    data->size_new_cY = 0;
2023 eromero 100
    data->mpd = mpd;
1619 slepc 101
 
102
    d->V = data->real_V;
103
    d->max_size_V = data->real_max_size_V;
104
    d->cX = data->real_V;
2023 eromero 105
    d->eigr = b->free_scalars; b->free_scalars+= max_size_V;
106
    d->eigi = b->free_scalars; b->free_scalars+= max_size_V;
1883 eromero 107
#ifdef PETSC_USE_COMPLEX
2023 eromero 108
    for(i=0; i<max_size_V; i++) d->eigi[i] = 0.0;
1619 slepc 109
#endif
1735 eromero 110
    d->nR = (PetscReal*)b->free_scalars;
2023 eromero 111
    b->free_scalars = (PetscScalar*)(d->nR + max_size_V);
112
    for(i=0; i<max_size_V; i++) d->nR[i] = PETSC_MAX;
1764 eromero 113
    d->nX = (PetscReal*)b->free_scalars;
2023 eromero 114
    b->free_scalars = (PetscScalar*)(d->nX + max_size_V);
1735 eromero 115
    d->errest = (PetscReal*)b->free_scalars;
2023 eromero 116
    b->free_scalars = (PetscScalar*)(d->errest + max_size_V);
1619 slepc 117
    d->ceigr = d->eigr;
118
    d->ceigi = d->eigi;
1795 eromero 119
    d->MTX = b->free_scalars; b->free_scalars+= b->max_size_V*b->max_size_V;
1743 eromero 120
    data->oldU = b->free_scalars; b->free_scalars+= b->max_size_V*b->max_size_V;
1820 eromero 121
    data->ldoldU = 0;
122
    data->oldV = PETSC_NULL;
123
    d->W = PETSC_NULL;
124
    d->MTY = PETSC_NULL;
125
    d->ldMTY = 0;
1795 eromero 126
    if (harm == PETSC_TRUE) {
127
      d->W = b->free_vecs; b->free_vecs+= max_size_V;
128
      d->MTY = b->free_scalars; b->free_scalars+= b->max_size_V*b->max_size_V;
129
      data->oldV = b->free_scalars; b->free_scalars+= b->max_size_V*b->max_size_V;
130
    }
1829 eromero 131
 
1743 eromero 132
    data->size_oldU = 0;
1619 slepc 133
    data->old_updateV_data = d->updateV_data;
134
    d->updateV_data = data;
135
    data->old_isRestarting = d->isRestarting;
136
    d->isRestarting = dvd_isrestarting_fullV;
1795 eromero 137
    d->updateV = dvd_updateV_extrapol;
2018 eromero 138
    d->preTestConv = dvd_updateV_testConv;
1619 slepc 139
    DVD_FL_ADD(d->destroyList, dvd_managementV_basic_d);
140
  }
141
 
142
  PetscFunctionReturn(0);
143
}
144
 
145
#undef __FUNCT__  
146
#define __FUNCT__ "dvd_isrestarting_fullV"
147
PetscTruth dvd_isrestarting_fullV(dvdDashboard *d)
148
{
149
  PetscTruth      restart;
150
  dvdManagV_basic *data = (dvdManagV_basic*)d->updateV_data;
151
 
152
  PetscFunctionBegin;
153
 
2023 eromero 154
  /* Take into account the possibility of conjugate eigenpairs */
155
#if defined(PETSC_USE_COMPLEX)
156
#define ONE 0
157
#else
158
#define ONE 1
159
#endif
1619 slepc 160
 
2023 eromero 161
  restart = (d->size_V + data->bs + ONE > PetscMin(data->mpd,d->max_size_V))?
162
                PETSC_TRUE:PETSC_FALSE;
163
 
164
#undef ONE
165
 
1619 slepc 166
  /* Check old isRestarting function */
167
  if ((restart == PETSC_FALSE) && (data->old_isRestarting))
168
    restart = data->old_isRestarting(d);
169
 
170
  PetscFunctionReturn(restart);
171
}
172
 
173
#undef __FUNCT__  
1735 eromero 174
#define __FUNCT__ "dvd_managementV_basic_d"
2021 eromero 175
PetscErrorCode dvd_managementV_basic_d(dvdDashboard *d)
1619 slepc 176
{
1735 eromero 177
  PetscErrorCode  ierr;
1619 slepc 178
  dvdManagV_basic *data = (dvdManagV_basic*)d->updateV_data;
179
 
180
  PetscFunctionBegin;
181
 
1735 eromero 182
  /* Restore changes in dvdDashboard */
183
  d->updateV_data = data->old_updateV_data;
184
 
185
  /* Free local data */
186
  ierr = PetscFree(data); CHKERRQ(ierr);
1653 slepc 187
 
1619 slepc 188
  PetscFunctionReturn(0);
189
}
190
 
191
#undef __FUNCT__  
1795 eromero 192
#define __FUNCT__ "dvd_updateV_extrapol"
2021 eromero 193
PetscErrorCode dvd_updateV_extrapol(dvdDashboard *d)
1619 slepc 194
{
195
  dvdManagV_basic *data = (dvdManagV_basic*)d->updateV_data;
1795 eromero 196
  PetscInt        i;
1619 slepc 197
  PetscErrorCode  ierr;
198
 
199
  PetscFunctionBegin;
200
 
1795 eromero 201
  /// Temporal! Copy the converged left eigenvectors to cY
202
  if (data->size_new_cY > 0) {
203
    for (i=0; i<data->size_new_cY; i++) {
204
      ierr = VecCopy(data->new_cY[i], d->cY[d->size_cY+i]); CHKERRQ(ierr);
205
    }
206
    d->size_cY+= data->size_new_cY;
207
    data->size_new_cY = 0;
208
  }
1743 eromero 209
 
2018 eromero 210
  /* If the subspaces doesn't need restart, add new vector */
211
  if (d->isRestarting(d) == PETSC_FALSE) {
212
    i = d->size_V;
213
    ierr = dvd_updateV_update_gen(d); CHKERRQ(ierr);
214
 
215
    /* If some vector were add, exit */
216
    if (i < d->size_V) { PetscFunctionReturn(0); }
217
  }
218
 
1972 eromero 219
  /* If some eigenpairs were converged, lock them  */
220
  if (d->npreconv > 0) {
221
    i = d->npreconv;
1795 eromero 222
    ierr = dvd_updateV_conv_gen(d); CHKERRQ(ierr);
1619 slepc 223
 
1972 eromero 224
    /* If some eigenpair was locked, exit */
225
    if (i > d->npreconv) { PetscFunctionReturn(0); }
226
  }
227
 
228
  /* Else, a restarting is performed */
229
  ierr = dvd_updateV_restart_gen(d); CHKERRQ(ierr);
230
 
1795 eromero 231
  PetscFunctionReturn(0);
232
}
1743 eromero 233
 
1795 eromero 234
#undef __FUNCT__  
235
#define __FUNCT__ "dvd_updateV_conv_gen"
236
PetscErrorCode dvd_updateV_conv_gen(dvdDashboard *d)
237
{
238
  dvdManagV_basic *data = (dvdManagV_basic*)d->updateV_data;
1883 eromero 239
  PetscInt        i, j, npreconv, ldpX, inc_V, cMT, size_cX, size_cy;
1795 eromero 240
  PetscErrorCode  ierr;
1883 eromero 241
  PetscScalar     *pX;
242
  PetscReal       norm;
243
  Vec             *new_cY=0, *cX, *cy;
1829 eromero 244
  PetscTruth      lindep;
1795 eromero 245
 
246
  PetscFunctionBegin;
247
 
1972 eromero 248
  /* If the left subspace is present, constrains the converged pairs to the
249
     number of free vectors in V */
250
  if (d->cY && d->pY)
251
    npreconv = PetscMin(d->max_size_V-d->size_V, d->npreconv);
252
  else
253
    npreconv = d->npreconv;
1795 eromero 254
 
1972 eromero 255
  /* Constrains the converged pairs to nev */
1966 eromero 256
#ifndef PETSC_USE_COMPLEX
1972 eromero 257
  /* Tries to maintain together conjugate eigenpairs */
258
  for(i = 0;
259
      (i + (d->eigi[i]!=0.0?1:0) < npreconv) && (d->nconv + i < d->nev);
260
      i+= (d->eigi[i]!=0.0?2:1));
261
  npreconv = i;
262
#else
263
  npreconv = PetscMax(PetscMin(d->nev - d->nconv, npreconv), 0);
1966 eromero 264
#endif
265
 
1972 eromero 266
  if (d->npreconv == 0) { PetscFunctionReturn(0); }
267
 
2021 eromero 268
  ierr = d->calcpairs_selectPairs(d, d->size_H); CHKERRQ(ierr);
1972 eromero 269
 
1795 eromero 270
  /* f.cY <- [f.cY f.V*f.pY(0:npreconv-1)] */
271
  if (d->cY && d->pY) {
272
    new_cY = &d->V[d->size_V];
273
    ierr = SlepcUpdateVectorsZ(new_cY, 0.0, 1.0, d->W?d->W:d->V, d->size_V,
274
                               d->pY, d->ldpY, d->size_H, npreconv);
1743 eromero 275
    CHKERRQ(ierr);
1972 eromero 276
 
1795 eromero 277
    /// Temporal! Postpone the copy of new_cY to cY
278
    data->new_cY = new_cY;
279
    data->size_new_cY = npreconv;
1972 eromero 280
  }
1743 eromero 281
 
1829 eromero 282
  /* BcX <- orth(BcX, B*cX),
283
     auxV = B*X, being X the last converged eigenvectors */
284
  if (d->BcX) for(i=0; i<npreconv; i++) {
285
    /* BcX <- [BcX auxV(i)] */
286
    ierr = VecCopy(d->auxV[i], d->BcX[d->size_cX+i]); CHKERRQ(ierr);
287
    ierr = IPOrthogonalize(d->ipI, 0, PETSC_NULL, d->size_cX+i, PETSC_NULL,
288
                           d->BcX, d->BcX[d->size_cX+i], PETSC_NULL,
289
                           &norm, &lindep); CHKERRQ(ierr);
290
    if(lindep == PETSC_TRUE) {
291
        SETERRQ(1, "Error during orth(BcX, B*cX(new))!");
292
    }
293
    ierr = VecScale(d->BcX[d->size_cX+i], 1.0/norm); CHKERRQ(ierr);
294
  }
295
 
1795 eromero 296
  /* Harmonics restarts wiht right eigenvectors, and other with
297
     the left ones */
1829 eromero 298
  pX = (d->W||!d->cY||d->BcX)?d->pX:d->pY;
299
  ldpX = (d->W||!d->cY||d->BcX)?d->ldpX:d->ldpY;
1795 eromero 300
 
1829 eromero 301
  /* If BcX, f.V <- orth(BcX, f.V) */
302
  if (d->BcX) cMT = 0;
303
  else        cMT = d->size_H - npreconv;
304
 
1795 eromero 305
  /* f.MTX <- pY(npreconv:size_H-1), f.MTY <- f.pY(npreconv:size_H-1) */
306
  d->ldMTX = d->ldMTY = d->size_H;
307
  d->size_MT = d->size_H;
308
  d->MT_type = DVD_MT_ORTHO;
1883 eromero 309
  ierr = SlepcDenseCopy(d->MTX, d->ldMTX, &pX[ldpX*npreconv], ldpX,
310
                        d->size_H, cMT); CHKERRQ(ierr);
1795 eromero 311
  if (d->W && d->pY) {
1883 eromero 312
    ierr = SlepcDenseCopy(d->MTY, d->ldMTY, &d->pY[d->ldpY*npreconv], d->ldpY,
313
                          d->size_H, cMT); CHKERRQ(ierr);
1743 eromero 314
  }
1795 eromero 315
 
316
  /* [f.cX(f.nconv) f.V] <- f.V*[f.pX(0:npreconv-1) f.pY(npreconv:f.size_V-1)] */
317
  if (&d->cX[d->nconv] == d->V) { /* cX and V are contiguous */
318
    ierr = SlepcDenseCopy(pX, ldpX, d->pX, d->ldpX, d->size_H, npreconv);
319
    CHKERRQ(ierr);
320
    ierr = SlepcUpdateVectorsZ(d->V, 0.0, 1.0, d->V, d->size_V, pX,
321
                               ldpX, d->size_H, d->size_H); CHKERRQ(ierr);
322
    d->V+= npreconv;
323
    inc_V = npreconv;
324
    d->max_size_V-= npreconv;
325
  } else {
326
    SETERRQ(1, "Untested case!");
327
    ierr = SlepcUpdateVectorsZ(&d->cX[d->nconv], 0.0, 1.0, d->V, d->size_V,
328
                               d->pX, d->ldpX, d->size_H, npreconv);
329
    CHKERRQ(ierr);
330
    ierr = SlepcUpdateVectorsZ(d->V, 0.0, 1.0, d->V, d->size_V,
331
                               &pX[ldpX*npreconv], ldpX,
332
                               d->size_H, cMT); CHKERRQ(ierr);
333
    inc_V = 0;
1743 eromero 334
  }
1795 eromero 335
  d->size_cX+= npreconv;
336
  d->size_V -= npreconv;
1630 slepc 337
 
1883 eromero 338
  /* Udpate cS and cT, if needed */
339
  if (d->cS) {
340
    PetscInt size_cS = d->size_cX-npreconv;
341
    cX = d->cY?d->cY:d->cX; size_cX = d->cY?d->size_cY:d->size_cX;
342
    cy = d->cY?new_cY:0; size_cy = d->cY?npreconv:0;
343
    ierr =
344
    dvd_updateV_YtWx(&d->cS[d->ldcS*size_cS], d->ldcS, cX, size_cX, cy,
345
                     size_cy, d->AV, d->size_AV,
346
                     d->pX, d->ldpX,
347
                     d->size_H, npreconv, d->auxV); CHKERRQ(ierr);
348
 
349
    if (DVD_ISNOT(d->sEP, DVD_EP_STD)) {if (d->BV) {
350
      ierr =
351
      dvd_updateV_YtWx(&d->cT[d->ldcT*size_cS], d->ldcT, cX, size_cX, cy,
352
                       size_cy, d->BV, d->size_AV,
353
                       d->pX, d->ldpX,
354
                       d->size_H, npreconv, d->auxV); CHKERRQ(ierr);
355
    } else if (!d->B) {
356
      ierr = VecsMultIa(&d->cT[d->ldcT*size_cS], 0, d->ldcT, cX, 0, size_cX,
357
                        &d->cX[size_cS], 0, npreconv); CHKERRQ(ierr);
358
      ierr = VecsMultIa(&d->cT[d->ldcT*size_cS+size_cX], 0, d->ldcT, cy, 0,
359
                        size_cy, &d->cX[size_cS], 0, npreconv); CHKERRQ(ierr);
360
    } else {
361
      /* TODO: Only for nprecond==1 */
362
      ierr = MatMult(d->B, d->cX[d->size_cX-1], d->auxV[0]); CHKERRQ(ierr);
363
      ierr = VecsMultIa(&d->cT[d->ldcT*size_cS], 0, d->ldcT, cX, 0, size_cX,
364
                        &d->auxV[0], 0, npreconv); CHKERRQ(ierr);
365
      ierr = VecsMultIa(&d->cT[d->ldcT*size_cS+size_cX], 0, d->ldcT, cy, 0,
366
                        size_cy, &d->auxV[0], 0, npreconv); CHKERRQ(ierr);
367
    }}
368
  }
369
 
1795 eromero 370
  /* f.W <- f.W * f.MTY */
371
  if (d->W) {
372
    ierr = SlepcUpdateVectorsZ(d->W, 0.0, 1.0, d->W, d->size_V+npreconv,
373
                               d->MTY, d->ldMTY, d->size_H, cMT);
374
    CHKERRQ(ierr);
375
  }
1619 slepc 376
 
1795 eromero 377
  /* Lock the converged pairs */
378
  d->eigr+= npreconv;
379
#ifndef PETSC_USE_COMPLEX
380
  if (d->eigi) d->eigi+= npreconv;
381
#endif
382
  d->nconv+= npreconv;
383
  d->errest+= npreconv;
1619 slepc 384
 
1795 eromero 385
  /* Notify the changes in V and update the other subspaces */
386
  d->V_imm_s = inc_V;             d->V_imm_e = inc_V;
387
  d->V_tra_s = 0;                 d->V_tra_e = cMT;
1829 eromero 388
  d->V_new_s = d->V_tra_e;        d->V_new_e = d->size_V;
1743 eromero 389
 
1795 eromero 390
  /* Remove oldU */
391
  data->size_oldU = 0;
1743 eromero 392
 
1795 eromero 393
  /* f.pX <- I, f.pY <- I */
2021 eromero 394
  d->ldpX = d->size_H;
395
  if (d->pY) d->ldpY = d->size_H;
1795 eromero 396
  for(i=0; i<d->size_H; i++) {
397
    for(j=0; j<d->size_H; j++) {
398
      d->pX[d->ldpX*i+j] = 0.0;
399
      if (d->pY) d->pY[d->ldpY*i+j] = 0.0;
1735 eromero 400
    }
1795 eromero 401
    d->pX[d->ldpX*i+i] = 1.0;
402
    if (d->pY) d->pY[d->ldpY*i+i] = 1.0;
1619 slepc 403
  }
404
 
1795 eromero 405
  d->npreconv-= npreconv;
406
 
1619 slepc 407
  PetscFunctionReturn(0);
408
}
409
 
410
#undef __FUNCT__  
1795 eromero 411
#define __FUNCT__ "dvd_updateV_restart_gen"
412
PetscErrorCode dvd_updateV_restart_gen(dvdDashboard *d)
1750 eromero 413
{
414
  dvdManagV_basic *data = (dvdManagV_basic*)d->updateV_data;
1795 eromero 415
  PetscInt        size_plusk, size_X, new_size_X, i, j;
1750 eromero 416
  PetscErrorCode  ierr;
417
 
418
  PetscFunctionBegin;
419
 
1795 eromero 420
  /* Select size_X desired pairs from V */
421
  size_X = PetscMin(PetscMin(data->min_size_V,
422
                             d->size_V ),
423
                             d->max_size_V );
1750 eromero 424
 
1795 eromero 425
  /* Add plusk eigenvectors from the previous iteration */
426
  size_plusk = PetscMax(0, PetscMin(PetscMin(data->plusk,
427
                                    data->size_oldU ),
428
                                    d->max_size_V - size_X ));
1750 eromero 429
 
1795 eromero 430
  /* Modify the subspaces */
2021 eromero 431
  ierr = d->calcpairs_selectPairs(d, d->size_H); CHKERRQ(ierr);
1751 eromero 432
 
1795 eromero 433
  d->ldMTX = d->size_MT = d->size_V;
434
  ierr = dvd_updateV_restartV_aux(d->V, d->size_V, d->MTX, d->ldMTX, d->pX,
435
                                  d->ldpX, size_X, data->oldU, data->ldoldU,
436
                                  data->size_oldU, size_plusk, d->auxS,
437
                                  d->size_auxS, &new_size_X); CHKERRQ(ierr);
438
  if (d->W && d->pY) {
439
    PetscInt new_size_Y;
440
    d->ldMTY = d->size_V;
441
    ierr = dvd_updateV_restartV_aux(d->W, d->size_V, d->MTY, d->ldMTY, d->pY,
442
                                    d->ldpY, size_X, data->oldV, data->ldoldU,
443
                                    data->size_oldU, new_size_X-size_X,
444
                                    d->auxS, d->size_auxS, &new_size_Y);
445
    CHKERRQ(ierr);
446
    new_size_X = PetscMin(new_size_X, new_size_Y);
447
  }
1751 eromero 448
 
1795 eromero 449
  /* Notify the changes in V and update the other subspaces */
450
  d->size_V = new_size_X;
451
  d->MT_type = DVD_MT_ORTHO;
452
  d->V_imm_s = 0;                 d->V_imm_e = 0;
453
  d->V_tra_s = 0;                 d->V_tra_e = new_size_X;
454
  d->V_new_s = d->V_tra_e;        d->V_new_e = d->V_tra_e;
1750 eromero 455
 
1795 eromero 456
  /* Remove oldU */
457
  data->size_oldU = 0;
1750 eromero 458
 
1934 eromero 459
  /* Remove information about the eigenpairs in V */
460
  /* Delete: eigr, eigi, errest, npreconv */
461
  for(i=0; i<d->size_V; i++)
1984 eromero 462
    d->nR[i] = d->errest[i] = PETSC_MAX;
1934 eromero 463
  d->npreconv = 0;
464
 
1795 eromero 465
  /* f.pX <- I, f.pY <- I */
2021 eromero 466
  d->ldpX = d->size_H;
467
  if (d->pY) d->ldpY = d->size_H;
1795 eromero 468
  for(i=0; i<d->size_H; i++) {
469
    for(j=0; j<d->size_H; j++) {
470
      d->pX[d->ldpX*i+j] = 0.0;
471
      if (d->pY) d->pY[d->ldpY*i+j] = 0.0;
1752 eromero 472
    }
1795 eromero 473
    d->pX[d->ldpX*i+i] = 1.0;
474
    if (d->pY) d->pY[d->ldpY*i+i] = 1.0;
475
  }
1752 eromero 476
 
1934 eromero 477
 
1795 eromero 478
  PetscFunctionReturn(0);
479
}
1750 eromero 480
 
481
 
1795 eromero 482
#undef __FUNCT__  
483
#define __FUNCT__ "dvd_updateV_update_gen"
484
PetscErrorCode dvd_updateV_update_gen(dvdDashboard *d)
485
{
486
  dvdManagV_basic *data = (dvdManagV_basic*)d->updateV_data;
487
  PetscInt        size_D;
488
  PetscErrorCode  ierr;
1750 eromero 489
 
1795 eromero 490
  PetscFunctionBegin;
1750 eromero 491
 
2021 eromero 492
  ierr = d->calcpairs_selectPairs(d, d->size_H); CHKERRQ(ierr);
1750 eromero 493
 
494
  /* Select the desired pairs */
495
  size_D = PetscMin(PetscMin(PetscMin(data->bs,
496
                                      d->size_V ),
497
                                      d->max_size_V-d->size_V ),
498
                                      d->size_H );
499
  if (size_D == 0) {
500
    PetscPrintf(PETSC_COMM_WORLD, "MON: D:%d H:%d\n", size_D, d->size_H);
501
    d->initV(d);
502
    d->calcPairs(d);
503
    //SETERRQ(1, "D == 0!\n");
504
    //PetscFunctionReturn(1);
505
  }
506
 
507
//  PetscPrintf(PETSC_COMM_WORLD, "EIGS: ");
508
//  for(i=0; i<d->size_H; i++) PetscPrintf(PETSC_COMM_WORLD, "%d:%g ", i, d->eigr[i]);
509
//  PetscPrintf(PETSC_COMM_WORLD, "\n");
510
 
511
  /* Fill V with D */
2021 eromero 512
  ierr = d->improveX(d, d->V+d->size_V, d->max_size_V-d->size_V, 0, size_D,
513
                     &size_D); CHKERRQ(ierr);
1750 eromero 514
 
1972 eromero 515
  /* If D is empty, exit */
516
  if (size_D == 0) { PetscFunctionReturn(0); }
1965 eromero 517
 
1750 eromero 518
  /* Get the converged pairs */
2021 eromero 519
  ierr = dvd_updateV_testConv(d, 0, size_D, size_D, d->auxV, d->auxS,
520
                              &d->npreconv); CHKERRQ(ierr);
1750 eromero 521
 
522
  /* Notify the changes in V */
523
  d->size_V+= size_D;
524
  d->size_D = size_D;
525
  d->V_imm_s = 0;                 d->V_imm_e = d->size_V-size_D;
526
  d->V_tra_s = 0;                 d->V_tra_e = 0;
527
  d->V_new_s = d->size_V-size_D;  d->V_new_e = d->size_V;
528
 
529
  /* Save the projected eigenvectors */
530
  if (data->plusk > 0) {
531
    data->ldoldU = data->size_oldU = d->size_H;
1795 eromero 532
    ierr = SlepcDenseCopy(data->oldU, data->ldoldU, d->pX, d->ldpX, d->size_H,
533
                          d->size_H); CHKERRQ(ierr);
534
    if (d->pY && d->W) {
535
      ierr = SlepcDenseCopy(data->oldV, data->ldoldU, d->pY, d->ldpY, d->size_H,
536
                            d->size_H); CHKERRQ(ierr);
1750 eromero 537
    }
538
  }
539
 
540
  PetscFunctionReturn(0);
541
}
542
 
543
 
544
#undef __FUNCT__  
1735 eromero 545
#define __FUNCT__ "dvd_updateV_testConv"
2018 eromero 546
PetscErrorCode dvd_updateV_testConv(dvdDashboard *d, PetscInt s, PetscInt pre,
547
                                    PetscInt e, Vec *auxV, PetscScalar *auxS,
548
                                                      PetscInt *nConv)
1619 slepc 549
{
1735 eromero 550
  PetscInt        i;
1966 eromero 551
#ifndef PETSC_USE_COMPLEX
552
  PetscInt        j;
553
#endif
1735 eromero 554
  PetscReal       norm;
1619 slepc 555
  PetscErrorCode  ierr;
1735 eromero 556
  PetscTruth      conv;
1619 slepc 557
 
558
  PetscFunctionBegin;
559
 
1743 eromero 560
  *nConv = s;
561
  for(i=s, conv=PETSC_TRUE; (conv == PETSC_TRUE) && (i < e); i++) {
1764 eromero 562
    if (i >= pre) {
563
      if ((d->B) && DVD_IS(d->sEP, DVD_EP_STD)) {
2021 eromero 564
        ierr = d->calcpairs_X(d, i, i+1, &auxV[1]); CHKERRQ(ierr);
1764 eromero 565
        ierr = MatMult(d->B, auxV[1], auxV[0]); CHKERRQ(ierr);
566
      }
2021 eromero 567
      ierr = d->calcpairs_residual(d, i, i+1, auxV, auxS, auxV[1]);
568
      CHKERRQ(ierr);
1735 eromero 569
    }
1764 eromero 570
    norm = d->nR[i]/d->nX[i];
1735 eromero 571
    conv = d->testConv(d, d->eigr[i], 0, norm, &d->errest[i]);
572
    if (conv == PETSC_TRUE) *nConv = i+1;
573
  }
1966 eromero 574
 
575
#ifndef PETSC_USE_COMPLEX
576
  /* Enforce converged conjugate conjugate complex eigenpairs */
577
  for(j=0; j<*nConv; j++) if(d->eigi[j] != 0.0) j++;
578
  if(j > *nConv) (*nConv)--;
579
#endif
1743 eromero 580
  for(; i < e; i++) d->errest[i] = -1.0;
581
  for(i=PetscMax(pre, *nConv); i<e; i++) d->nR[i] = -1.0;
1735 eromero 582
 
1619 slepc 583
  PetscFunctionReturn(0);
584
}
585
 
1795 eromero 586
 
587
/*
588
  U <- [pX(0:size_X-1) gs(pX(0:size_X-1), oldpX(0:size_plusk-1))]
589
  V <- V * U,
590
  where
591
  new_size_V, return the new size of V
592
  auxS, auxiliar vector of size 2*ldpX, at least
593
  size_auxS, the size of auxS
594
*/
595
#undef __FUNCT__  
596
#define __FUNCT__ "dvd_updateV_restartV_aux"
597
PetscErrorCode dvd_updateV_restartV_aux(Vec *V, PetscInt size_V,
598
                                        PetscScalar *U, PetscInt ldU,
599
                                        PetscScalar *pX, PetscInt ldpX,
600
                                        PetscInt cpX, PetscScalar *oldpX,
601
                                        PetscInt ldoldpX, PetscInt roldpX,
602
                                        PetscInt coldpX, PetscScalar *auxS,
603
                                        PetscInt size_auxS,
604
                                        PetscInt *new_size_V)
605
{
606
  PetscInt        i, j;
607
  PetscErrorCode  ierr;
608
 
609
  PetscFunctionBegin;
610
 
611
  /* Add the size_X best eigenpairs */
612
  ierr = SlepcDenseCopy(U, ldU, pX, ldpX, size_V, cpX); CHKERRQ(ierr);
613
 
614
  /* Add plusk eigenvectors from the previous iteration */
615
  ierr = SlepcDenseCopy(&U[cpX*ldU], ldU, oldpX, ldoldpX, roldpX, coldpX);
616
  CHKERRQ(ierr);
617
  for(i=cpX; i<cpX+coldpX; i++)
618
    for(j=roldpX; j<size_V; j++)
619
        U[i*ldU+j] = 0.0;
620
 
621
  /* U <- orth(U) */
622
  /// Temporal! Correct sentence: U <- orth(U(0:size_X-1), U(size_X:size_X+size_plusk))
623
  if (coldpX > 0) {
624
    ierr = SlepcDenseOrth(U, ldU, size_V, cpX+coldpX, auxS, size_auxS,
625
                          new_size_V); CHKERRQ(ierr);
626
  } else
627
    *new_size_V = cpX;
628
 
629
  /* V <- V * U */
630
  ierr = SlepcUpdateVectorsZ(V, 0.0, 1.0, V, size_V, U, ldU, size_V,
631
                             *new_size_V); CHKERRQ(ierr);
632
 
633
  PetscFunctionReturn(0);
634
}
635
 
636
/*
1883 eromero 637
  Compute S = [ Y' * W * x
638
                y' * W * x ]
1795 eromero 639
  where
640
  ldS, the leading dimension of S,
641
  cY, number of vectors of Y,
642
  ldy, the leading dimension of y,
643
  ry,cy, rows and columns of y,
644
  cW, number of vectors of W,
645
  ldH, the leading dimension of H,
646
  rH,cH, rows and columns of H,
647
  ldx, the leading dimension of y,
648
  rx,cx, rows and columns of x,
649
  r, a reduction,
650
  sr, a permanent space,
1829 eromero 651
  auxV, array of auxiliar vectors of size cx (at the end, auxV <- W*x),
1795 eromero 652
  auxS, auxiliar scalar vector of size rH*cx.
653
*/
654
#undef __FUNCT__
655
#define __FUNCT__ "dvd_updateV_YtWx"
656
PetscErrorCode dvd_updateV_YtWx(PetscScalar *S, PetscInt ldS,
1883 eromero 657
                                Vec *Y, PetscInt cY, Vec *y, PetscInt cy,
658
                                Vec *W, PetscInt cW, PetscScalar *x,
659
                                PetscInt ldx,
660
                                PetscInt rx, PetscInt cx, Vec *auxV)
1795 eromero 661
{
662
  PetscErrorCode  ierr;
663
 
664
  PetscFunctionBegin;
665
 
666
  /* auxV <- W * x */
667
  ierr = SlepcUpdateVectorsZ(auxV, 0.0, 1.0, W, cW, x, ldx, rx, cx);
668
  CHKERRQ(ierr);
669
 
670
  /* S(0:cY-1, 0:cx-1) <- Y' * auxV */
671
  ierr = VecsMultIa(S, 0, ldS, Y, 0, cY, auxV, 0, cx); CHKERRQ(ierr);
672
 
1883 eromero 673
  /* S(cY:cY+cy-1, 0:cx-1) <- y' * auxV */
674
  ierr = VecsMultIa(&S[cY], 0, ldS, y, 0, cy, auxV, 0, cx); CHKERRQ(ierr);
1795 eromero 675
 
676
  PetscFunctionReturn(0);
677
}
678