Actual source code: qeplin_n1.c
1: /*
3: Linearization for general QEP, companion form 1.
5: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6: SLEPc - Scalable Library for Eigenvalue Problem Computations
7: Copyright (c) 2002-2010, Universidad Politecnica de Valencia, Spain
9: This file is part of SLEPc.
10:
11: SLEPc is free software: you can redistribute it and/or modify it under the
12: terms of version 3 of the GNU Lesser General Public License as published by
13: the Free Software Foundation.
15: SLEPc is distributed in the hope that it will be useful, but WITHOUT ANY
16: WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17: FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
18: more details.
20: You should have received a copy of the GNU Lesser General Public License
21: along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
22: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
23: */
25: #include private/qepimpl.h
26: #include slepceps.h
27: #include linearp.h
29: /*
30: Given the quadratic problem (l^2*M + l*C + K)*x = 0 the following
31: linearization is employed:
33: A*z = l*B*z where A = [ 0 I ] B = [ I 0 ] z = [ x ]
34: [ -K -C ] [ 0 M ] [ l*x ]
35: */
39: PetscErrorCode MatMult_QEPLINEAR_N1A(Mat A,Vec x,Vec y)
40: {
42: QEP_LINEAR *ctx;
43: PetscScalar *px,*py;
44: PetscInt m;
45:
47: MatShellGetContext(A,(void**)&ctx);
48: MatGetLocalSize(ctx->M,&m,PETSC_NULL);
49: VecGetArray(x,&px);
50: VecGetArray(y,&py);
51: VecPlaceArray(ctx->x1,px);
52: VecPlaceArray(ctx->x2,px+m);
53: VecPlaceArray(ctx->y1,py);
54: VecPlaceArray(ctx->y2,py+m);
55: /* y2 = -(K*x1 + C*x2) */
56: MatMult(ctx->K,ctx->x1,ctx->y2);
57: MatMult(ctx->C,ctx->x2,ctx->y1);
58: VecAXPY(ctx->y2,ctx->sfactor,ctx->y1);
59: VecScale(ctx->y2,-1.0);
60: /* y1 = x2 */
61: VecCopy(ctx->x2,ctx->y1);
62: VecResetArray(ctx->x1);
63: VecResetArray(ctx->x2);
64: VecResetArray(ctx->y1);
65: VecResetArray(ctx->y2);
66: VecRestoreArray(x,&px);
67: VecRestoreArray(y,&py);
68: return(0);
69: }
73: PetscErrorCode MatMult_QEPLINEAR_N1B(Mat B,Vec x,Vec y)
74: {
76: QEP_LINEAR *ctx;
77: PetscScalar *px,*py;
78: PetscInt m;
79:
81: MatShellGetContext(B,(void**)&ctx);
82: MatGetLocalSize(ctx->M,&m,PETSC_NULL);
83: VecGetArray(x,&px);
84: VecGetArray(y,&py);
85: VecPlaceArray(ctx->x1,px);
86: VecPlaceArray(ctx->x2,px+m);
87: VecPlaceArray(ctx->y1,py);
88: VecPlaceArray(ctx->y2,py+m);
89: /* y1 = x1 */
90: VecCopy(ctx->x1,ctx->y1);
91: /* y2 = M*x2 */
92: MatMult(ctx->M,ctx->x2,ctx->y2);
93: VecScale(ctx->y2,ctx->sfactor*ctx->sfactor);
94: VecResetArray(ctx->x1);
95: VecResetArray(ctx->x2);
96: VecResetArray(ctx->y1);
97: VecResetArray(ctx->y2);
98: VecRestoreArray(x,&px);
99: VecRestoreArray(y,&py);
100: return(0);
101: }
105: PetscErrorCode MatGetDiagonal_QEPLINEAR_N1A(Mat A,Vec diag)
106: {
108: QEP_LINEAR *ctx;
109: PetscScalar *pd;
110: PetscInt m;
111:
113: MatShellGetContext(A,(void**)&ctx);
114: MatGetLocalSize(ctx->M,&m,PETSC_NULL);
115: VecGetArray(diag,&pd);
116: VecPlaceArray(ctx->x1,pd);
117: VecPlaceArray(ctx->x2,pd+m);
118: VecSet(ctx->x1,0.0);
119: MatGetDiagonal(ctx->C,ctx->x2);
120: VecScale(ctx->x2,-ctx->sfactor);
121: VecResetArray(ctx->x1);
122: VecResetArray(ctx->x2);
123: VecRestoreArray(diag,&pd);
124: return(0);
125: }
129: PetscErrorCode MatGetDiagonal_QEPLINEAR_N1B(Mat B,Vec diag)
130: {
132: QEP_LINEAR *ctx;
133: PetscScalar *pd;
134: PetscInt m;
135:
137: MatShellGetContext(B,(void**)&ctx);
138: MatGetLocalSize(ctx->M,&m,PETSC_NULL);
139: VecGetArray(diag,&pd);
140: VecPlaceArray(ctx->x1,pd);
141: VecPlaceArray(ctx->x2,pd+m);
142: VecSet(ctx->x1,1.0);
143: MatGetDiagonal(ctx->M,ctx->x2);
144: VecScale(ctx->x2,ctx->sfactor*ctx->sfactor);
145: VecResetArray(ctx->x1);
146: VecResetArray(ctx->x2);
147: VecRestoreArray(diag,&pd);
148: return(0);
149: }
153: PetscErrorCode MatCreateExplicit_QEPLINEAR_N1A(MPI_Comm comm,QEP_LINEAR *ctx,Mat *A)
154: {
156: PetscInt M,N,m,n,i,j,row,start,end,ncols,*pos;
157: PetscScalar *svals;
158: const PetscInt *cols;
159: const PetscScalar *vals;
160:
162: MatGetSize(ctx->M,&M,&N);
163: MatGetLocalSize(ctx->M,&m,&n);
164: MatCreate(comm,A);
165: MatSetSizes(*A,m+n,m+n,M+N,M+N);
166: MatSetFromOptions(*A);
167: PetscMalloc(sizeof(PetscInt)*n,&pos);
168: PetscMalloc(sizeof(PetscScalar)*n,&svals);
169: MatGetOwnershipRange(ctx->M,&start,&end);
170: for (i=start;i<end;i++) {
171: row = i + M;
172: MatSetValue(*A,i,i+M,-1.0,INSERT_VALUES);
173: MatGetRow(ctx->K,i,&ncols,&cols,&vals);
174: MatSetValues(*A,1,&row,ncols,cols,vals,INSERT_VALUES);
175: MatRestoreRow(ctx->K,i,&ncols,&cols,&vals);
176: MatGetRow(ctx->C,i,&ncols,&cols,&vals);
177: for (j=0;j<ncols;j++) {
178: pos[j] = cols[j] + M;
179: svals[j] = vals[j]*ctx->sfactor;
180: }
181: MatSetValues(*A,1,&row,ncols,pos,svals,INSERT_VALUES);
182: MatRestoreRow(ctx->C,i,&ncols,&cols,&vals);
183: }
184: PetscFree(pos);
185: PetscFree(svals);
186: MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);
187: MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);
188: MatScale(*A,-1.0);
189: return(0);
190: }
194: PetscErrorCode MatCreateExplicit_QEPLINEAR_N1B(MPI_Comm comm,QEP_LINEAR *ctx,Mat *B)
195: {
197: PetscInt M,N,m,n,i,j,row,start,end,ncols,*pos;
198: PetscScalar *svals;
199: const PetscInt *cols;
200: const PetscScalar *vals;
201:
203: MatGetSize(ctx->M,&M,&N);
204: MatGetLocalSize(ctx->M,&m,&n);
205: MatCreate(comm,B);
206: MatSetSizes(*B,m+n,m+n,M+N,M+N);
207: MatSetFromOptions(*B);
208: PetscMalloc(sizeof(PetscInt)*n,&pos);
209: PetscMalloc(sizeof(PetscScalar)*n,&svals);
210: MatGetOwnershipRange(ctx->M,&start,&end);
211: for (i=start;i<end;i++) {
212: row = i + M;
213: MatSetValue(*B,i,i,1.0,INSERT_VALUES);
214: MatGetRow(ctx->M,i,&ncols,&cols,&vals);
215: for (j=0;j<ncols;j++) {
216: pos[j] = cols[j] + M;
217: svals[j] = vals[j]*ctx->sfactor*ctx->sfactor;
218: }
219: MatSetValues(*B,1,&row,ncols,pos,svals,INSERT_VALUES);
220: MatRestoreRow(ctx->M,i,&ncols,&cols,&vals);
221: }
222: PetscFree(pos);
223: PetscFree(svals);
224: MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);
225: MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);
226: return(0);
227: }