Actual source code: damped_beam.c
slepc-3.7.1 2016-05-27
1: /*
2: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3: SLEPc - Scalable Library for Eigenvalue Problem Computations
4: Copyright (c) 2002-2016, Universitat Politecnica de Valencia, Spain
6: This file is part of SLEPc.
8: SLEPc is free software: you can redistribute it and/or modify it under the
9: terms of version 3 of the GNU Lesser General Public License as published by
10: the Free Software Foundation.
12: SLEPc is distributed in the hope that it will be useful, but WITHOUT ANY
13: WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14: FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
15: more details.
17: You should have received a copy of the GNU Lesser General Public License
18: along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
19: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
20: */
21: /*
22: This example implements one of the problems found at
23: NLEVP: A Collection of Nonlinear Eigenvalue Problems,
24: The University of Manchester.
25: The details of the collection can be found at:
26: [1] T. Betcke et al., "NLEVP: A Collection of Nonlinear Eigenvalue
27: Problems", ACM Trans. Math. Software 39(2), Article 7, 2013.
29: The damped_beam problem is a QEP from the vibrarion analysis of a beam
30: simply supported at both ends and damped in the middle.
31: */
33: static char help[] = "Quadratic eigenproblem from the vibrarion analysis of a beam.\n\n"
34: "The command line options are:\n"
35: " -n <n> ... dimension of the matrices.\n\n";
37: #include <slepcpep.h>
41: int main(int argc,char **argv)
42: {
43: Mat M,Mo,C,K,Ko,A[3]; /* problem matrices */
44: PEP pep; /* polynomial eigenproblem solver context */
45: IS isf,isbc,is;
46: PetscInt n=200,nele,Istart,Iend,i,j,mloc,nloc,bc[2];
47: PetscReal width=0.05,height=0.005,glength=1.0,dlen,EI,area,rho;
48: PetscScalar K1[4],K2[4],K2t[4],K3[4],M1[4],M2[4],M2t[4],M3[4],damp=5.0;
49: PetscBool terse;
52: SlepcInitialize(&argc,&argv,(char*)0,help);
54: PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);
55: nele = n/2;
56: n = 2*nele;
57: PetscPrintf(PETSC_COMM_WORLD,"\nSimply supported beam damped in the middle, n=%D (nele=%D)\n\n",n,nele);
59: dlen = glength/nele;
60: EI = 7e10*width*height*height*height/12.0;
61: area = width*height;
62: rho = 0.674/(area*glength);
64: K1[0] = 12; K1[1] = 6*dlen; K1[2] = 6*dlen; K1[3] = 4*dlen*dlen;
65: K2[0] = -12; K2[1] = 6*dlen; K2[2] = -6*dlen; K2[3] = 2*dlen*dlen;
66: K2t[0] = -12; K2t[1] = -6*dlen; K2t[2] = 6*dlen; K2t[3] = 2*dlen*dlen;
67: K3[0] = 12; K3[1] = -6*dlen; K3[2] = -6*dlen; K3[3] = 4*dlen*dlen;
68: M1[0] = 156; M1[1] = 22*dlen; M1[2] = 22*dlen; M1[3] = 4*dlen*dlen;
69: M2[0] = 54; M2[1] = -13*dlen; M2[2] = 13*dlen; M2[3] = -3*dlen*dlen;
70: M2t[0] = 54; M2t[1] = 13*dlen; M2t[2] = -13*dlen; M2t[3] = -3*dlen*dlen;
71: M3[0] = 156; M3[1] = -22*dlen; M3[2] = -22*dlen; M3[3] = 4*dlen*dlen;
73: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
74: Compute the matrices that define the eigensystem, (k^2*M+k*C+K)x=0
75: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
77: /* K is block-tridiagonal */
78: MatCreate(PETSC_COMM_WORLD,&Ko);
79: MatSetSizes(Ko,PETSC_DECIDE,PETSC_DECIDE,n+2,n+2);
80: MatSetBlockSize(Ko,2);
81: MatSetFromOptions(Ko);
82: MatSetUp(Ko);
83:
84: MatGetOwnershipRange(Ko,&Istart,&Iend);
85: for (i=Istart/2;i<Iend/2;i++) {
86: if (i>0) {
87: j = i-1;
88: MatSetValuesBlocked(Ko,1,&i,1,&j,K2t,ADD_VALUES);
89: MatSetValuesBlocked(Ko,1,&i,1,&i,K3,ADD_VALUES);
90: }
91: if (i<nele) {
92: j = i+1;
93: MatSetValuesBlocked(Ko,1,&i,1,&j,K2,ADD_VALUES);
94: MatSetValuesBlocked(Ko,1,&i,1,&i,K1,ADD_VALUES);
95: }
96: }
97: MatAssemblyBegin(Ko,MAT_FINAL_ASSEMBLY);
98: MatAssemblyEnd(Ko,MAT_FINAL_ASSEMBLY);
99: MatScale(Ko,EI/(dlen*dlen*dlen));
101: /* M is block-tridiagonal */
102: MatCreate(PETSC_COMM_WORLD,&Mo);
103: MatSetSizes(Mo,PETSC_DECIDE,PETSC_DECIDE,n+2,n+2);
104: MatSetBlockSize(Mo,2);
105: MatSetFromOptions(Mo);
106: MatSetUp(Mo);
108: MatGetOwnershipRange(Mo,&Istart,&Iend);
109: for (i=Istart/2;i<Iend/2;i++) {
110: if (i>0) {
111: j = i-1;
112: MatSetValuesBlocked(Mo,1,&i,1,&j,M2t,ADD_VALUES);
113: MatSetValuesBlocked(Mo,1,&i,1,&i,M3,ADD_VALUES);
114: }
115: if (i<nele) {
116: j = i+1;
117: MatSetValuesBlocked(Mo,1,&i,1,&j,M2,ADD_VALUES);
118: MatSetValuesBlocked(Mo,1,&i,1,&i,M1,ADD_VALUES);
119: }
120: }
121: MatAssemblyBegin(Mo,MAT_FINAL_ASSEMBLY);
122: MatAssemblyEnd(Mo,MAT_FINAL_ASSEMBLY);
123: MatScale(Mo,rho*area*dlen/420);
125: /* remove rows/columns from K and M corresponding to boundary conditions */
126: ISCreateStride(PETSC_COMM_WORLD,Iend-Istart,Istart,1,&isf);
127: bc[0] = 0; bc[1] = n;
128: ISCreateGeneral(PETSC_COMM_SELF,2,bc,PETSC_USE_POINTER,&isbc);
129: ISDifference(isf,isbc,&is);
130: MatGetSubMatrix(Ko,is,is,MAT_INITIAL_MATRIX,&K);
131: MatGetSubMatrix(Mo,is,is,MAT_INITIAL_MATRIX,&M);
132: MatGetLocalSize(M,&mloc,&nloc);
134: /* C is zero except for the (nele,nele)-entry */
135: MatCreate(PETSC_COMM_WORLD,&C);
136: MatSetSizes(C,mloc,nloc,PETSC_DECIDE,PETSC_DECIDE);
137: MatSetFromOptions(C);
138: MatSetUp(C);
139:
140: MatGetOwnershipRange(C,&Istart,&Iend);
141: if (nele-1>=Istart && nele-1<Iend) {
142: MatSetValue(C,nele-1,nele-1,damp,INSERT_VALUES);
143: }
144: MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);
145: MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);
146:
147: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
148: Create the eigensolver and solve the problem
149: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
151: PEPCreate(PETSC_COMM_WORLD,&pep);
152: A[0] = K; A[1] = C; A[2] = M;
153: PEPSetOperators(pep,3,A);
154: PEPSetFromOptions(pep);
155: PEPSolve(pep);
157: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
158: Display solution and clean up
159: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
160:
161: /* show detailed info unless -terse option is given by user */
162: PetscOptionsHasName(NULL,NULL,"-terse",&terse);
163: if (terse) {
164: PEPErrorView(pep,PEP_ERROR_BACKWARD,NULL);
165: } else {
166: PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD,PETSC_VIEWER_ASCII_INFO_DETAIL);
167: PEPReasonView(pep,PETSC_VIEWER_STDOUT_WORLD);
168: PEPErrorView(pep,PEP_ERROR_BACKWARD,PETSC_VIEWER_STDOUT_WORLD);
169: PetscViewerPopFormat(PETSC_VIEWER_STDOUT_WORLD);
170: }
171: PEPDestroy(&pep);
172: ISDestroy(&isf);
173: ISDestroy(&isbc);
174: ISDestroy(&is);
175: MatDestroy(&M);
176: MatDestroy(&C);
177: MatDestroy(&K);
178: MatDestroy(&Ko);
179: MatDestroy(&Mo);
180: SlepcFinalize();
181: return ierr;
182: }