1
/*$Id: eige.c,v 1.35 2001/08/07 03:03:45 balay Exp $*/
3
#include "src/sles/ksp/kspimpl.h" /*I "petscksp.h" I*/
6
#define __FUNCT__ "KSPComputeExplicitOperator"
8
KSPComputeExplicitOperator - Computes the explicit preconditioned operator.
13
. ksp - the Krylov subspace context
16
. mat - the explict preconditioned operator
19
This computation is done by applying the operators to columns of the
22
Currently, this routine uses a dense matrix format when 1 processor
23
is used and a sparse format otherwise. This routine is costly in general,
24
and is recommended for use only with relatively small systems.
28
.keywords: KSP, compute, explicit, operator
30
.seealso: KSPComputeEigenvaluesExplicitly()
32
int KSPComputeExplicitOperator(KSP ksp,Mat *mat)
35
int ierr,i,M,m,size,*rows,start,end;
38
PetscScalar *array,zero = 0.0,one = 1.0;
41
PetscValidHeaderSpecific(ksp,KSP_COOKIE);
42
PetscValidPointer(mat);
45
ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
47
ierr = VecDuplicate(ksp->vec_sol,&in);CHKERRQ(ierr);
48
ierr = VecDuplicate(ksp->vec_sol,&out);CHKERRQ(ierr);
49
ierr = VecGetSize(in,&M);CHKERRQ(ierr);
50
ierr = VecGetLocalSize(in,&m);CHKERRQ(ierr);
51
ierr = VecGetOwnershipRange(in,&start,&end);CHKERRQ(ierr);
52
ierr = PetscMalloc((m+1)*sizeof(int),&rows);CHKERRQ(ierr);
53
for (i=0; i<m; i++) {rows[i] = start + i;}
56
ierr = MatCreateSeqDense(comm,M,M,PETSC_NULL,mat);CHKERRQ(ierr);
58
/* ierr = MatCreateMPIDense(comm,m,M,M,M,PETSC_NULL,mat);CHKERRQ(ierr); */
59
ierr = MatCreateMPIAIJ(comm,m,m,M,M,0,0,0,0,mat);CHKERRQ(ierr);
62
ierr = PCGetOperators(ksp->B,&A,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
66
ierr = VecSet(&zero,in);CHKERRQ(ierr);
67
ierr = VecSetValues(in,1,&i,&one,INSERT_VALUES);CHKERRQ(ierr);
68
ierr = VecAssemblyBegin(in);CHKERRQ(ierr);
69
ierr = VecAssemblyEnd(in);CHKERRQ(ierr);
71
ierr = KSP_MatMult(ksp,A,in,out);CHKERRQ(ierr);
72
ierr = KSP_PCApply(ksp,ksp->B,out,in);CHKERRQ(ierr);
74
ierr = VecGetArray(in,&array);CHKERRQ(ierr);
75
ierr = MatSetValues(*mat,m,rows,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
76
ierr = VecRestoreArray(in,&array);CHKERRQ(ierr);
79
ierr = PetscFree(rows);CHKERRQ(ierr);
80
ierr = VecDestroy(in);CHKERRQ(ierr);
81
ierr = VecDestroy(out);CHKERRQ(ierr);
82
ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
83
ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
84
PetscFunctionReturn(0);
87
#include "petscblaslapack.h"
90
#define __FUNCT__ "KSPComputeEigenvaluesExplicitly"
92
KSPComputeEigenvaluesExplicitly - Computes all of the eigenvalues of the
93
preconditioned operator using LAPACK.
98
+ ksp - iterative context obtained from KSPCreate()
99
- n - size of arrays r and c
102
+ r - real part of computed eigenvalues
103
- c - complex part of computed eigenvalues
106
This approach is very slow but will generally provide accurate eigenvalue
107
estimates. This routine explicitly forms a dense matrix representing
108
the preconditioned operator, and thus will run only for relatively small
109
problems, say n < 500.
111
Many users may just want to use the monitoring routine
112
KSPSingularValueMonitor() (which can be set with option -ksp_singmonitor)
113
to print the singular values at each iteration of the linear solve.
117
.keywords: KSP, compute, eigenvalues, explicitly
119
.seealso: KSPComputeEigenvalues(), KSPSingularValueMonitor(), KSPComputeExtremeSingularValues()
121
int KSPComputeEigenvaluesExplicitly(KSP ksp,int nmax,PetscReal *r,PetscReal *c)
124
int i,n,ierr,size,rank,dummy;
125
MPI_Comm comm = ksp->comm;
132
ierr = KSPComputeExplicitOperator(ksp,&BA);CHKERRQ(ierr);
133
ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
134
ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
136
ierr = MatGetSize(BA,&n,&n);CHKERRQ(ierr);
137
if (size > 1) { /* assemble matrix on first processor */
139
ierr = MatCreateMPIDense(ksp->comm,n,n,n,n,PETSC_NULL,&A);CHKERRQ(ierr);
142
ierr = MatCreateMPIDense(ksp->comm,0,n,n,n,PETSC_NULL,&A);CHKERRQ(ierr);
144
PetscLogObjectParent(BA,A);
146
ierr = MatGetOwnershipRange(BA,&row,&dummy);CHKERRQ(ierr);
147
ierr = MatGetLocalSize(BA,&m,&dummy);CHKERRQ(ierr);
148
for (i=0; i<m; i++) {
149
ierr = MatGetRow(BA,row,&nz,&cols,&vals);CHKERRQ(ierr);
150
ierr = MatSetValues(A,1,&row,nz,cols,vals,INSERT_VALUES);CHKERRQ(ierr);
151
ierr = MatRestoreRow(BA,row,&nz,&cols,&vals);CHKERRQ(ierr);
155
ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
156
ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
157
ierr = MatGetArray(A,&array);CHKERRQ(ierr);
159
ierr = MatGetArray(BA,&array);CHKERRQ(ierr);
162
#if defined(PETSC_HAVE_ESSL)
163
/* ESSL has a different calling sequence for dgeev() and zgeev() than standard LAPACK */
165
PetscScalar sdummy,*cwork;
166
PetscReal *work,*realpart;
167
int clen,idummy,lwork,*perm,zero;
169
#if !defined(PETSC_USE_COMPLEX)
174
ierr = PetscMalloc(clen*sizeof(PetscScalar),&cwork);CHKERRQ(ierr);
177
ierr = PetscMalloc(lwork*sizeof(PetscReal),&work);CHKERRQ(ierr);
178
ierr = PetscMalloc(n*sizeof(PetscReal),&realpart);CHKERRQ(ierr);
180
LAgeev_(&zero,array,&n,cwork,&sdummy,&idummy,&idummy,&n,work,&lwork);
181
ierr = PetscFree(work);CHKERRQ(ierr);
183
/* For now we stick with the convention of storing the real and imaginary
184
components of evalues separately. But is this what we really want? */
185
ierr = PetscMalloc(n*sizeof(int),&perm);CHKERRQ(ierr);
187
#if !defined(PETSC_USE_COMPLEX)
188
for (i=0; i<n; i++) {
189
realpart[i] = cwork[2*i];
192
ierr = PetscSortRealWithPermutation(n,realpart,perm);CHKERRQ(ierr);
193
for (i=0; i<n; i++) {
194
r[i] = cwork[2*perm[i]];
195
c[i] = cwork[2*perm[i]+1];
198
for (i=0; i<n; i++) {
199
realpart[i] = PetscRealPart(cwork[i]);
202
ierr = PetscSortRealWithPermutation(n,realpart,perm);CHKERRQ(ierr);
203
for (i=0; i<n; i++) {
204
r[i] = PetscRealPart(cwork[perm[i]]);
205
c[i] = PetscImaginaryPart(cwork[perm[i]]);
208
ierr = PetscFree(perm);CHKERRQ(ierr);
209
ierr = PetscFree(realpart);CHKERRQ(ierr);
210
ierr = PetscFree(cwork);CHKERRQ(ierr);
212
#elif !defined(PETSC_USE_COMPLEX)
214
PetscScalar *work,sdummy;
215
PetscReal *realpart,*imagpart;
216
int idummy,lwork,*perm;
220
ierr = PetscMalloc(2*n*sizeof(PetscReal),&realpart);CHKERRQ(ierr);
221
imagpart = realpart + n;
222
ierr = PetscMalloc(5*n*sizeof(PetscReal),&work);CHKERRQ(ierr);
223
#if defined(PETSC_MISSING_LAPACK_GEEV)
224
SETERRQ(PETSC_ERR_SUP,"GEEV - Lapack routine is unavilable\nNot able to provide eigen values.");
226
LAgeev_("N","N",&n,array,&n,realpart,imagpart,&sdummy,&idummy,&sdummy,&idummy,work,&lwork,&ierr);
228
if (ierr) SETERRQ1(PETSC_ERR_LIB,"Error in LAPACK routine %d",ierr);
229
ierr = PetscFree(work);CHKERRQ(ierr);
230
ierr = PetscMalloc(n*sizeof(int),&perm);CHKERRQ(ierr);
231
for (i=0; i<n; i++) { perm[i] = i;}
232
ierr = PetscSortRealWithPermutation(n,realpart,perm);CHKERRQ(ierr);
233
for (i=0; i<n; i++) {
234
r[i] = realpart[perm[i]];
235
c[i] = imagpart[perm[i]];
237
ierr = PetscFree(perm);CHKERRQ(ierr);
238
ierr = PetscFree(realpart);CHKERRQ(ierr);
242
PetscScalar *work,sdummy,*eigs;
244
int idummy,lwork,*perm;
248
ierr = PetscMalloc(5*n*sizeof(PetscScalar),&work);CHKERRQ(ierr);
249
ierr = PetscMalloc(2*n*sizeof(PetscReal),&rwork);CHKERRQ(ierr);
250
ierr = PetscMalloc(n*sizeof(PetscScalar),&eigs);CHKERRQ(ierr);
251
#if defined(PETSC_MISSING_LAPACK_GEEV)
252
SETERRQ(PETSC_ERR_SUP,"GEEV - Lapack routine is unavilable\nNot able to provide eigen values.");
254
LAgeev_("N","N",&n,array,&n,eigs,&sdummy,&idummy,&sdummy,&idummy,work,&lwork,rwork,&ierr);
256
if (ierr) SETERRQ1(PETSC_ERR_LIB,"Error in LAPACK routine %d",ierr);
257
ierr = PetscFree(work);CHKERRQ(ierr);
258
ierr = PetscFree(rwork);CHKERRQ(ierr);
259
ierr = PetscMalloc(n*sizeof(int),&perm);CHKERRQ(ierr);
260
for (i=0; i<n; i++) { perm[i] = i;}
261
for (i=0; i<n; i++) { r[i] = PetscRealPart(eigs[i]);}
262
ierr = PetscSortRealWithPermutation(n,r,perm);CHKERRQ(ierr);
263
for (i=0; i<n; i++) {
264
r[i] = PetscRealPart(eigs[perm[i]]);
265
c[i] = PetscImaginaryPart(eigs[perm[i]]);
267
ierr = PetscFree(perm);CHKERRQ(ierr);
268
ierr = PetscFree(eigs);CHKERRQ(ierr);
272
ierr = MatRestoreArray(A,&array);CHKERRQ(ierr);
273
ierr = MatDestroy(A);CHKERRQ(ierr);
275
ierr = MatRestoreArray(BA,&array);CHKERRQ(ierr);
277
ierr = MatDestroy(BA);CHKERRQ(ierr);
278
PetscFunctionReturn(0);