| Line 75... |
Line 75... |
*thetai; /* the shifts used in the correction eq. */
|
*thetai; /* the shifts used in the correction eq. */
|
PetscInt maxits, /* maximum number of iterations */
|
PetscInt maxits, /* maximum number of iterations */
|
r_s, r_e, /* the selected eigenpairs to improve */
|
r_s, r_e, /* the selected eigenpairs to improve */
|
ksp_max_size; /* the ksp maximum subvectors size */
|
ksp_max_size; /* the ksp maximum subvectors size */
|
PetscReal tol, /* the maximum solution tolerance */
|
PetscReal tol, /* the maximum solution tolerance */
|
|
lastTol, /* last tol for dynamic stopping criterion */
|
fix; /* tolerance for using the approx. eigenvalue */
|
fix; /* tolerance for using the approx. eigenvalue */
|
|
PetscBool
|
|
dynamic; /* if the dynamic stopping criterion is applied */
|
dvdDashboard
|
dvdDashboard
|
*d; /* the currect dvdDashboard reference */
|
*d; /* the currect dvdDashboard reference */
|
PC old_pc; /* old pc in ksp */
|
PC old_pc; /* old pc in ksp */
|
Vec
|
Vec
|
*u, /* new X vectors */
|
*u, /* new X vectors */
|
| Line 104... |
Line 107... |
#define FromIntToScalar(S) (_Ceil((S)*sizeof(PetscBLASInt),sizeof(PetscScalar)))
|
#define FromIntToScalar(S) (_Ceil((S)*sizeof(PetscBLASInt),sizeof(PetscScalar)))
|
|
|
#undef __FUNCT__
|
#undef __FUNCT__
|
#define __FUNCT__ "dvd_improvex_jd"
|
#define __FUNCT__ "dvd_improvex_jd"
|
PetscErrorCode dvd_improvex_jd(dvdDashboard *d, dvdBlackboard *b, KSP ksp,
|
PetscErrorCode dvd_improvex_jd(dvdDashboard *d, dvdBlackboard *b, KSP ksp,
|
PetscInt max_bs, PetscInt cX_impr)
|
PetscInt max_bs, PetscInt cX_impr, PetscBool dynamic)
|
{
|
{
|
PetscErrorCode ierr;
|
PetscErrorCode ierr;
|
dvdImprovex_jd *data;
|
dvdImprovex_jd *data;
|
PetscBool t, herm = DVD_IS(d->sEP, DVD_EP_HERMITIAN)?PETSC_TRUE:PETSC_FALSE;
|
PetscBool t, herm = DVD_IS(d->sEP, DVD_EP_HERMITIAN)?PETSC_TRUE:PETSC_FALSE;
|
PC pc;
|
PC pc;
|
| Line 156... |
Line 159... |
}
|
}
|
|
|
/* Setup the step */
|
/* Setup the step */
|
if (b->state >= DVD_STATE_CONF) {
|
if (b->state >= DVD_STATE_CONF) {
|
ierr = PetscMalloc(sizeof(dvdImprovex_jd), &data); CHKERRQ(ierr);
|
ierr = PetscMalloc(sizeof(dvdImprovex_jd), &data); CHKERRQ(ierr);
|
|
data->dynamic = dynamic;
|
data->size_real_KZ = size_P;
|
data->size_real_KZ = size_P;
|
data->real_KZ = b->free_vecs; b->free_vecs+= data->size_real_KZ;
|
data->real_KZ = b->free_vecs; b->free_vecs+= data->size_real_KZ;
|
d->max_size_cX_in_impr = cX_impr;
|
d->max_size_cX_in_impr = cX_impr;
|
data->XKZ = b->free_scalars; b->free_scalars+= size_P*size_P;
|
data->XKZ = b->free_scalars; b->free_scalars+= size_P*size_P;
|
data->ldXKZ = size_P;
|
data->ldXKZ = size_P;
|
| Line 194... |
Line 198... |
|
|
PetscFunctionBegin;
|
PetscFunctionBegin;
|
|
|
data->KZ = data->real_KZ;
|
data->KZ = data->real_KZ;
|
data->size_KZ = data->size_cX = data->old_size_X = 0;
|
data->size_KZ = data->size_cX = data->old_size_X = 0;
|
|
data->lastTol = data->dynamic?0.5:0.0;
|
|
|
/* Setup the ksp */
|
/* Setup the ksp */
|
if(data->ksp) {
|
if(data->ksp) {
|
/* Create the reference vector */
|
/* Create the reference vector */
|
ierr = VecCreateCompWithVecs(d->V, data->ksp_max_size, PETSC_NULL,
|
ierr = VecCreateCompWithVecs(d->V, data->ksp_max_size, PETSC_NULL,
|
| Line 205... |
Line 210... |
|
|
/* Save the current pc and set a PCNONE */
|
/* Save the current pc and set a PCNONE */
|
ierr = KSPGetPC(data->ksp, &data->old_pc); CHKERRQ(ierr);
|
ierr = KSPGetPC(data->ksp, &data->old_pc); CHKERRQ(ierr);
|
ierr = PetscTypeCompare((PetscObject)data->old_pc, PCNONE, &t);
|
ierr = PetscTypeCompare((PetscObject)data->old_pc, PCNONE, &t);
|
CHKERRQ(ierr);
|
CHKERRQ(ierr);
|
|
data->lastTol = 0.5;
|
if (t) {
|
if (t) {
|
data->old_pc = 0;
|
data->old_pc = 0;
|
} else {
|
} else {
|
ierr = PetscObjectReference((PetscObject)data->old_pc); CHKERRQ(ierr);
|
ierr = PetscObjectReference((PetscObject)data->old_pc); CHKERRQ(ierr);
|
ierr = PCCreate(((PetscObject)d->eps)->comm, &pc); CHKERRQ(ierr);
|
ierr = PCCreate(((PetscObject)d->eps)->comm, &pc); CHKERRQ(ierr);
|
| Line 330... |
Line 336... |
pY = auxS; auxS+= d->size_H*d->size_H;
|
pY = auxS; auxS+= d->size_H*d->size_H;
|
ierr = dvd_improvex_get_eigenvectors(d, pX, pY, d->size_H, auxS,
|
ierr = dvd_improvex_get_eigenvectors(d, pX, pY, d->size_H, auxS,
|
d->size_auxS-(auxS-d->auxS));
|
d->size_auxS-(auxS-d->auxS));
|
CHKERRQ(ierr);
|
CHKERRQ(ierr);
|
}
|
}
|
|
|
|
/* Restart lastTol if a new pair converged */
|
|
if (data->dynamic && data->size_cX < d->size_cX)
|
|
data->lastTol = 0.5;
|
|
|
for(i=0, s=0, auxS0=auxS; i<n; i+=s) {
|
for(i=0, s=0, auxS0=auxS; i<n; i+=s) {
|
/* If the selected eigenvalue is complex, but the arithmetic is real... */
|
/* If the selected eigenvalue is complex, but the arithmetic is real... */
|
#if !defined(PETSC_USE_COMPLEX)
|
#if !defined(PETSC_USE_COMPLEX)
|
if (PetscAbsScalar(d->eigi[i] != 0.0)) {
|
if (PetscAbsScalar(d->eigi[i] != 0.0)) {
|
| Line 362... |
Line 372... |
ierr = d->improvex_jd_lit(d, r_s+i+j, &data->theta[2*j],
|
ierr = d->improvex_jd_lit(d, r_s+i+j, &data->theta[2*j],
|
&data->thetai[j], &maxits0, &tol0);
|
&data->thetai[j], &maxits0, &tol0);
|
CHKERRQ(ierr);
|
CHKERRQ(ierr);
|
maxits+= maxits0; tol*= tol0;
|
maxits+= maxits0; tol*= tol0;
|
}
|
}
|
maxits/= s; tol = exp(log(tol)/s);
|
maxits/= s; tol = data->dynamic?data->lastTol:exp(log(tol)/s);
|
|
|
/* Compute u, v and kr */
|
/* Compute u, v and kr */
|
ierr = dvd_improvex_jd_proj_cuv(d, r_s+i, r_s+i+s, &u, &v, kr,
|
ierr = dvd_improvex_jd_proj_cuv(d, r_s+i, r_s+i+s, &u, &v, kr,
|
&data->auxV, &auxS, data->theta, data->thetai,
|
&data->auxV, &auxS, data->theta, data->thetai,
|
&pX[d->size_H*(r_s+i+d->cX_in_H)], &pY[d->size_H*(r_s+i+d->cX_in_H)], d->size_H);
|
&pX[d->size_H*(r_s+i+d->cX_in_H)], &pY[d->size_H*(r_s+i+d->cX_in_H)], d->size_H);
|
| Line 410... |
Line 420... |
ierr = VecDestroy(&kr_comp); CHKERRQ(ierr);
|
ierr = VecDestroy(&kr_comp); CHKERRQ(ierr);
|
ierr = VecDestroy(&D_comp); CHKERRQ(ierr);
|
ierr = VecDestroy(&D_comp); CHKERRQ(ierr);
|
}
|
}
|
}
|
}
|
*size_D = i;
|
*size_D = i;
|
|
if (data->dynamic) data->lastTol = PetscMax(data->lastTol/2.0,PETSC_MACHINE_EPSILON*10.0);
|
|
|
/* Callback old improveX */
|
/* Callback old improveX */
|
if (data->old_improveX) {
|
if (data->old_improveX) {
|
d->improveX_data = data->old_improveX_data;
|
d->improveX_data = data->old_improveX_data;
|
data->old_improveX(d, PETSC_NULL, 0, 0, 0, PETSC_NULL);
|
data->old_improveX(d, PETSC_NULL, 0, 0, 0, PETSC_NULL);
|