Actual source code: ex54.c


  2: static char help[] = "Creates a matrix from quadrilateral finite elements in 2D, Laplacian \n\
  3:   -ne <size>       : problem size in number of elements (eg, -ne 31 gives 32^2 grid)\n\
  4:   -alpha <v>      : scaling of material coeficient in embedded circle\n\n";

  6: #include <petscksp.h>

  8: int main(int argc,char **args)
  9: {
 10:   Mat            Amat,Pmat;
 12:   PetscInt       i,m,M,its,Istart,Iend,j,Ii,ix,ne=4;
 13:   PetscReal      x,y,h;
 14:   Vec            xx,bb;
 15:   KSP            ksp;
 16:   PetscReal      soft_alpha = 1.e-3;
 17:   MPI_Comm       comm;
 18:   PetscMPIInt    npe,mype;
 19:   PetscScalar    DD[4][4],DD2[4][4];
 20: #if defined(PETSC_USE_LOG)
 21:   PetscLogStage stage;
 22: #endif
 23: #define DIAG_S 0.0
 24:   PetscScalar DD1[4][4] = { {5.0+DIAG_S, -2.0, -1.0, -2.0},
 25:                             {-2.0, 5.0+DIAG_S, -2.0, -1.0},
 26:                             {-1.0, -2.0, 5.0+DIAG_S, -2.0},
 27:                             {-2.0, -1.0, -2.0, 5.0+DIAG_S} };

 29:   PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr;
 30:   comm = PETSC_COMM_WORLD;
 31:   MPI_Comm_rank(comm, &mype);
 32:   MPI_Comm_size(comm, &npe);
 33:   PetscOptionsGetInt(NULL,NULL,"-ne",&ne,NULL);
 34:   h     = 1./ne;
 35:   /* ne*ne; number of global elements */
 36:   PetscOptionsGetReal(NULL,NULL,"-alpha",&soft_alpha,NULL);
 37:   M    = (ne+1)*(ne+1); /* global number of nodes */

 39:   /* create stiffness matrix (2) */
 40:   MatCreate(comm,&Amat);
 41:   MatSetSizes(Amat,PETSC_DECIDE,PETSC_DECIDE,M,M);
 42:   MatSetType(Amat,MATAIJ);
 43:   MatSetOption(Amat,MAT_SPD,PETSC_TRUE);
 44:   MatSetFromOptions(Amat);
 45:   MatSeqAIJSetPreallocation(Amat,81,NULL);
 46:   MatMPIAIJSetPreallocation(Amat,81,NULL,57,NULL);

 48:   MatCreate(comm,&Pmat);
 49:   MatSetSizes(Pmat,PETSC_DECIDE,PETSC_DECIDE,M,M);
 50:   MatSetType(Pmat,MATMPIAIJ);
 51:   MatSetFromOptions(Pmat);
 52:   MatSeqAIJSetPreallocation(Pmat,81,NULL);
 53:   MatMPIAIJSetPreallocation(Pmat,81,NULL,57,NULL);

 55:   /* vectors */
 56:   MatCreateVecs(Amat,&bb,&xx);
 57:   VecSet(bb,.0);
 58:   /* generate element matrices -- see ex56.c on how to use different data set */
 59:   {
 60:     DD1[0][0] =  0.66666666666666663;
 61:     DD1[0][1] = -0.16666666666666669;
 62:     DD1[0][2] = -0.33333333333333343;
 63:     DD1[0][3] = -0.16666666666666666;
 64:     DD1[1][0] = -0.16666666666666669;
 65:     DD1[1][1] =  0.66666666666666663;
 66:     DD1[1][2] = -0.16666666666666666;
 67:     DD1[1][3] = -0.33333333333333343;
 68:     DD1[2][0] = -0.33333333333333343;
 69:     DD1[2][1] = -0.16666666666666666;
 70:     DD1[2][2] =  0.66666666666666663;
 71:     DD1[2][3] = -0.16666666666666663;
 72:     DD1[3][0] = -0.16666666666666666;
 73:     DD1[3][1] = -0.33333333333333343;
 74:     DD1[3][2] = -0.16666666666666663;
 75:     DD1[3][3] =  0.66666666666666663;

 77:     /* BC version of element */
 78:     for (i=0;i<4;i++) {
 79:       for (j=0;j<4;j++) {
 80:         if (i<2 || j < 2) {
 81:           if (i==j) DD2[i][j] = .1*DD1[i][j];
 82:           else DD2[i][j] = 0.0;
 83:         } else DD2[i][j] = DD1[i][j];
 84:       }
 85:     }
 86:   }
 87:   {
 88:     PetscReal *coords;
 89:     PC             pc;
 90:     /* forms the element stiffness for the Laplacian and coordinates */
 91:     MatGetOwnershipRange(Amat,&Istart,&Iend);
 92:     m    = Iend-Istart;
 93:     PetscMalloc1(2*m,&coords);
 94:     for (Ii=Istart,ix=0; Ii<Iend; Ii++,ix++) {
 95:       j = Ii/(ne+1); i = Ii%(ne+1);
 96:       /* coords */
 97:       x            = h*(Ii % (ne+1)); y = h*(Ii/(ne+1));
 98:       coords[2*ix] = x; coords[2*ix+1] = y;
 99:       if (i<ne && j<ne) {
100:         PetscInt jj,ii,idx[4];
101:         /* radius */
102:         PetscReal radius = PetscSqrtReal((x-.5+h/2)*(x-.5+h/2) + (y-.5+h/2)*(y-.5+h/2));
103:         PetscReal alpha  = 1.0;
104:         idx[0] = Ii; idx[1] = Ii+1; idx[2] = Ii + (ne+1) + 1; idx[3] =  Ii + (ne+1);
105:         if (radius < 0.25) alpha = soft_alpha;
106:         for (ii=0; ii<4; ii++) {
107:           for (jj=0; jj<4; jj++) DD[ii][jj] = alpha*DD1[ii][jj];
108:         }
109:         MatSetValues(Pmat,4,idx,4,idx,(const PetscScalar*)DD,ADD_VALUES);
110:         if (j>0) {
111:           MatSetValues(Amat,4,idx,4,idx,(const PetscScalar*)DD,ADD_VALUES);
112:         } else {
113:           /* a BC */
114:           for (ii=0;ii<4;ii++) {
115:             for (jj=0;jj<4;jj++) DD[ii][jj] = alpha*DD2[ii][jj];
116:           }
117:           MatSetValues(Amat,4,idx,4,idx,(const PetscScalar*)DD,ADD_VALUES);
118:         }
119:       }
120:       if (j>0) {
121:         PetscScalar v  = h*h;
122:         PetscInt    jj = Ii;
123:         VecSetValues(bb,1,&jj,&v,INSERT_VALUES);
124:       }
125:     }
126:     MatAssemblyBegin(Amat,MAT_FINAL_ASSEMBLY);
127:     MatAssemblyEnd(Amat,MAT_FINAL_ASSEMBLY);
128:     MatAssemblyBegin(Pmat,MAT_FINAL_ASSEMBLY);
129:     MatAssemblyEnd(Pmat,MAT_FINAL_ASSEMBLY);
130:     VecAssemblyBegin(bb);
131:     VecAssemblyEnd(bb);

133:     /* Setup solver */
134:     KSPCreate(PETSC_COMM_WORLD,&ksp);
135:     KSPSetFromOptions(ksp);

137:     /* finish KSP/PC setup */
138:     KSPSetOperators(ksp, Amat, Amat);

140:     KSPGetPC(ksp,&pc);
141:     PCSetCoordinates(pc, 2, m, coords);
142:     PetscFree(coords);
143:   }

145:   if (!PETSC_TRUE) {
146:     PetscViewer viewer;
147:     PetscViewerASCIIOpen(comm, "Amat.m", &viewer);
148:     PetscViewerPushFormat(viewer, PETSC_VIEWER_ASCII_MATLAB);
149:     MatView(Amat,viewer);
150:     PetscViewerPopFormat(viewer);
151:     PetscViewerDestroy(&viewer);
152:   }

154:   /* solve */
155: #if defined(PETSC_USE_LOG)
156:   PetscLogStageRegister("Solve", &stage);
157:   PetscLogStagePush(stage);
158: #endif
159:   VecSet(xx,.0);

161:   KSPSetUp(ksp);

163:   KSPSolve(ksp,bb,xx);

165: #if defined(PETSC_USE_LOG)
166:   PetscLogStagePop();
167: #endif

169:   KSPGetIterationNumber(ksp,&its);

171:   if (!PETSC_TRUE) {
172:     PetscReal   norm,norm2;
173:     PetscViewer viewer;
174:     Vec         res;
175:     PetscViewerASCIIOpen(comm, "rhs.m", &viewer);
176:     PetscViewerPushFormat(viewer, PETSC_VIEWER_ASCII_MATLAB);
177:     VecView(bb,viewer);
178:     PetscViewerPopFormat(viewer);
179:     PetscViewerDestroy(&viewer);
180:     VecNorm(bb, NORM_2, &norm2);

182:     PetscViewerASCIIOpen(comm, "solution.m", &viewer);
183:     PetscViewerPushFormat(viewer, PETSC_VIEWER_ASCII_MATLAB);
184:     VecView(xx,viewer);
185:     PetscViewerPopFormat(viewer);
186:     PetscViewerDestroy(&viewer);

188:     VecDuplicate(xx, &res);
189:     MatMult(Amat, xx, res);
190:     VecAXPY(bb, -1.0, res);
191:     VecDestroy(&res);
192:     VecNorm(bb,NORM_2,&norm);
193:     PetscPrintf(PETSC_COMM_WORLD,"[%d]%s |b-Ax|/|b|=%e, |b|=%e\n",0,PETSC_FUNCTION_NAME,norm/norm2,norm2);

195:     PetscViewerASCIIOpen(comm, "residual.m", &viewer);
196:     PetscViewerPushFormat(viewer, PETSC_VIEWER_ASCII_MATLAB);
197:     VecView(bb,viewer);
198:     PetscViewerPopFormat(viewer);
199:     PetscViewerDestroy(&viewer);
200:   }

202:   /* Free work space */
203:   KSPDestroy(&ksp);
204:   VecDestroy(&xx);
205:   VecDestroy(&bb);
206:   MatDestroy(&Amat);
207:   MatDestroy(&Pmat);

209:   PetscFinalize();
210:   return ierr;
211: }



215: /*TEST

217:    build:
218:       requires: !complex

220:    test:
221:       nsize: 4
222:       args: -ne 19 -alpha 1.e-3 -pc_type gamg -pc_gamg_agg_nsmooths 1  -mg_levels_ksp_max_it 3 -ksp_monitor -ksp_converged_reason -ksp_type cg

224:    test:
225:       suffix: seqaijmkl
226:       nsize: 4
227:       requires: mkl_sparse
228:       args: -ne 19 -alpha 1.e-3 -pc_type gamg -pc_gamg_agg_nsmooths 1  -mg_levels_ksp_max_it 3 -ksp_monitor -ksp_converged_reason -ksp_type cg -mat_seqaij_type seqaijmkl

230:    test:
231:       suffix: Classical
232:       args: -ne 49 -alpha 1.e-3 -ksp_type cg -pc_type gamg -pc_gamg_type classical -mg_levels_ksp_chebyshev_esteig 0,0.05,0,1.05 -ksp_converged_reason
233:       output_file: output/ex54_classical.out

235:    test:
236:       suffix: geo
237:       nsize: 4
238:       args: -ne 49 -alpha 1.e-3 -ksp_type cg -pc_type gamg -pc_gamg_type geo -pc_gamg_coarse_eq_limit 200 -mg_levels_pc_type jacobi -mg_levels_ksp_chebyshev_esteig 0,0.05,0,1.05 -ksp_monitor_short -mg_levels_ksp_max_it 3
239:       requires: triangle
240:       output_file: output/ex54_0.out

242: TEST*/