Actual source code: ex42.c
petsc-3.3-p0 2012-06-05
1: static char help[] =
2: "Solves the incompressible, variable viscosity stokes equation in 3d using Q1Q1 elements, \n\
3: stabilized with Bochev's polynomial projection method. Note that implementation here assumes \n\
4: all boundaries are free-slip, i.e. zero normal flow and zero tangential stress \n\
5: -mx : number elements in x-direction \n\
6: -my : number elements in y-direction \n\
7: -mz : number elements in z-direction \n\
8: -stokes_ksp_monitor_blocks : active monitor for each component u,v,w,p \n\
9: -model : defines viscosity and forcing function. Choose either: 0 (isoviscous), 1 (manufactured-broken), 2 (solcx-2d), 3 (sinker) \n" ;
11: /* Contributed by Dave May */
13: #include petscksp.h
14: #include petscpcmg.h
15: #include petscdmda.h
17: #define PROFILE_TIMING
18: #define ASSEMBLE_LOWER_TRIANGULAR
20: #define NSD 3 /* number of spatial dimensions */
21: #define NODES_PER_EL 8 /* nodes per element */
22: #define U_DOFS 3 /* degrees of freedom per velocity node */
23: #define P_DOFS 1 /* degrees of freedom per pressure node */
24: #define GAUSS_POINTS 8
26: /* Gauss point based evaluation */
27: typedef struct {
28: PetscScalar gp_coords[NSD*GAUSS_POINTS];
29: PetscScalar eta[GAUSS_POINTS];
30: PetscScalar fx[GAUSS_POINTS];
31: PetscScalar fy[GAUSS_POINTS];
32: PetscScalar fz[GAUSS_POINTS];
33: PetscScalar hc[GAUSS_POINTS];
34: } GaussPointCoefficients;
36: typedef struct {
37: PetscScalar u_dof;
38: PetscScalar v_dof;
39: PetscScalar w_dof;
40: PetscScalar p_dof;
41: } StokesDOF;
43: typedef struct _p_CellProperties *CellProperties;
44: struct _p_CellProperties {
45: PetscInt ncells;
46: PetscInt mx,my,mz;
47: PetscInt sex,sey,sez;
48: GaussPointCoefficients *gpc;
49: };
51: static PetscErrorCode DMDAGetElementCorners(DM da,PetscInt *sx,PetscInt *sy,PetscInt *sz,PetscInt *mx,PetscInt *my,PetscInt *mz) ;
53: /* elements */
56: PetscErrorCode CellPropertiesCreate(DM da_stokes,CellProperties *C)
57: {
59: CellProperties cells;
60: PetscInt mx,my,mz,sex,sey,sez;
61:
63: PetscMalloc (sizeof (struct _p_CellProperties ),&cells);
64:
65: DMDAGetElementCorners(da_stokes,&sex,&sey,&sez,&mx,&my,&mz);
66: cells->mx = mx;
67: cells->my = my;
68: cells->mz = mz;
69: cells->ncells = mx * my * mz;
70: cells->sex = sex;
71: cells->sey = sey;
72: cells->sez = sez;
73: PetscMalloc (sizeof (GaussPointCoefficients)*mx*my*mz,&cells->gpc);
74:
75: *C = cells;
76: return (0);
77: }
81: PetscErrorCode CellPropertiesDestroy(CellProperties *C)
82: {
84: CellProperties cells;
87: if (!C) { return (0); }
88: cells = *C;
89: PetscFree (cells->gpc);
90: PetscFree (cells);
91: *C = PETSC_NULL ;
92: return (0);
93: }
97: PetscErrorCode CellPropertiesGetCell(CellProperties C,PetscInt I,PetscInt J,PetscInt K,GaussPointCoefficients **G)
98: {
100: *G = &C->gpc[ (I-C->sex) + (J-C->sey)*C->mx + (K-C->sez)*C->mx*C->my ];
101: return (0);
102: }
104: /* FEM routines */
105: /*
106: Element: Local basis function ordering
107: 1-----2
108: | |
109: | |
110: 0-----3
111: */
112: static void ShapeFunctionQ13D_Evaluate(PetscScalar _xi[],PetscScalar Ni[])
113: {
114: PetscReal xi = PetscRealPart(_xi[0]);
115: PetscReal eta = PetscRealPart(_xi[1]);
116: PetscReal zeta = PetscRealPart(_xi[2]);
118: Ni[0] = 0.125 * ( 1.0 - xi ) * ( 1.0 - eta ) * ( 1.0 - zeta );
119: Ni[1] = 0.125 * ( 1.0 - xi ) * ( 1.0 + eta ) * ( 1.0 - zeta );
120: Ni[2] = 0.125 * ( 1.0 + xi ) * ( 1.0 + eta ) * ( 1.0 - zeta );
121: Ni[3] = 0.125 * ( 1.0 + xi ) * ( 1.0 - eta ) * ( 1.0 - zeta );
123: Ni[4] = 0.125 * ( 1.0 - xi ) * ( 1.0 - eta ) * ( 1.0 + zeta );
124: Ni[5] = 0.125 * ( 1.0 - xi ) * ( 1.0 + eta ) * ( 1.0 + zeta );
125: Ni[6] = 0.125 * ( 1.0 + xi ) * ( 1.0 + eta ) * ( 1.0 + zeta );
126: Ni[7] = 0.125 * ( 1.0 + xi ) * ( 1.0 - eta ) * ( 1.0 + zeta );
127: }
129: static void ShapeFunctionQ13D_Evaluate_dxi(PetscScalar _xi[],PetscScalar GNi[][NODES_PER_EL])
130: {
131: PetscReal xi = PetscRealPart(_xi[0]);
132: PetscReal eta = PetscRealPart(_xi[1]);
133: PetscReal zeta = PetscRealPart(_xi[2]);
134: /* xi deriv */
135: GNi[0][0] = - 0.125 * ( 1.0 - eta ) * ( 1.0 - zeta );
136: GNi[0][1] = - 0.125 * ( 1.0 + eta ) * ( 1.0 - zeta );
137: GNi[0][2] = 0.125 * ( 1.0 + eta ) * ( 1.0 - zeta );
138: GNi[0][3] = 0.125 * ( 1.0 - eta ) * ( 1.0 - zeta );
140: GNi[0][4] = - 0.125 * ( 1.0 - eta ) * ( 1.0 + zeta );
141: GNi[0][5] = - 0.125 * ( 1.0 + eta ) * ( 1.0 + zeta );
142: GNi[0][6] = 0.125 * ( 1.0 + eta ) * ( 1.0 + zeta );
143: GNi[0][7] = 0.125 * ( 1.0 - eta ) * ( 1.0 + zeta );
144: /* eta deriv */
145: GNi[1][0] = - 0.125 * ( 1.0 - xi ) * ( 1.0 - zeta );
146: GNi[1][1] = 0.125 * ( 1.0 - xi ) * ( 1.0 - zeta );
147: GNi[1][2] = 0.125 * ( 1.0 + xi ) * ( 1.0 - zeta );
148: GNi[1][3] = - 0.125 * ( 1.0 + xi ) * ( 1.0 - zeta );
150: GNi[1][4] = - 0.125 * ( 1.0 - xi ) * ( 1.0 + zeta );
151: GNi[1][5] = 0.125 * ( 1.0 - xi ) * ( 1.0 + zeta );
152: GNi[1][6] = 0.125 * ( 1.0 + xi ) * ( 1.0 + zeta );
153: GNi[1][7] = - 0.125 * ( 1.0 + xi ) * ( 1.0 + zeta );
154: /* zeta deriv */
155: GNi[2][0] = -0.125 * ( 1.0 - xi ) * ( 1.0 - eta );
156: GNi[2][1] = -0.125 * ( 1.0 - xi ) * ( 1.0 + eta );
157: GNi[2][2] = -0.125 * ( 1.0 + xi ) * ( 1.0 + eta );
158: GNi[2][3] = -0.125 * ( 1.0 + xi ) * ( 1.0 - eta );
160: GNi[2][4] = 0.125 * ( 1.0 - xi ) * ( 1.0 - eta );
161: GNi[2][5] = 0.125 * ( 1.0 - xi ) * ( 1.0 + eta );
162: GNi[2][6] = 0.125 * ( 1.0 + xi ) * ( 1.0 + eta );
163: GNi[2][7] = 0.125 * ( 1.0 + xi ) * ( 1.0 - eta );
164: }
166: static void matrix_inverse_3x3(PetscScalar A[3][3],PetscScalar B[3][3])
167: {
168: PetscScalar t4, t6, t8, t10, t12, t14, t17;
170: t4 = A[2][0] * A[0][1];
171: t6 = A[2][0] * A[0][2];
172: t8 = A[1][0] * A[0][1];
173: t10 = A[1][0] * A[0][2];
174: t12 = A[0][0] * A[1][1];
175: t14 = A[0][0] * A[1][2];
176: t17 = 0.1e1 / (t4 * A[1][2] - t6 * A[1][1] - t8 * A[2][2] + t10 * A[2][1] + t12 * A[2][2] - t14 * A[2][1]);
178: B[0][0] = (A[1][1] * A[2][2] - A[1][2] * A[2][1]) * t17;
179: B[0][1] = -(A[0][1] * A[2][2] - A[0][2] * A[2][1]) * t17;
180: B[0][2] = (A[0][1] * A[1][2] - A[0][2] * A[1][1]) * t17;
181: B[1][0] = -(-A[2][0] * A[1][2] + A[1][0] * A[2][2]) * t17;
182: B[1][1] = (-t6 + A[0][0] * A[2][2]) * t17;
183: B[1][2] = -(-t10 + t14) * t17;
184: B[2][0] = (-A[2][0] * A[1][1] + A[1][0] * A[2][1]) * t17;
185: B[2][1] = -(-t4 + A[0][0] * A[2][1]) * t17;
186: B[2][2] = (-t8 + t12) * t17;
187: }
189: static void ShapeFunctionQ13D_Evaluate_dx(PetscScalar GNi[][NODES_PER_EL],PetscScalar GNx[][NODES_PER_EL],PetscScalar coords[],PetscScalar *det_J)
190: {
191: PetscScalar J00,J01,J02,J10,J11,J12,J20,J21,J22;
192: PetscInt n;
193: PetscScalar iJ[3][3],JJ[3][3];
195: J00 = J01 = J02 = 0.0;
196: J10 = J11 = J12 = 0.0;
197: J20 = J21 = J22 = 0.0;
198: for (n=0; n<NODES_PER_EL; n++) {
199: PetscScalar cx = coords[ NSD*n + 0 ];
200: PetscScalar cy = coords[ NSD*n + 1 ];
201: PetscScalar cz = coords[ NSD*n + 2 ];
203: /* J_ij = d(x_j) / d(xi_i) */ /* J_ij = \sum _I GNi[j][I} * x_i */
204: J00 = J00 + GNi[0][n] * cx; /* J_xx */
205: J01 = J01 + GNi[0][n] * cy; /* J_xy = dx/deta */
206: J02 = J02 + GNi[0][n] * cz; /* J_xz = dx/dzeta */
208: J10 = J10 + GNi[1][n] * cx; /* J_yx = dy/dxi */
209: J11 = J11 + GNi[1][n] * cy; /* J_yy */
210: J12 = J12 + GNi[1][n] * cz; /* J_yz */
212: J20 = J20 + GNi[2][n] * cx; /* J_zx */
213: J21 = J21 + GNi[2][n] * cy; /* J_zy */
214: J22 = J22 + GNi[2][n] * cz; /* J_zz */
215: }
217: JJ[0][0] = J00; JJ[0][1] = J01; JJ[0][2] = J02;
218: JJ[1][0] = J10; JJ[1][1] = J11; JJ[1][2] = J12;
219: JJ[2][0] = J20; JJ[2][1] = J21; JJ[2][2] = J22;
221: matrix_inverse_3x3(JJ,iJ);
223: *det_J = J00*J11*J22 - J00*J12*J21 - J10*J01*J22 + J10*J02*J21 + J20*J01*J12 - J20*J02*J11;
225: for (n=0; n<NODES_PER_EL; n++) {
226: GNx[0][n] = GNi[0][n]*iJ[0][0] + GNi[1][n]*iJ[0][1] + GNi[2][n]*iJ[0][2];
227: GNx[1][n] = GNi[0][n]*iJ[1][0] + GNi[1][n]*iJ[1][1] + GNi[2][n]*iJ[1][2];
228: GNx[2][n] = GNi[0][n]*iJ[2][0] + GNi[1][n]*iJ[2][1] + GNi[2][n]*iJ[2][2];
229: }
230: }
232: static void ConstructGaussQuadrature3D(PetscInt *ngp,PetscScalar gp_xi[][NSD],PetscScalar gp_weight[])
233: {
234: *ngp = 8;
235: gp_xi[0][0] = -0.57735026919; gp_xi[0][1] = -0.57735026919; gp_xi[0][2] = -0.57735026919;
236: gp_xi[1][0] = -0.57735026919; gp_xi[1][1] = 0.57735026919; gp_xi[1][2] = -0.57735026919;
237: gp_xi[2][0] = 0.57735026919; gp_xi[2][1] = 0.57735026919; gp_xi[2][2] = -0.57735026919;
238: gp_xi[3][0] = 0.57735026919; gp_xi[3][1] = -0.57735026919; gp_xi[3][2] = -0.57735026919;
240: gp_xi[4][0] = -0.57735026919; gp_xi[4][1] = -0.57735026919; gp_xi[4][2] = 0.57735026919;
241: gp_xi[5][0] = -0.57735026919; gp_xi[5][1] = 0.57735026919; gp_xi[5][2] = 0.57735026919;
242: gp_xi[6][0] = 0.57735026919; gp_xi[6][1] = 0.57735026919; gp_xi[6][2] = 0.57735026919;
243: gp_xi[7][0] = 0.57735026919; gp_xi[7][1] = -0.57735026919; gp_xi[7][2] = 0.57735026919;
245: gp_weight[0] = 1.0;
246: gp_weight[1] = 1.0;
247: gp_weight[2] = 1.0;
248: gp_weight[3] = 1.0;
250: gp_weight[4] = 1.0;
251: gp_weight[5] = 1.0;
252: gp_weight[6] = 1.0;
253: gp_weight[7] = 1.0;
254: }
256: /* procs to the left claim the ghost node as their element */
259: static PetscErrorCode DMDAGetLocalElementSize(DM da,PetscInt *mxl,PetscInt *myl,PetscInt *mzl)
260: {
261: PetscInt m,n,p,M,N,P;
262: PetscInt sx,sy,sz;
266: DMDAGetInfo (da,0,&M,&N,&P,0,0,0,0,0,0,0,0,0);
267: DMDAGetCorners (da,&sx,&sy,&sz,&m,&n,&p);
269: if (mxl) {
270: *mxl = m;
271: if ((sx+m) == M) { /* last proc */
272: *mxl = m-1;
273: }
274: }
275: if (myl) {
276: *myl = n;
277: if ((sy+n) == N) { /* last proc */
278: *myl = n-1;
279: }
280: }
281: if (mzl) {
282: *mzl = p;
283: if ((sz+p) == P) { /* last proc */
284: *mzl = p-1;
285: }
286: }
287: return (0);
288: }
292: static PetscErrorCode DMDAGetElementCorners(DM da,PetscInt *sx,PetscInt *sy,PetscInt *sz,PetscInt *mx,PetscInt *my,PetscInt *mz)
293: {
294: PetscInt si,sj,sk;
298: DMDAGetGhostCorners (da,&si,&sj,&sk,0,0,0);
300: if (sx) {
301: *sx = si;
302: if (si != 0) {
303: *sx = si+1;
304: }
305: }
306: if (sy) {
307: *sy = sj;
308: if (sj != 0) {
309: *sy = sj+1;
310: }
311: }
312: if (sz) {
313: *sz = sk;
314: if (sk != 0) {
315: *sz = sk+1;
316: }
317: }
318: DMDAGetLocalElementSize(da,mx,my,mz);
319: return (0);
320: }
322: /*
323: i,j are the element indices
324: The unknown is a vector quantity.
325: The s[].c is used to indicate the degree of freedom.
326: */
329: static PetscErrorCode DMDAGetElementEqnums3D_up(MatStencil s_u[],MatStencil s_p[],PetscInt i,PetscInt j,PetscInt k)
330: {
331: PetscInt n;
333: /* velocity */
334: n = 0;
335: /* node 0 */
336: s_u[n].i = i; s_u[n].j = j; s_u[n].k = k; s_u[n].c = 0; n++; /* Vx0 */
337: s_u[n].i = i; s_u[n].j = j; s_u[n].k = k; s_u[n].c = 1; n++; /* Vy0 */
338: s_u[n].i = i; s_u[n].j = j; s_u[n].k = k; s_u[n].c = 2; n++; /* Vz0 */
340: s_u[n].i = i; s_u[n].j = j+1; s_u[n].k = k; s_u[n].c = 0; n++;
341: s_u[n].i = i; s_u[n].j = j+1; s_u[n].k = k; s_u[n].c = 1; n++;
342: s_u[n].i = i; s_u[n].j = j+1; s_u[n].k = k; s_u[n].c = 2; n++;
344: s_u[n].i = i+1; s_u[n].j = j+1; s_u[n].k = k; s_u[n].c = 0; n++;
345: s_u[n].i = i+1; s_u[n].j = j+1; s_u[n].k = k; s_u[n].c = 1; n++;
346: s_u[n].i = i+1; s_u[n].j = j+1; s_u[n].k = k; s_u[n].c = 2; n++;
348: s_u[n].i = i+1; s_u[n].j = j; s_u[n].k = k; s_u[n].c = 0; n++;
349: s_u[n].i = i+1; s_u[n].j = j; s_u[n].k = k; s_u[n].c = 1; n++;
350: s_u[n].i = i+1; s_u[n].j = j; s_u[n].k = k; s_u[n].c = 2; n++;
352: /* */
353: s_u[n].i = i; s_u[n].j = j; s_u[n].k = k+1; s_u[n].c = 0; n++; /* Vx4 */
354: s_u[n].i = i; s_u[n].j = j; s_u[n].k = k+1; s_u[n].c = 1; n++; /* Vy4 */
355: s_u[n].i = i; s_u[n].j = j; s_u[n].k = k+1; s_u[n].c = 2; n++; /* Vz4 */
357: s_u[n].i = i; s_u[n].j = j+1; s_u[n].k = k+1; s_u[n].c = 0; n++;
358: s_u[n].i = i; s_u[n].j = j+1; s_u[n].k = k+1; s_u[n].c = 1; n++;
359: s_u[n].i = i; s_u[n].j = j+1; s_u[n].k = k+1; s_u[n].c = 2; n++;
361: s_u[n].i = i+1; s_u[n].j = j+1; s_u[n].k = k+1; s_u[n].c = 0; n++;
362: s_u[n].i = i+1; s_u[n].j = j+1; s_u[n].k = k+1; s_u[n].c = 1; n++;
363: s_u[n].i = i+1; s_u[n].j = j+1; s_u[n].k = k+1; s_u[n].c = 2; n++;
365: s_u[n].i = i+1; s_u[n].j = j; s_u[n].k = k+1; s_u[n].c = 0; n++;
366: s_u[n].i = i+1; s_u[n].j = j; s_u[n].k = k+1; s_u[n].c = 1; n++;
367: s_u[n].i = i+1; s_u[n].j = j; s_u[n].k = k+1; s_u[n].c = 2; n++;
369: /* pressure */
370: n = 0;
371: s_p[n].i = i; s_p[n].j = j; s_p[n].k = k; s_p[n].c = 3; n++; /* P0 */
372: s_p[n].i = i; s_p[n].j = j+1; s_p[n].k = k; s_p[n].c = 3; n++;
373: s_p[n].i = i+1; s_p[n].j = j+1; s_p[n].k = k; s_p[n].c = 3; n++;
374: s_p[n].i = i+1; s_p[n].j = j; s_p[n].k = k; s_p[n].c = 3; n++;
376: s_p[n].i = i; s_p[n].j = j; s_p[n].k = k+1; s_p[n].c = 3; n++; /* P0 */
377: s_p[n].i = i; s_p[n].j = j+1; s_p[n].k = k+1; s_p[n].c = 3; n++;
378: s_p[n].i = i+1; s_p[n].j = j+1; s_p[n].k = k+1; s_p[n].c = 3; n++;
379: s_p[n].i = i+1; s_p[n].j = j; s_p[n].k = k+1; s_p[n].c = 3; n++;
380: return (0);
381: }
385: static PetscErrorCode GetElementCoords3D(DMDACoor3d ***coords,PetscInt i,PetscInt j,PetscInt k,PetscScalar el_coord[])
386: {
388: /* get coords for the element */
389: el_coord[0] = coords[k ][j ][i ].x;
390: el_coord[1] = coords[k ][j ][i ].y;
391: el_coord[2] = coords[k ][j ][i ].z;
393: el_coord[3] = coords[k ][j+1][i].x;
394: el_coord[4] = coords[k ][j+1][i].y;
395: el_coord[5] = coords[k ][j+1][i].z;
397: el_coord[6] = coords[k ][j+1][i+1].x;
398: el_coord[7] = coords[k ][j+1][i+1].y;
399: el_coord[8] = coords[k ][j+1][i+1].z;
401: el_coord[9 ] = coords[k ][j ][i+1].x;
402: el_coord[10] = coords[k ][j ][i+1].y;
403: el_coord[11] = coords[k ][j ][i+1].z;
405: el_coord[12] = coords[k+1][j ][i ].x;
406: el_coord[13] = coords[k+1][j ][i ].y;
407: el_coord[14] = coords[k+1][j ][i ].z;
409: el_coord[15] = coords[k+1][j+1][i ].x;
410: el_coord[16] = coords[k+1][j+1][i ].y;
411: el_coord[17] = coords[k+1][j+1][i ].z;
413: el_coord[18] = coords[k+1][j+1][i+1].x;
414: el_coord[19] = coords[k+1][j+1][i+1].y;
415: el_coord[20] = coords[k+1][j+1][i+1].z;
417: el_coord[21] = coords[k+1][j ][i+1].x;
418: el_coord[22] = coords[k+1][j ][i+1].y;
419: el_coord[23] = coords[k+1][j ][i+1].z;
420: return (0);
421: }
425: static PetscErrorCode StokesDAGetNodalFields3D(StokesDOF ***field,PetscInt i,PetscInt j,PetscInt k,StokesDOF nodal_fields[])
426: {
428: /* get the nodal fields for u */
429: nodal_fields[0].u_dof = field[k ][j ][i ].u_dof;
430: nodal_fields[0].v_dof = field[k ][j ][i ].v_dof;
431: nodal_fields[0].w_dof = field[k ][j ][i ].w_dof;
433: nodal_fields[1].u_dof = field[k ][j+1][i ].u_dof;
434: nodal_fields[1].v_dof = field[k ][j+1][i ].v_dof;
435: nodal_fields[1].w_dof = field[k ][j+1][i ].w_dof;
437: nodal_fields[2].u_dof = field[k ][j+1][i+1].u_dof;
438: nodal_fields[2].v_dof = field[k ][j+1][i+1].v_dof;
439: nodal_fields[2].w_dof = field[k ][j+1][i+1].w_dof;
441: nodal_fields[3].u_dof = field[k ][j ][i+1].u_dof;
442: nodal_fields[3].v_dof = field[k ][j ][i+1].v_dof;
443: nodal_fields[3].w_dof = field[k ][j ][i+1].w_dof;
445: nodal_fields[4].u_dof = field[k+1][j ][i ].u_dof;
446: nodal_fields[4].v_dof = field[k+1][j ][i ].v_dof;
447: nodal_fields[4].w_dof = field[k+1][j ][i ].w_dof;
449: nodal_fields[5].u_dof = field[k+1][j+1][i ].u_dof;
450: nodal_fields[5].v_dof = field[k+1][j+1][i ].v_dof;
451: nodal_fields[5].w_dof = field[k+1][j+1][i ].w_dof;
453: nodal_fields[6].u_dof = field[k+1][j+1][i+1].u_dof;
454: nodal_fields[6].v_dof = field[k+1][j+1][i+1].v_dof;
455: nodal_fields[6].w_dof = field[k+1][j+1][i+1].w_dof;
457: nodal_fields[7].u_dof = field[k+1][j ][i+1].u_dof;
458: nodal_fields[7].v_dof = field[k+1][j ][i+1].v_dof;
459: nodal_fields[7].w_dof = field[k+1][j ][i+1].w_dof;
461: /* get the nodal fields for p */
462: nodal_fields[0].p_dof = field[k ][j ][i ].p_dof;
463: nodal_fields[1].p_dof = field[k ][j+1][i ].p_dof;
464: nodal_fields[2].p_dof = field[k ][j+1][i+1].p_dof;
465: nodal_fields[3].p_dof = field[k ][j ][i+1].p_dof;
467: nodal_fields[4].p_dof = field[k+1][j ][i ].p_dof;
468: nodal_fields[5].p_dof = field[k+1][j+1][i ].p_dof;
469: nodal_fields[6].p_dof = field[k+1][j+1][i+1].p_dof;
470: nodal_fields[7].p_dof = field[k+1][j ][i+1].p_dof;
471: return (0);
472: }
474: static PetscInt ASS_MAP_wIwDI_uJuDJ(
475: PetscInt wi,PetscInt wd,PetscInt w_NPE,PetscInt w_dof,
476: PetscInt ui,PetscInt ud,PetscInt u_NPE,PetscInt u_dof)
477: {
478: PetscInt ij;
479: PETSC_UNUSED PetscInt r,c,nr,nc;
481: nr = w_NPE*w_dof;
482: nc = u_NPE*u_dof;
484: r = w_dof*wi+wd;
485: c = u_dof*ui+ud;
487: ij = r*nc+c;
489: return ij;
490: }
494: static PetscErrorCode DMDASetValuesLocalStencil3D_ADD_VALUES(StokesDOF ***fields_F,MatStencil u_eqn[],MatStencil p_eqn[],PetscScalar Fe_u[],PetscScalar Fe_p[])
495: {
496: PetscInt n,I,J,K;
499: for (n = 0; n<NODES_PER_EL; n++) {
500: I = u_eqn[NSD*n ].i;
501: J = u_eqn[NSD*n ].j;
502: K = u_eqn[NSD*n ].k;
503: fields_F[K][J][I].u_dof = fields_F[K][J][I].u_dof+Fe_u[NSD*n ];
505: I = u_eqn[NSD*n+1].i;
506: J = u_eqn[NSD*n+1].j;
507: K = u_eqn[NSD*n+1].k;
508: fields_F[K][J][I].v_dof = fields_F[K][J][I].v_dof+Fe_u[NSD*n+1];
510: I = u_eqn[NSD*n+2].i;
511: J = u_eqn[NSD*n+2].j;
512: K = u_eqn[NSD*n+2].k;
513: fields_F[K][J][I].w_dof = fields_F[K][J][I].w_dof+Fe_u[NSD*n+2];
515: I = p_eqn[n].i;
516: J = p_eqn[n].j;
517: K = p_eqn[n].k;
518: fields_F[K][J][I].p_dof = fields_F[K][J][I].p_dof+Fe_p[n ];
520: }
521: return (0);
522: }
524: static void FormStressOperatorQ13D(PetscScalar Ke[],PetscScalar coords[],PetscScalar eta[])
525: {
526: PetscInt ngp;
527: PetscScalar gp_xi[GAUSS_POINTS][NSD];
528: PetscScalar gp_weight[GAUSS_POINTS];
529: PetscInt p,i,j,k;
530: PetscScalar GNi_p[NSD][NODES_PER_EL],GNx_p[NSD][NODES_PER_EL];
531: PetscScalar J_p,tildeD[6];
532: PetscScalar B[6][U_DOFS*NODES_PER_EL];
533: const PetscInt nvdof = U_DOFS*NODES_PER_EL;
535: /* define quadrature rule */
536: ConstructGaussQuadrature3D(&ngp,gp_xi,gp_weight);
538: /* evaluate integral */
539: for (p = 0; p < ngp; p++) {
540: ShapeFunctionQ13D_Evaluate_dxi(gp_xi[p],GNi_p);
541: ShapeFunctionQ13D_Evaluate_dx(GNi_p,GNx_p,coords,&J_p);
543: for (i = 0; i < NODES_PER_EL; i++) {
544: PetscScalar d_dx_i = GNx_p[0][i];
545: PetscScalar d_dy_i = GNx_p[1][i];
546: PetscScalar d_dz_i = GNx_p[2][i];
548: B[0][3*i ] = d_dx_i; B[0][3*i+1] = 0.0; B[0][3*i+2] = 0.0;
549: B[1][3*i ] = 0.0; B[1][3*i+1] = d_dy_i; B[1][3*i+2] = 0.0;
550: B[2][3*i ] = 0.0; B[2][3*i+1] = 0.0; B[2][3*i+2] = d_dz_i;
552: B[3][3*i] = d_dy_i; B[3][3*i+1] = d_dx_i; B[3][3*i+2] = 0.0; /* e_xy */
553: B[4][3*i] = d_dz_i; B[4][3*i+1] = 0.0; B[4][3*i+2] = d_dx_i;/* e_xz */
554: B[5][3*i] = 0.0; B[5][3*i+1] = d_dz_i; B[5][3*i+2] = d_dy_i;/* e_yz */
555: }
558: tildeD[0] = 2.0*gp_weight[p]*J_p*eta[p];
559: tildeD[1] = 2.0*gp_weight[p]*J_p*eta[p];
560: tildeD[2] = 2.0*gp_weight[p]*J_p*eta[p];
562: tildeD[3] = gp_weight[p]*J_p*eta[p];
563: tildeD[4] = gp_weight[p]*J_p*eta[p];
564: tildeD[5] = gp_weight[p]*J_p*eta[p];
566: /* form Bt tildeD B */
567: /*
568: Ke_ij = Bt_ik . D_kl . B_lj
569: = B_ki . D_kl . B_lj
570: = B_ki . D_kk . B_kj
571: */
572: for (i = 0; i < nvdof; i++) {
573: for (j = i; j < nvdof; j++) {
574: for (k = 0; k < 6; k++) {
575: Ke[i*nvdof+j] += B[k][i]*tildeD[k]*B[k][j];
576: }
577: }
578: }
580: }
581: /* fill lower triangular part */
582: #ifdef ASSEMBLE_LOWER_TRIANGULAR
583: for (i = 0; i < nvdof; i++) {
584: for (j = i; j < nvdof; j++) {
585: Ke[j*nvdof+i] = Ke[i*nvdof+j];
586: }
587: }
588: #endif
589: }
591: static void FormGradientOperatorQ13D(PetscScalar Ke[],PetscScalar coords[])
592: {
593: PetscInt ngp;
594: PetscScalar gp_xi[GAUSS_POINTS][NSD];
595: PetscScalar gp_weight[GAUSS_POINTS];
596: PetscInt p,i,j,di;
597: PetscScalar Ni_p[NODES_PER_EL];
598: PetscScalar GNi_p[NSD][NODES_PER_EL],GNx_p[NSD][NODES_PER_EL];
599: PetscScalar J_p,fac;
601: /* define quadrature rule */
602: ConstructGaussQuadrature3D(&ngp,gp_xi,gp_weight);
604: /* evaluate integral */
605: for (p = 0; p < ngp; p++) {
606: ShapeFunctionQ13D_Evaluate(gp_xi[p],Ni_p);
607: ShapeFunctionQ13D_Evaluate_dxi(gp_xi[p],GNi_p);
608: ShapeFunctionQ13D_Evaluate_dx(GNi_p,GNx_p,coords,&J_p);
609: fac = gp_weight[p]*J_p;
611: for (i = 0; i < NODES_PER_EL; i++) { /* u nodes */
612: for (di = 0; di < NSD; di++) { /* u dofs */
613: for (j = 0; j < NODES_PER_EL; j++) { /* p nodes, p dofs = 1 (ie no loop) */
614: PetscInt IJ;
615: IJ = ASS_MAP_wIwDI_uJuDJ(i,di,NODES_PER_EL,3,j,0,NODES_PER_EL,1);
617: Ke[IJ] = Ke[IJ]-GNx_p[di][i]*Ni_p[j]*fac;
618: }
619: }
620: }
621: }
622: }
624: static void FormDivergenceOperatorQ13D(PetscScalar De[],PetscScalar coords[])
625: {
626: PetscScalar Ge[U_DOFS*NODES_PER_EL*P_DOFS*NODES_PER_EL];
627: PetscInt i,j;
628: PetscInt nr_g,nc_g;
630: PetscMemzero (Ge,sizeof (PetscScalar )*U_DOFS*NODES_PER_EL*P_DOFS*NODES_PER_EL);
631: FormGradientOperatorQ13D(Ge,coords);
633: nr_g = U_DOFS*NODES_PER_EL;
634: nc_g = P_DOFS*NODES_PER_EL;
636: for (i = 0; i < nr_g; i++) {
637: for (j = 0; j < nc_g; j++) {
638: De[nr_g*j+i] = Ge[nc_g*i+j];
639: }
640: }
641: }
643: static void FormStabilisationOperatorQ13D(PetscScalar Ke[],PetscScalar coords[],PetscScalar eta[])
644: {
645: PetscInt ngp;
646: PetscScalar gp_xi[GAUSS_POINTS][NSD];
647: PetscScalar gp_weight[GAUSS_POINTS];
648: PetscInt p,i,j;
649: PetscScalar Ni_p[NODES_PER_EL];
650: PetscScalar GNi_p[NSD][NODES_PER_EL],GNx_p[NSD][NODES_PER_EL];
651: PetscScalar J_p,fac,eta_avg;
653: /* define quadrature rule */
654: ConstructGaussQuadrature3D(&ngp,gp_xi,gp_weight);
656: /* evaluate integral */
657: for (p = 0; p < ngp; p++) {
658: ShapeFunctionQ13D_Evaluate(gp_xi[p],Ni_p);
659: ShapeFunctionQ13D_Evaluate_dxi(gp_xi[p],GNi_p);
660: ShapeFunctionQ13D_Evaluate_dx(GNi_p,GNx_p,coords,&J_p);
661: fac = gp_weight[p]*J_p;
662: /*
663: for (i = 0; i < NODES_PER_EL; i++) {
664: for (j = i; j < NODES_PER_EL; j++) {
665: Ke[NODES_PER_EL*i+j] -= fac*(Ni_p[i]*Ni_p[j]-0.015625);
666: }
667: }
668: */
670: for (i = 0; i < NODES_PER_EL; i++) {
671: for (j = 0; j < NODES_PER_EL; j++) {
672: Ke[NODES_PER_EL*i+j] -= fac*(Ni_p[i]*Ni_p[j]-0.015625);
673: }
674: }
675: }
677: /* scale */
678: eta_avg = 0.0;
679: for (p = 0; p < ngp; p++) {
680: eta_avg += eta[p];
681: }
682: eta_avg = (1.0/((PetscScalar )ngp))*eta_avg;
683: fac = 1.0/eta_avg;
685: /*
686: for (i = 0; i < NODES_PER_EL; i++) {
687: for (j = i; j < NODES_PER_EL; j++) {
688: Ke[NODES_PER_EL*i+j] = fac*Ke[NODES_PER_EL*i+j];
689: #ifdef ASSEMBLE_LOWER_TRIANGULAR
690: Ke[NODES_PER_EL*j+i] = Ke[NODES_PER_EL*i+j];
691: #endif
692: }
693: }
694: */
696: for (i = 0; i < NODES_PER_EL; i++) {
697: for (j = 0; j < NODES_PER_EL; j++) {
698: Ke[NODES_PER_EL*i+j] = fac*Ke[NODES_PER_EL*i+j];
699: }
700: }
701: }
703: static void FormScaledMassMatrixOperatorQ13D(PetscScalar Ke[],PetscScalar coords[],PetscScalar eta[])
704: {
705: PetscInt ngp;
706: PetscScalar gp_xi[GAUSS_POINTS][NSD];
707: PetscScalar gp_weight[GAUSS_POINTS];
708: PetscInt p,i,j;
709: PetscScalar Ni_p[NODES_PER_EL];
710: PetscScalar GNi_p[NSD][NODES_PER_EL],GNx_p[NSD][NODES_PER_EL];
711: PetscScalar J_p,fac,eta_avg;
713: /* define quadrature rule */
714: ConstructGaussQuadrature3D(&ngp,gp_xi,gp_weight);
716: /* evaluate integral */
717: for (p = 0; p < ngp; p++) {
718: ShapeFunctionQ13D_Evaluate(gp_xi[p],Ni_p);
719: ShapeFunctionQ13D_Evaluate_dxi(gp_xi[p],GNi_p);
720: ShapeFunctionQ13D_Evaluate_dx(GNi_p,GNx_p,coords,&J_p);
721: fac = gp_weight[p]*J_p;
723: /*
724: for (i = 0; i < NODES_PER_EL; i++) {
725: for (j = i; j < NODES_PER_EL; j++) {
726: Ke[NODES_PER_EL*i+j] = Ke[NODES_PER_EL*i+j]-fac*Ni_p[i]*Ni_p[j];
727: }
728: }
729: */
731: for (i = 0; i < NODES_PER_EL; i++) {
732: for (j = 0; j < NODES_PER_EL; j++) {
733: Ke[NODES_PER_EL*i+j] = Ke[NODES_PER_EL*i+j]-fac*Ni_p[i]*Ni_p[j];
734: }
735: }
736: }
738: /* scale */
739: eta_avg = 0.0;
740: for (p = 0; p < ngp; p++) {
741: eta_avg += eta[p];
742: }
743: eta_avg = (1.0/((PetscScalar )ngp))*eta_avg;
744: fac = 1.0/eta_avg;
745: /*
746: for (i = 0; i < NODES_PER_EL; i++) {
747: for (j = i; j < NODES_PER_EL; j++) {
748: Ke[NODES_PER_EL*i+j] = fac*Ke[NODES_PER_EL*i+j];
749: #ifdef ASSEMBLE_LOWER_TRIANGULAR
750: Ke[NODES_PER_EL*j+i] = Ke[NODES_PER_EL*i+j];
751: #endif
752: }
753: }
754: */
756: for (i = 0; i < NODES_PER_EL; i++) {
757: for (j = 0; j < NODES_PER_EL; j++) {
758: Ke[NODES_PER_EL*i+j] = fac*Ke[NODES_PER_EL*i+j];
759: }
760: }
761: }
763: static void FormMomentumRhsQ13D(PetscScalar Fe[],PetscScalar coords[],PetscScalar fx[],PetscScalar fy[],PetscScalar fz[])
764: {
765: PetscInt ngp;
766: PetscScalar gp_xi[GAUSS_POINTS][NSD];
767: PetscScalar gp_weight[GAUSS_POINTS];
768: PetscInt p,i;
769: PetscScalar Ni_p[NODES_PER_EL];
770: PetscScalar GNi_p[NSD][NODES_PER_EL],GNx_p[NSD][NODES_PER_EL];
771: PetscScalar J_p,fac;
773: /* define quadrature rule */
774: ConstructGaussQuadrature3D(&ngp,gp_xi,gp_weight);
776: /* evaluate integral */
777: for (p = 0; p < ngp; p++) {
778: ShapeFunctionQ13D_Evaluate(gp_xi[p],Ni_p);
779: ShapeFunctionQ13D_Evaluate_dxi(gp_xi[p],GNi_p);
780: ShapeFunctionQ13D_Evaluate_dx(GNi_p,GNx_p,coords,&J_p);
781: fac = gp_weight[p]*J_p;
783: for (i = 0; i < NODES_PER_EL; i++) {
784: Fe[NSD*i ] -= fac*Ni_p[i]*fx[p];
785: Fe[NSD*i+1] -= fac*Ni_p[i]*fy[p];
786: Fe[NSD*i+2] -= fac*Ni_p[i]*fz[p];
787: }
788: }
789: }
791: static void FormContinuityRhsQ13D(PetscScalar Fe[],PetscScalar coords[],PetscScalar hc[])
792: {
793: PetscInt ngp;
794: PetscScalar gp_xi[GAUSS_POINTS][NSD];
795: PetscScalar gp_weight[GAUSS_POINTS];
796: PetscInt p,i;
797: PetscScalar Ni_p[NODES_PER_EL];
798: PetscScalar GNi_p[NSD][NODES_PER_EL],GNx_p[NSD][NODES_PER_EL];
799: PetscScalar J_p,fac;
801: /* define quadrature rule */
802: ConstructGaussQuadrature3D(&ngp,gp_xi,gp_weight);
804: /* evaluate integral */
805: for (p = 0; p < ngp; p++) {
806: ShapeFunctionQ13D_Evaluate(gp_xi[p],Ni_p);
807: ShapeFunctionQ13D_Evaluate_dxi(gp_xi[p],GNi_p);
808: ShapeFunctionQ13D_Evaluate_dx(GNi_p,GNx_p,coords,&J_p);
809: fac = gp_weight[p]*J_p;
811: for (i = 0; i < NODES_PER_EL; i++) {
812: Fe[i] -= fac*Ni_p[i]*hc[p];
813: }
814: }
815: }
817: #define _ZERO_ROWCOL_i(A,i) { \
818: PetscInt KK; \
819: PetscScalar tmp = A[24*(i)+(i)]; \
820: for(KK=0;KK<24;KK++){A[24*(i)+KK]=0.0;} \
821: for(KK=0;KK<24;KK++){A[24*KK+(i)]=0.0;} \
822: A[24*(i)+(i)] = tmp;} \
824: #define _ZERO_ROW_i(A,i) { \
825: PetscInt KK; \
826: for(KK=0;KK<8;KK++){A[8*(i)+KK]=0.0;}}
828: #define _ZERO_COL_i(A,i) { \
829: PetscInt KK; \
830: for(KK=0;KK<8;KK++){A[24*KK+(i)]=0.0;}}
834: static PetscErrorCode AssembleA_Stokes(Mat A,DM stokes_da,CellProperties cell_properties)
835: {
836: DM cda;
837: Vec coords;
838: DMDACoor3d ***_coords;
839: MatStencil u_eqn[NODES_PER_EL*U_DOFS];
840: MatStencil p_eqn[NODES_PER_EL*P_DOFS];
841: PetscInt sex,sey,sez,mx,my,mz;
842: PetscInt ei,ej,ek;
843: PetscScalar Ae[NODES_PER_EL*U_DOFS*NODES_PER_EL*U_DOFS];
844: PetscScalar Ge[NODES_PER_EL*U_DOFS*NODES_PER_EL*P_DOFS];
845: PetscScalar De[NODES_PER_EL*P_DOFS*NODES_PER_EL*U_DOFS];
846: PetscScalar Ce[NODES_PER_EL*P_DOFS*NODES_PER_EL*P_DOFS];
847: PetscScalar el_coords[NODES_PER_EL*NSD];
848: GaussPointCoefficients *props;
849: PetscScalar *prop_eta;
850: PetscInt n,M,N,P;
851: PetscLogDouble t0,t1;
852: PetscErrorCode ierr;
856: DMDAGetInfo (stokes_da,0,&M,&N,&P,0,0,0, 0,0,0,0,0,0);
857: /* setup for coords */
858: DMDAGetCoordinateDA (stokes_da,&cda);
859: DMDAGetGhostedCoordinates (stokes_da,&coords);
860: DMDAVecGetArray (cda,coords,&_coords);
862: DMDAGetElementCorners(stokes_da,&sex,&sey,&sez,&mx,&my,&mz);
863: PetscGetTime (&t0);
864: for (ek = sez; ek < sez+mz; ek++) {
865: for (ej = sey; ej < sey+my; ej++) {
866: for (ei = sex; ei < sex+mx; ei++) {
867: /* get coords for the element */
868: GetElementCoords3D(_coords,ei,ej,ek,el_coords);
869: /* get cell properties */
870: CellPropertiesGetCell(cell_properties,ei,ej,ek,&props);
871: /* get coefficients for the element */
872: prop_eta = props->eta;
874: /* initialise element stiffness matrix */
875: PetscMemzero (Ae,sizeof (PetscScalar )*NODES_PER_EL*U_DOFS*NODES_PER_EL*U_DOFS);
876: PetscMemzero (Ge,sizeof (PetscScalar )*NODES_PER_EL*U_DOFS*NODES_PER_EL*P_DOFS);
877: PetscMemzero (De,sizeof (PetscScalar )*NODES_PER_EL*P_DOFS*NODES_PER_EL*U_DOFS);
878: PetscMemzero (Ce,sizeof (PetscScalar )*NODES_PER_EL*P_DOFS*NODES_PER_EL*P_DOFS);
880: /* form element stiffness matrix */
881: FormStressOperatorQ13D(Ae,el_coords,prop_eta);
882: FormGradientOperatorQ13D(Ge,el_coords);
883: /*#ifdef ASSEMBLE_LOWER_TRIANGULAR*/
884: FormDivergenceOperatorQ13D(De,el_coords);
885: /*#endif*/
886: FormStabilisationOperatorQ13D(Ce,el_coords,prop_eta);
888: /* insert element matrix into global matrix */
889: DMDAGetElementEqnums3D_up(u_eqn,p_eqn,ei,ej,ek);
891: for (n=0; n<NODES_PER_EL; n++) {
892: if ( (u_eqn[3*n ].i == 0) || (u_eqn[3*n ].i == M-1) ) {
893: _ZERO_ROWCOL_i(Ae,3*n);
894: _ZERO_ROW_i (Ge,3*n);
895: _ZERO_COL_i (De,3*n);
896: }
898: if ( (u_eqn[3*n+1].j == 0) || (u_eqn[3*n+1].j == N-1) ) {
899: _ZERO_ROWCOL_i(Ae,3*n+1);
900: _ZERO_ROW_i (Ge,3*n+1);
901: _ZERO_COL_i (De,3*n+1);
902: }
904: if ( (u_eqn[3*n+2].k == 0) || (u_eqn[3*n+2].k == P-1) ) {
905: _ZERO_ROWCOL_i(Ae,3*n+2);
906: _ZERO_ROW_i (Ge,3*n+2);
907: _ZERO_COL_i (De,3*n+2);
908: }
909: }
910: MatSetValuesStencil (A,NODES_PER_EL*U_DOFS,u_eqn,NODES_PER_EL*U_DOFS,u_eqn,Ae,ADD_VALUES );
911: MatSetValuesStencil (A,NODES_PER_EL*U_DOFS,u_eqn,NODES_PER_EL*P_DOFS,p_eqn,Ge,ADD_VALUES );
912: MatSetValuesStencil (A,NODES_PER_EL*P_DOFS,p_eqn,NODES_PER_EL*U_DOFS,u_eqn,De,ADD_VALUES );
913: MatSetValuesStencil (A,NODES_PER_EL*P_DOFS,p_eqn,NODES_PER_EL*P_DOFS,p_eqn,Ce,ADD_VALUES );
914: }
915: }
916: }
917: MatAssemblyBegin (A,MAT_FINAL_ASSEMBLY);
918: MatAssemblyEnd (A,MAT_FINAL_ASSEMBLY);
920: DMDAVecRestoreArray (cda,coords,&_coords);
922: PetscGetTime (&t1);
923: return (0);
924: }
928: static PetscErrorCode AssembleA_PCStokes(Mat A,DM stokes_da,CellProperties cell_properties)
929: {
930: DM cda;
931: Vec coords;
932: DMDACoor3d ***_coords;
933: MatStencil u_eqn[NODES_PER_EL*U_DOFS];
934: MatStencil p_eqn[NODES_PER_EL*P_DOFS];
935: PetscInt sex,sey,sez,mx,my,mz;
936: PetscInt ei,ej,ek;
937: PetscScalar Ae[NODES_PER_EL*U_DOFS*NODES_PER_EL*U_DOFS];
938: PetscScalar Ge[NODES_PER_EL*U_DOFS*NODES_PER_EL*P_DOFS];
939: PetscScalar De[NODES_PER_EL*P_DOFS*NODES_PER_EL*U_DOFS];
940: PetscScalar Ce[NODES_PER_EL*P_DOFS*NODES_PER_EL*P_DOFS];
941: PetscScalar el_coords[NODES_PER_EL*NSD];
942: GaussPointCoefficients *props;
943: PetscScalar *prop_eta;
944: PetscInt n,M,N,P;
945: PetscErrorCode ierr;
949: DMDAGetInfo (stokes_da,0,&M,&N,&P,0,0,0, 0,0,0,0,0,0);
950: /* setup for coords */
951: DMDAGetCoordinateDA (stokes_da,&cda);
952: DMDAGetGhostedCoordinates (stokes_da,&coords);
953: DMDAVecGetArray (cda,coords,&_coords);
955: DMDAGetElementCorners(stokes_da,&sex,&sey,&sez,&mx,&my,&mz);
956: for (ek = sez; ek < sez+mz; ek++) {
957: for (ej = sey; ej < sey+my; ej++) {
958: for (ei = sex; ei < sex+mx; ei++) {
959: /* get coords for the element */
960: GetElementCoords3D(_coords,ei,ej,ek,el_coords);
961: /* get cell properties */
962: CellPropertiesGetCell(cell_properties,ei,ej,ek,&props);
963: /* get coefficients for the element */
964: prop_eta = props->eta;
966: /* initialise element stiffness matrix */
967: PetscMemzero (Ae,sizeof (PetscScalar )*NODES_PER_EL*U_DOFS*NODES_PER_EL*U_DOFS);
968: PetscMemzero (Ge,sizeof (PetscScalar )*NODES_PER_EL*U_DOFS*NODES_PER_EL*P_DOFS);
969: PetscMemzero (De,sizeof (PetscScalar )*NODES_PER_EL*P_DOFS*NODES_PER_EL*U_DOFS);
970: PetscMemzero (Ce,sizeof (PetscScalar )*NODES_PER_EL*P_DOFS*NODES_PER_EL*P_DOFS);
972: /* form element stiffness matrix */
973: FormStressOperatorQ13D(Ae,el_coords,prop_eta);
974: FormGradientOperatorQ13D(Ge,el_coords);
975: /*FormDivergenceOperatorQ13D(De,el_coords);*/
line976">976: FormScaledMassMatrixOperatorQ13D(Ce,el_coords,pro
/* insert element matrix into global matrix */
line979">979: DMDAGetElementEqnums3D_up(u_eqn,p_eqn,ei,
line981">981: for (n=0; n<NODES_PER_EL;
line982">982: if ( (u_eqn[3*n].i == 0) || (u_eqn[3*n].i == M
line983">983: _ZERO_ROWCOL_i(A
line984">984: _ZERO_ROW_i (G
line985">985: _ZERO_COL_i (D
line986">986:
line988">988: if ( (u_eqn[3*n+1].j == 0) || (u_eqn[3*n+1].j == N
line989">989: _ZERO_ROWCOL_i(Ae,
line990">990: _ZERO_ROW_i (Ge,
line991">991: _ZERO_COL_i (De,
line992">992:
line994">994: if ( (u_eqn[3*n+2].k == 0) || (u_eqn[3*n+2].k == P
line995">995: _ZERO_ROWCOL_i(Ae,
line996">996: _ZERO_ROW_i (Ge,
line997">997: _ZERO_COL_i (De,
line998">998:
line999">999:
line1000">1000: MatSetValuesStencil (A,NODES_PER_EL*U_DOFS,u_eqn,NODES_PER_EL*U_DOFS,u_eqn,Ae,ADD_VALUE
line1001">1001: MatSetValuesStencil (A,NODES_PER_EL*U_DOFS,u_eqn,NODES_PER_EL*P_DOFS,p_eqn,Ge,ADD_VALUE
/* MatSetValuesStencil (A,NODES_PER_EL*P_DOFS,p_eqn,NODES_PER_EL*U_DOFS,u_eqn,De,ADD_VALUES );*/
line1003">1003: MatSetValuesStencil (A,NODES_PER_EL*P_DOFS,p_eqn,NODES_PER_EL*P_DOFS,p_eqn,Ce,ADD_VALUE
line1004">1004:
line1005">1005:
line1006">1006:
line1007">1007: MatAssemblyBegin (A,MAT_FINAL_ASS
line1008">1008: MatAssemblyEnd (A,MAT_FINAL_ASS
line1010">1010: DMDAVecRestoreArray (cda,coords,&_c
line1011">1011: return
line1012">1012
line1016">1016: static PetscErrorCode AssembleF_Stokes(Vec F,DM stokes_da,CellProperties cell_properties)
line1017">1017
line1018">1018: DM
line1019">1019: Vec
line1020">1020: DMDACoor3d ***_
line1021">1021: MatStencil u_eqn[NODES_PER_EL*U
line1022">1022: MatStencil p_eqn[NODES_PER_EL*P
line1023">1023: PetscInt sex,sey,sez,mx
line1024">1024: PetscInt ei
line1025">1025: PetscScalar Fe[NODES_PER_EL*U
line1026">1026: PetscScalar He[NODES_PER_EL*P
line1027">1027: PetscScalar el_coords[NODES_PER_E
line1028">1028: GaussPointCoefficients
line1029">1029: PetscScalar *prop_fx,*prop_fy,*prop_fz,*p
line1030">1030: Vec l
line1031">1031: StokesDOF
line1032">1032: PetscInt n
line1033">1033: PetscErrorCode
line1037">1037: DMDAGetInfo (stokes_da,0,&M,&N,&P,0,0,0, 0,0,0,
/* setup for coords */
line1039">1039: DMDAGetCoordinateDA (stokes_da,&am
line1040">1040: DMDAGetGhostedCoordinates (stokes_da,&c
line1041">1041: DMDAVecGetArray (cda,coords,&_c
/* get acces to the vector */
line1044">1044: DMGetLocalVector (stokes_da,&lo
line1045">1045: VecZeroEntries (lo
line1046">1046: DMDAVecGetArray (stokes_da,local_F,&a
line1048">1048: DMDAGetElementCorners(stokes_da,&sex,&sey,&sez,&mx,&my,&a
line1049">1049: for (ek = sez; ek < sez+mz;
line1050">1050: for (ej = sey; ej < sey+my;
line1051">1051: for (ei = sex; ei < sex+mx;
/* get coords for the element */
line1053">1053: GetElementCoords3D(_coords,ei,ej,ek,el_c
/* get cell properties */
line1055">1055: CellPropertiesGetCell(cell_properties,ei,ej,ek,&
/* get coefficients for the element */
line1057">1057: prop_fx = props-
line1058">1058: prop_fy = props-
line1059">1059: prop_fz = props-
line1060">1060: prop_hc = props-
/* initialise element stiffness matrix */
line1063">1063: PetscMemzero (Fe,sizeof (PetscScalar )*NODES_PER_EL*U
line1064">1064: PetscMemzero (He,sizeof (PetscScalar )*NODES_PER_EL*P
/* form element stiffness matrix */
line1067">1067: FormMomentumRhsQ13D(Fe,el_coords,prop_fx,prop_fy,pr
line1068">1068: FormContinuityRhsQ13D(He,el_coords,pr
/* insert element matrix into global matrix */
line1071">1071: DMDAGetElementEqnums3D_up(u_eqn,p_eqn,ei,
line1073">1073: for (n=0; n<NODES_PER_EL;
line1074">1074: if ( (u_eqn[3*n ].i == 0) || (u_eqn[3*n ].i == M
line1075">1075: Fe[3*n ]
line1076">1076:
line1078">1078: if ( (u_eqn[3*n+1].j == 0) || (u_eqn[3*n+1].j == N
line1079">1079: Fe[3*n+1]
line1080">1080:
line1082">1082: if ( (u_eqn[3*n+2].k == 0) || (u_eqn[3*n+2].k == P
line1083">1083: Fe[3*n+2]
line1084">1084:
line1085">1085:
line1087">1087: DMDASetValuesLocalStencil3D_ADD_VALUES(ff,u_eqn,p_eqn,
line1088">1088:
line1089">1089:
line1090">1090:
line1091">1091: DMDAVecRestoreArray (stokes_da,local_F,&a
line1092">1092: DMLocalToGlobalBegin (stokes_da,local_F,ADD_VALUES<
line1093">1093: DMLocalToGlobalEnd (stokes_da,local_F,ADD_VALUES<
line1094">1094: DMRestoreLocalVector (stokes_da,&lo
line1096">1096: DMDAVecRestoreArray (cda,coords,&_c
line1097">1097: return
line1098">1098
line1100">1100: static void evaluate_MS_FrankKamentski_constants(PetscReal *theta,PetscReal *MX,PetscReal *MY,PetscReal *MZ)
line1101">1101
line1102">1102: *theta
line1103">1103: *MX = 2.0
line1104">1104: *MY = 2.0
line1105">1105: *MZ = 2.0
line1106">1106
line1107">1107: static void evaluate_MS_FrankKamentski(PetscReal pos[],PetscReal v[],PetscReal *p,PetscReal *eta,PetscReal Fm[],PetscReal *Fc)
line1108">1108
line1109">1109: PetscReal
line1110">1110: PetscReal theta,MX
line1112">1112: evaluate_MS_FrankKamentski_constants(&theta,&MX,&MY,&a
line1113">1113: x =
line1114">1114: y =
line1115">1115: z =
line1116">1116: if
/*
v[0] = pow(z,3)*exp(y)*sin(M_PI*x);
v[1] = z*cos(2.0*M_PI*x)*exp(-y)*sin(M_PI*y);
v[2] = -(pow(x,3) + pow(y,3))*sin(2.0*M_PI*z);
*/
/*
v[0] = sin(M_PI*x);
v[1] = sin(M_PI*y);
v[2] = sin(M_PI*z);
*/
line1127">1127: v[0] = pow(z,3)*exp(y)*sin(M
line1128">1128: v[1] = z*cos(2.0*M_PI*x)*exp(-y)*sin(M
line1129">1129: v[2] = pow(z,2)*(cos(2.0*M_PI*x)*exp(-y)*sin(M_PI*y)/2 - M_PI*cos(M_PI*y)*cos(2.0*M_PI*x)*exp(-y)/2) - M_PI*pow(z,4)*cos(M_PI*x)*exp
line1130">1130:
line1131">1131: if
line1132">1132: *p = pow(x,2) + pow(y,2) + po
line1133">1133:
line1134">1134: if
/**eta = exp(-theta*(1.0 - y - 0.1*cos(MX*x)*cos(MZ*z)*sin(MY*y)));*/
line1136">1136: *eta
line1137">1137:
line1138">1138: if
/*
Fm[0] = -2*x - 2.0*pow(M_PI,2)*pow(z,3)*exp(y)*exp(-theta*(1 - y - 0.1*cos(MX*x)*cos(MZ*z)*sin(MY*y)))*sin(M_PI*x) - 0.2*MZ*theta*(-1.5*pow(x,2)*sin(2.0*M_PI*z) + 1.5*pow(z,2)*exp(y)*sin(M_PI*x))*cos(MX*x)*exp(-theta*(1 - y - 0.1*cos(MX*x)*cos(MZ*z)*sin(MY*y)))*sin(MY*y)*sin(MZ*z) - 0.2*M_PI*MX*theta*pow(z,3)*cos(M_PI*x)*cos(MZ*z)*exp(y)*exp(-theta*(1 - y - 0.1*cos(MX*x)*cos(MZ*z)*sin(MY*y)))*sin(MX*x)*sin(MY*y) + 2.0*(3.0*z*exp(y)*sin(M_PI*x) - 3.0*M_PI*pow(x,2)*cos(2.0*M_PI*z))*exp(-theta*(1 - y - 0.1*cos(MX*x)*cos(MZ*z)*sin(MY*y))) + 2.0*(0.5*pow(z,3)*exp(y)*sin(M_PI*x) + M_PI*z*exp(-y)*sin(M_PI*y)*sin(2.0*M_PI*x) - 1.0*z*pow(M_PI,2)*cos(M_PI*y)*exp(-y)*sin(2.0*M_PI*x))*exp(-theta*(1 - y - 0.1*cos(MX*x)*cos(MZ*z)*sin(MY*y))) + 2.0*theta*(1 + 0.1*MY*cos(MX*x)*cos(MY*y)*cos(MZ*z))*(0.5*pow(z,3)*exp(y)*sin(M_PI*x) - 1.0*M_PI*z*exp(-y)*sin(M_PI*y)*sin(2.0*M_PI*x))*exp(-theta*(1 - y - 0.1*cos(MX*x)*cos(MZ*z)*sin(MY*y))) ;
Fm[1] = -2*y - 0.2*MX*theta*(0.5*pow(z,3)*exp(y)*sin(M_PI*x) - 1.0*M_PI*z*exp(-y)*sin(M_PI*y)*sin(2.0*M_PI*x))*cos(MZ*z)*exp(-theta*(1 - y - 0.1*cos(MX*x)*cos(MZ*z)*sin(MY*y)))*sin(MX*x)*sin(MY*y) - 0.2*MZ*theta*(-1.5*pow(y,2)*sin(2.0*M_PI*z) + 0.5*cos(2.0*M_PI*x)*exp(-y)*sin(M_PI*y))*cos(MX*x)*exp(-theta*(1 - y - 0.1*cos(MX*x)*cos(MZ*z)*sin(MY*y)))*sin(MY*y)*sin(MZ*z) + 2.0*(-2.0*z*pow(M_PI,2)*cos(2.0*M_PI*x)*exp(-y)*sin(M_PI*y) + 0.5*M_PI*pow(z,3)*cos(M_PI*x)*exp(y))*exp(-theta*(1 - y - 0.1*cos(MX*x)*cos(MZ*z)*sin(MY*y))) + 2.0*(z*cos(2.0*M_PI*x)*exp(-y)*sin(M_PI*y) - z*pow(M_PI,2)*cos(2.0*M_PI*x)*exp(-y)*sin(M_PI*y) - 2*M_PI*z*cos(M_PI*y)*cos(2.0*M_PI*x)*exp(-y))*exp(-theta*(1 - y - 0.1*cos(MX*x)*cos(MZ*z)*sin(MY*y))) + 2.0*theta*(1 + 0.1*MY*cos(MX*x)*cos(MY*y)*cos(MZ*z))*(-z*cos(2.0*M_PI*x)*exp(-y)*sin(M_PI*y) + M_PI*z*cos(M_PI*y)*cos(2.0*M_PI*x)*exp(-y))*exp(-theta*(1 - y - 0.1*cos(MX*x)*cos(MZ*z)*sin(MY*y))) - 6.0*M_PI*pow(y,2)*cos(2.0*M_PI*z)*exp(-theta*(1 - y - 0.1*cos(MX*x)*cos(MZ*z)*sin(MY*y)));
Fm[2] = -2*z + 8.0*pow(M_PI,2)*(pow(x,3) + pow(y,3))*exp(-theta*(1 - y - 0.1*cos(MX*x)*cos(MZ*z)*sin(MY*y)))*sin(2.0*M_PI*z) - 0.2*MX*theta*(-1.5*pow(x,2)*sin(2.0*M_PI*z) + 1.5*pow(z,2)*exp(y)*sin(M_PI*x))*cos(MZ*z)*exp(-theta*(1 - y - 0.1*cos(MX*x)*cos(MZ*z)*sin(MY*y)))*sin(MX*x)*sin(MY*y) + 0.4*M_PI*MZ*theta*(pow(x,3) + pow(y,3))*cos(MX*x)*cos(2.0*M_PI*z)*exp(-theta*(1 - y - 0.1*cos(MX*x)*cos(MZ*z)*sin(MY*y)))*sin(MY*y)*sin(MZ*z) + 2.0*(-3.0*x*sin(2.0*M_PI*z) + 1.5*M_PI*pow(z,2)*cos(M_PI*x)*exp(y))*exp(-theta*(1 - y - 0.1*cos(MX*x)*cos(MZ*z)*sin(MY*y))) + 2.0*(-3.0*y*sin(2.0*M_PI*z) - 0.5*cos(2.0*M_PI*x)*exp(-y)*sin(M_PI*y) + 0.5*M_PI*cos(M_PI*y)*cos(2.0*M_PI*x)*exp(-y))*exp(-theta*(1 - y - 0.1*cos(MX*x)*cos(MZ*z)*sin(MY*y))) + 2.0*theta*(1 + 0.1*MY*cos(MX*x)*cos(MY*y)*cos(MZ*z))*(-1.5*pow(y,2)*sin(2.0*M_PI*z) + 0.5*cos(2.0*M_PI*x)*exp(-y)*sin(M_PI*y))*exp(-theta*(1 - y - 0.1*cos(MX*x)*cos(MZ*z)*sin(MY*y))) ;
*/
/*
Fm[0]=-2*x - 2.0*pow(M_PI,2)*sin(M_PI*x);
Fm[1]=-2*y - 2.0*pow(M_PI,2)*sin(M_PI*y);
Fm[2]=-2*z - 2.0*pow(M_PI,2)*sin(M_PI*z);
*/
/*
Fm[0] = -2*x + pow(z,3)*exp(y)*sin(M_PI*x) + 6.0*z*exp(y)*sin(M_PI*x) - 6.0*M_PI*pow(x,2)*cos(2.0*M_PI*z) - 2.0*pow(M_PI,2)*pow(z,3)*exp(y)*sin(M_PI*x) + 2.0*M_PI*z*exp(-y)*sin(M_PI*y)*sin(2.0*M_PI*x) - 2.0*z*pow(M_PI,2)*cos(M_PI*y)*exp(-y)*sin(2.0*M_PI*x) ;
Fm[1] = -2*y - 6.0*M_PI*pow(y,2)*cos(2.0*M_PI*z) + 2.0*z*cos(2.0*M_PI*x)*exp(-y)*sin(M_PI*y) - 6.0*z*pow(M_PI,2)*cos(2.0*M_PI*x)*exp(-y)*sin(M_PI*y) + M_PI*pow(z,3)*cos(M_PI*x)*exp(y) - 4.0*M_PI*z*cos(M_PI*y)*cos(2.0*M_PI*x)*exp(-y);
Fm[2] = -2*z - 6.0*x*sin(2.0*M_PI*z) - 6.0*y*sin(2.0*M_PI*z) - cos(2.0*M_PI*x)*exp(-y)*sin(M_PI*y) + 8.0*pow(M_PI,2)*(pow(x,3) + pow(y,3))*sin(2.0*M_PI*z) + 3.0*M_PI*pow(z,2)*cos(M_PI*x)*exp(y) + M_PI*cos(M_PI*y)*cos(2.0*M_PI*x)*exp(-y) ;
*/
line1154">1154: Fm[0] = -2*x + 2*z*(pow(M_PI,2)*cos(M_PI*y)*exp(-y)*sin(2.0*M_PI*x) - 1.0*M_PI*exp(-y)*sin(M_PI*y)*sin(2.0*M_PI*x)) + pow(z,3)*exp(y)*sin(M_PI*x) + 6.0*z*exp(y)*sin(M_PI*x) - 1.0*pow(M_PI,2)*pow(z,3)*exp(y)*sin(M_PI*x) + 2.0*M_PI*z*exp(-y)*sin(M_PI*y)*sin(2.0*M_PI*x) - 2.0*z*pow(M_PI,2)*cos(M_PI*y)*exp(-y)*sin(2.0*M
line1155">1155: Fm[1] = -2*y + 2*z*(-cos(2.0*M_PI*x)*exp(-y)*sin(M_PI*y)/2 + pow(M_PI,2)*cos(2.0*M_PI*x)*exp(-y)*sin(M_PI*y)/2 + M_PI*cos(M_PI*y)*cos(2.0*M_PI*x)*exp(-y)) + 2.0*z*cos(2.0*M_PI*x)*exp(-y)*sin(M_PI*y) - 6.0*z*pow(M_PI,2)*cos(2.0*M_PI*x)*exp(-y)*sin(M_PI*y) - 4.0*M_PI*z*cos(M_PI*y)*cos(2.0*M_PI*x)*ex
line1156">1156: Fm[2] = -2*z + pow(z,2)*(-2.0*pow(M_PI,2)*cos(2.0*M_PI*x)*exp(-y)*sin(M_PI*y) + 2.0*pow(M_PI,3)*cos(M_PI*y)*cos(2.0*M_PI*x)*exp(-y)) + pow(z,2)*(cos(2.0*M_PI*x)*exp(-y)*sin(M_PI*y)/2 - 3*pow(M_PI,2)*cos(2.0*M_PI*x)*exp(-y)*sin(M_PI*y)/2 + pow(M_PI,3)*cos(M_PI*y)*cos(2.0*M_PI*x)*exp(-y)/2 - 3*M_PI*cos(M_PI*y)*cos(2.0*M_PI*x)*exp(-y)/2) + 1.0*cos(2.0*M_PI*x)*exp(-y)*sin(M_PI*y) + 0.25*pow(M_PI,3)*pow(z,4)*cos(M_PI*x)*exp(y) - 0.25*M_PI*pow(z,4)*cos(M_PI*x)*exp(y) - 3.0*M_PI*pow(z,2)*cos(M_PI*x)*exp(y) - 1.0*M_PI*cos(M_PI*y)*cos(2.0*M_PI*x)*ex
line1157">1157:
line1158">1158: if
/**Fc = -2.0*M_PI*(pow(x,3) + pow(y,3))*cos(2.0*M_PI*z) - z*cos(2.0*M_PI*x)*exp(-y)*sin(M_PI*y) + M_PI*pow(z,3)*cos(M_PI*x)*exp(y) + M_PI*z*cos(M_PI*y)*cos(2.0*M_PI*x)*exp(-y) ;*/
/**Fc = M_PI*cos(M_PI*x) + M_PI*cos(M_PI*y) + M_PI*cos(M_PI*z);*/
/**Fc = -2.0*M_PI*(pow(x,3) + pow(y,3))*cos(2.0*M_PI*z) - z*cos(2.0*M_PI*x)*exp(-y)*sin(M_PI*y) + M_PI*pow(z,3)*cos(M_PI*x)*exp(y) + M_PI*z*cos(M_PI*y)*cos(2.0*M_PI*x)*exp(-y);*/
line1162">1162: *Fc
line1163">1163:
line1164">1164
line1168">1168: static PetscErrorCode DMDACreateManufacturedSolution(PetscInt mx,PetscInt my,PetscInt mz,DM *_da,Vec *_X)
line1169">1169
line1170">1170: DM
line1171">1171: Vec X,l
line1172">1172: StokesDOF ***_
line1173">1173: Vec
line1174">1174: DMDACoor3d ***_
line1175">1175: PetscInt si,sj,sk,ei,ej,ek
line1179">1179: DMDACreate3d (PETSC_COMM_WORLD ,DMDA_BOUNDARY_NONE,DMDA_BOUNDARY_NONE,DMDA_BOUNDARY_NONE,DMDA_STENCIL_B
line1180">1180: mx+1,my+1,mz+1,PETSC_DECIDE ,PETSC_DECIDE ,PETSC_DECIDE ,4,1,PETSC_NULL ,PETSC_NULL ,PETSC_NULL ,&a
line1181">1181: DMDASetFieldName (da,0,"anlytic_Vx"
line1182">1182: DMDASetFieldName (da,1,"anlytic_Vy"
line1183">1183: DMDASetFieldName (da,2,"anlytic_Vz"
line1184">1184: DMDASetFieldName (da,3,"analytic_P"
line1186">1186: DMDASetUniformCoordinates (da,0.0,1.0,0.0,1.0,0.
line1188">1188: DMDAGetGhostedCoordinates (da,&c
line1189">1189: DMDAGetCoordinateDA (da,&am
line1190">1190: DMDAVecGetArray (cda,coords,&_c
line1192">1192: DMCreateGlobalVector (da,&
line1193">1193: DMCreateLocalVector (da,&lo
line1194">1194: DMDAVecGetArray (da,local_X,&_s
line1196">1196: DMDAGetGhostCorners (da,&si,&sj,&sk,&ei,&ej,&a
line1197">1197: for (k = sk; k < sk+ek;
line1198">1198: for (j = sj; j < sj+ej;
line1199">1199: for (i = si; i < si+ei;
line1200">1200: PetscReal pos[NSD],pressure,ve
line1202">1202: pos[0] = PetscRealPart(_coords[k][j]
line1203">1203: pos[1] = PetscRealPart(_coords[k][j]
line1204">1204: pos[2] = PetscRealPart(_coords[k][j]
line1206">1206: evaluate_MS_FrankKamentski(pos,vel,&pressure,PETSC_NULL ,PETSC_NULL ,PETSC_NUL
line1208">1208: _stokes[k][j][i].u_dof =
line1209">1209: _stokes[k][j][i].v_dof =
line1210">1210: _stokes[k][j][i].w_dof =
line1211">1211: _stokes[k][j][i].p_dof = pr
line1212">1212:
line1213">1213:
line1214">1214:
line1215">1215: DMDAVecRestoreArray (da,local_X,&_s
line1216">1216: DMDAVecRestoreArray (cda,coords,&_c
line1218">1218: DMLocalToGlobalBegin (da,local_X,INSERT_VALUES<
line1219">1219: DMLocalToGlobalEnd (da,local_X,INSERT_VALUES<
line1221">1221: VecDestroy (&lo
line1223">1223: *_d
line1224">1224: *_
line1225">1225: return
line1226">1226
line1230">1230: static PetscErrorCode DMDAIntegrateErrors3D(DM stokes_da,Vec X,Vec X_analytic)
line1231">1231
line1232">1232: DM
line1233">1233: Vec coords,X_analytic_local,X
line1234">1234: DMDACoor3d ***_
line1235">1235: PetscInt sex,sey,sez,mx
line1236">1236: PetscInt ei
line1237">1237: PetscScalar el_coords[NODES_PER_E
line1238">1238: StokesDOF ***stokes_analytic,***
line1239">1239: StokesDOF stokes_analytic_e[NODES_PER_EL],stokes_e[NODES_P
line1241">1241: PetscScalar GNi_p[NSD][NODES_PER_EL],GNx_p[NSD][NODES_P
line1242">1242: PetscScalar Ni_p[NODES_P
line1243">1243: PetscInt
line1244">1244: PetscScalar gp_xi[GAUSS_POINTS
line1245">1245: PetscScalar gp_weight[GAUSS_P
line1246">1246: PetscInt
line1247">1247: PetscScalar J
line1248">1248: PetscScalar h,p_e_L2,u_e_L2,u_e_H1,p_L2,u_L2,u_H1,tp_L2,tu_L2
line1249">1249: PetscScalar tint_p_ms,tint_p,int_p_ms
line1250">1250: PetscInt
line1251">1251: PetscReal xymin[NSD],xyma
/* define quadrature rule */
line1256">1256: ConstructGaussQuadrature3D(&ngp,gp_xi,gp_w
/* setup for coords */
line1259">1259: DMDAGetCoordinateDA (stokes_da,&am
line1260">1260: DMDAGetGhostedCoordinates (stokes_da,&c
line1261">1261: DMDAVecGetArray (cda,coords,&_c
/* setup for analytic */
line1264">1264: DMCreateLocalVector (stokes_da,&X_analytic_
line1265">1265: DMGlobalToLocalBegin (stokes_da,X_analytic,INSERT_VALUES ,X_analytic_
line1266">1266: DMGlobalToLocalEnd (stokes_da,X_analytic,INSERT_VALUES ,X_analytic_
line1267">1267: DMDAVecGetArray (stokes_da,X_analytic_local,&stokes_ana
/* setup for solution */
line1270">1270: DMCreateLocalVector (stokes_da,&X_
line1271">1271: DMGlobalToLocalBegin (stokes_da,X,INSERT_VALUES ,X_
line1272">1272: DMGlobalToLocalEnd (stokes_da,X,INSERT_VALUES ,X_
line1273">1273: DMDAVecGetArray (stokes_da,X_local,&s
line1275">1275: DMDAGetInfo (stokes_da,0,&M,0,0,0,0,0,0,0,0,
line1276">1276: DMDAGetBoundingBox (stokes_da,xymin,
line1278">1278: h = (xymax[0]-xymin[0])/((PetscReal )
line1280">1280: tp_L2 = tu_L2 = tu_H1
line1281">1281: tint_p_ms = tint_p
line1283">1283: DMDAGetElementCorners(stokes_da,&sex,&sey,&sez,&mx,&my,&a
line1285">1285: for (ek = sez; ek < sez+mz;
line1286">1286: for (ej = sey; ej < sey+my;
line1287">1287: for (ei = sex; ei < sex+mx;
/* get coords for the element */
line1289">1289: GetElementCoords3D(_coords,ei,ej,ek,el_c
line1290">1290: StokesDAGetNodalFields3D(stokes,ei,ej,ek,sto
line1291">1291: StokesDAGetNodalFields3D(stokes_analytic,ei,ej,ek,stokes_analy
/* evaluate integral */
line1294">1294: for (p = 0; p < ngp;
line1295">1295: ShapeFunctionQ13D_Evaluate(gp_xi[p]
line1296">1296: ShapeFunctionQ13D_Evaluate_dxi(gp_xi[p],
line1297">1297: ShapeFunctionQ13D_Evaluate_dx(GNi_p,GNx_p,el_coords,&am
line1298">1298: fac = gp_weight[
line1300">1300: for (i = 0; i < NODES_PER_EL;
line1301">1301: tint_p_ms = tint_p_ms+fac*Ni_p[i]*stokes_analytic_e[i]
line1302">1302: tint_p = tint_p +fac*Ni_p[i]*stokes_e[i]
line1303">1303:
line1304">1304:
line1305">1305:
line1306">1306:
line1307">1307:
line1308">1308: MPI_Allreduce (&tint_p_ms,&int_p_ms,1,MPIU_SCALAR ,MPIU_SUM,PETSC_COMM_WORL
line1309">1309: MPI_Allreduce (&tint_p,&int_p,1,MPIU_SCALAR ,MPIU_SUM,PETSC_COMM_WORL
line1311">1311: PetscPrintf (PETSC_COMM_WORLD ,"\\int P dv %1.4e (h) %1.4e (ms)\n" ,PetscRealPart(int_p),PetscRealPart(int_
/* remove mine and add manufacture one */
line1314">1314: DMDAVecRestoreArray (stokes_da,X_analytic_local,&stokes_ana
line1315">1315: DMDAVecRestoreArray (stokes_da,X_local,&s
line1317">1317:
line1318">1318: PetscInt k
line1319">1319: PetscScalar *
line1320">1320: DMDAGetInfo (stokes_da,0, 0,0,0, 0,0,0, &dof,0,0,
line1322">1322: VecGetLocalSize (X_local,&
line1323">1323: VecGetArray (X_local,&f
line1324">1324: for (k=0; k<L/dof;
line1325">1325: fields[dof*k+3] = fields[dof*k+3] - int_p + in
line1326">1326:
line1327">1327: VecRestoreArray (X_local,&f
line1329">1329: VecGetLocalSize (X,&
line1330">1330: VecGetArray (X,&f
line1331">1331: for (k=0; k<L/dof;
line1332">1332: fields[dof*k+3] = fields[dof*k+3] - int_p + in
line1333">1333:
line1334">1334: VecRestoreArray (X,&f
line1335">1335:
line1337">1337: DMDAVecGetArray (stokes_da,X_local,&s
line1338">1338: DMDAVecGetArray (stokes_da,X_analytic_local,&stokes_ana
line1340">1340: for (ek = sez; ek < sez+mz;
line1341">1341: for (ej = sey; ej < sey+my;
line1342">1342: for (ei = sex; ei < sex+mx;
/* get coords for the element */
line1344">1344: GetElementCoords3D(_coords,ei,ej,ek,el_c
line1345">1345: StokesDAGetNodalFields3D(stokes,ei,ej,ek,sto
line1346">1346: StokesDAGetNodalFields3D(stokes_analytic,ei,ej,ek,stokes_analy
/* evaluate integral */
line1349">1349: p_e_L2
line1350">1350: u_e_L2
line1351">1351: u_e_H1
line1352">1352: for (p = 0; p < ngp;
line1353">1353: ShapeFunctionQ13D_Evaluate(gp_xi[p]
line1354">1354: ShapeFunctionQ13D_Evaluate_dxi(gp_xi[p],
line1355">1355: ShapeFunctionQ13D_Evaluate_dx(GNi_p,GNx_p,el_coords,&am
line1356">1356: fac = gp_weight[
line1358">1358: for (i = 0; i < NODES_PER_EL;
line1359">1359: PetscScalar u_error,v_error,w
line1361">1361: p_e_L2 = p_e_L2+fac*Ni_p[i]*(stokes_e[i].p_dof-stokes_analytic_e[i].p_dof)*(stokes_e[i].p_dof-stokes_analytic_e[i].
line1363">1363: u_error = stokes_e[i].u_dof-stokes_analytic_e[i]
line1364">1364: v_error = stokes_e[i].v_dof-stokes_analytic_e[i]
line1365">1365: w_error = stokes_e[i].w_dof-stokes_analytic_e[i]
/*
if (p==0) {
printf("p=0: %d %d %d %1.4e,%1.4e,%1.4e \n", ei,ej,ek,u_error,v_error,w_error);
}
*/
line1371">1371: u_e_L2 += fac*Ni_p[i]*(u_error*u_error+v_error*v_error+w_error*w_
/* du/dx */
line1374">1374: +GNx_p[1][i]*u_error*GNx_p[1][i]*
line1375">1375: +GNx_p[2][i]*u_error*GNx_p[2][i]*
/* dv/dx */
line1377">1377: +GNx_p[1][i]*v_error*GNx_p[1][i]*
line1378">1378: +GNx_p[2][i]*v_error*GNx_p[2][i]*
/* dw/dx */
line1380">1380: +GNx_p[1][i]*w_error*GNx_p[1][i]*
line1381">1381: +GNx_p[2][i]*w_error*GNx_p[2][i]*w_e
line1382">1382:
line1383">1383:
line1385">1385: tp_L2 +=
line1386">1386: tu_L2 +=
line1387">1387: tu_H1 +=
line1388">1388:
line1389">1389:
line1390">1390:
line1391">1391: MPI_Allreduce (&tp_L2,&p_L2,1,MPIU_SCALAR ,MPIU_SUM,PETSC_COMM_WORL
line1392">1392: MPI_Allreduce (&tu_L2,&u_L2,1,MPIU_SCALAR ,MPIU_SUM,PETSC_COMM_WORL
line1393">1393: MPI_Allreduce (&tu_H1,&u_H1,1,MPIU_SCALAR ,MPIU_SUM,PETSC_COMM_WORL
line1394">1394: p_L2 = PetscSqrtScalar
line1395">1395: u_L2 = PetscSqrtScalar
line1396">1396: u_H1 = PetscSqrtScalar
line1398">1398: PetscPrintf (PETSC_COMM_WORLD ,"%1.4e %1.4e %1.4e %1.4e \n" ,PetscRealPart(h),PetscRealPart(p_L2),PetscRealPart(u_L2),PetscRealPart(
line1401">1401: DMDAVecRestoreArray (cda,coords,&_c
line1403">1403: DMDAVecRestoreArray (stokes_da,X_analytic_local,&stokes_ana
line1404">1404: VecDestroy (&X_analytic_
line1405">1405: DMDAVecRestoreArray (stokes_da,X_local,&s
line1406">1406: VecDestroy (&X_
line1407">1407: return
line1408">1408
line1412">1412: PetscErrorCode DAView_3DVTK_StructuredGrid_appended(DM da,Vec FIELD,const char file_prefix[])
line1413">1413
line1414">1414: char vtk_filename[PETSC_MAX_PAT
line1415">1415: PetscMPIInt
line1416">1416: MPI_Comm
line1417">1417: FILE *vtk_fp = PETSC_NU
line1418">1418: PetscInt si,sj,sk,nx,n
line1419">1419: PetscInt f,n_fi
line1420">1420: DM
line1421">1421: Vec
line1422">1422: Vec l
line1423">1423: PetscScalar *_L
line1424">1424: PetscInt memory_
line1425">1425: PetscScalar *
line1426">1426: PetscLogDouble
line1430">1430: PetscGetTime (&a
/* create file name */
line1433">1433: PetscObjectGetComm ((PetscObject )da,&
line1434">1434: MPI_Comm_rank (comm,&
line1435">1435: PetscSNPrintf (vtk_filename,sizeof vtk_filename,"subdomain-%s-p%1.4d.vts" ,file_prefix
/* open file and write header */
line1438">1438: vtk_fp = fopen(vtk_filename,"w"
line1439">1439: if (!vtk_fp) SETERRQ1 (PETSC_COMM_SELF ,PETSC_ERR_SYS,"Cannot open file = %s \n" ,vtk_fil
line1441">1441: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp,"<?xml version=\"1.0\"?>\n"
/* coords */
line1444">1444: DMDAGetGhostCorners (da,&si,&sj,&sk,&nx,&ny,&a
line1445">1445: N = nx * n
line1447">1447: #ifdef PETSC_WORDS_BIGENDIAN
line1448">1448: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp,"<VTKFile type=\"StructuredGrid\" version=\"0.1\" byte_order=\"BigEndian\">\n"
line1449">1449: #else
line1450">1450: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp,"<VTKFile type=\"StructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n"
line1451">1451: #endif
line1452">1452: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp," <StructuredGrid WholeExtent=\"%D %D %D %D %D %D\">\n" ,si,si+nx-1,sj,sj+ny-1,sk,sk
line1453">1453: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp," <Piece Extent=\"%D %D %D %D %D %D\">\n" ,si,si+nx-1,sj,sj+ny-1,sk,sk
line1455">1455: memory_offs
line1457">1457: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp," <CellData></CellData>\n"
line1459">1459: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp," <Points>\n"
/* copy coordinates */
line1462">1462: DMDAGetCoordinateDA (da,&am
line1463">1463: DMDAGetGhostedCoordinates (da,&c
line1464">1464: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp," <DataArray type=\"Float64\" NumberOfComponents=\"3\" format=\"appended\" offset=\"%d\" />\n" ,memory_o
line1465">1465: memory_offset = memory_offset + sizeof (PetscInt ) + sizeof (PetscScalar
line1467">1467: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp," </Points>\n"
line1469">1469: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp," <PointData Scalars=\" "
line1470">1470: DMDAGetInfo (da,0,0,0,0,0,0,0,&n_fields,0,0,
line1471">1471: for (f=0; f<n_fields;
line1472">1472: const char *fiel
line1473">1473: DMDAGetFieldName (da,f,&field
line1474">1474: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp,"%s " ,field
line1475">1475:
line1476">1476: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp,"\">\n"
line1478">1478: for (f=0; f<n_fields;
line1479">1479: const char *fiel
line1481">1481: DMDAGetFieldName (da,f,&field
line1482">1482: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp," <DataArray type=\"Float64\" Name=\"%s\" format=\"appended\" offset=\"%d\"/>\n" , field_name,memory_o
line1483">1483: memory_offset = memory_offset + sizeof (PetscInt ) + sizeof (PetscScalar<
line1484">1484:
line1486">1486: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp," </PointData>\n"
line1487">1487: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp," </Piece>\n"
line1488">1488: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp," </StructuredGrid>\n"
line1490">1490: PetscMalloc (sizeof (PetscScalar )*N,&b
line1491">1491: DMGetLocalVector (da,&l_
line1492">1492: DMGlobalToLocalBegin (da, FIELD,INSERT_VALUES ,l_
line1493">1493: DMGlobalToLocalEnd (da,FIELD,INSERT_VALUES ,l_
line1494">1494: VecGetArray (l_FIELD,&_L_
line1496">1496: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp," <AppendedData encoding=\"raw\">\n"
line1497">1497: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp,"_"
/* write coordinates */
line1500">1500:
line1501">1501: int length = sizeof (PetscScalar
line1502">1502: PetscScalar *all
line1504">1504: fwrite(&length,sizeof (int),1,v
line1505">1505: VecGetArray (coords,&allc
line1506">1506: fwrite(allcoords,sizeof (PetscScalar ),3*N,v
line1507">1507: VecRestoreArray (coords,&allc
line1508">1508:
/* write fields */
line1510">1510: for (f=0; f<n_fields;
line1511">1511: int length = sizeof (PetscScalar<
line1512">1512: fwrite(&length,sizeof (int),1,v
/* load */
line1514">1514: for (i=0; i<N;
line1515">1515: buffer[i] = _L_FIELD[n_fields*
line1516">1516:
/* write */
line1519">1519: fwrite(buffer,sizeof (PetscScalar ),N,v
line1520">1520:
line1521">1521: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp,"\n </AppendedData>\n"
line1523">1523: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp,"</VTKFile>\n"
line1525">1525: PetscFree (b
line1526">1526: VecRestoreArray (l_FIELD,&_L_
line1527">1527: DMRestoreLocalVector (da,&l_
line1529">1529: if (vt
line1530">1530: fclose(v
line1531">1531: vtk_fp
line1532">1532:
line1534">1534: PetscGetTime (&a
line1535">1535: return
line1536">1536
line1540">1540: PetscErrorCode DAViewVTK_write_PieceExtend(FILE *vtk_fp,PetscInt indent_level,DM da,const char local_file_prefix[])
line1541">1541
line1542">1542: PetscMPIInt npro
line1543">1543: MPI_Comm
line1544">1544: const PetscInt *lx,*
line1545">1545: PetscInt M,N,P,pM,pN,pP,sum,*olx,*ol
line1546">1546: PetscInt *osx,*osy,*osz,*oex,*oe
line1547">1547: PetscInt i,j,k,II,s
/* create file name */
line1552">1552: PetscObjectGetComm ((PetscObject )da,&
line1553">1553: MPI_Comm_size (comm,&
line1554">1554: MPI_Comm_rank (comm,&
line1556">1556: DMDAGetInfo (da,0,&M,&N,&P,&pM,&pN,&pP,0,&stencil,0,
line1557">1557: DMDAGetOwnershipRanges (da,&lx,&ly,&a
/* generate start,end list */
line1560">1560: PetscMalloc (sizeof (PetscInt )*(pM+1),&am
line1561">1561: PetscMalloc (sizeof (PetscInt )*(pN+1),&am
line1562">1562: PetscMalloc (sizeof (PetscInt )*(pP+1),&am
line1563">1563: s
line1564">1564: for (i=0; i<pM;
line1565">1565: olx[i]
line1566">1566: sum = sum +
line1567">1567: } olx[pM]
line1568">1568: s
line1569">1569: for (i=0; i<pN;
line1570">1570: oly[i]
line1571">1571: sum = sum +
line1572">1572: } oly[pN]
line1573">1573: s
line1574">1574: for (i=0; i<pP;
line1575">1575: olz[i]
line1576">1576: sum = sum +
line1577">1577: } olz[pP]
line1578">1578: PetscMalloc (sizeof (PetscInt )*(pM),&am
line1579">1579: PetscMalloc (sizeof (PetscInt )*(pN),&am
line1580">1580: PetscMalloc (sizeof (PetscInt )*(pP),&am
line1581">1581: PetscMalloc (sizeof (PetscInt )*(pM),&am
line1582">1582: PetscMalloc (sizeof (PetscInt )*(pN),&am
line1583">1583: PetscMalloc (sizeof (PetscInt )*(pP),&am
line1584">1584: for (i=0; i<pM;
line1585">1585: osx[i] = olx[i] - s
line1586">1586: oex[i] = olx[i] + lx[i] + s
line1587">1587: if (osx[i]<0)os
line1588">1588: if (oex[i]>M)oe
line1589">1589:
line1591">1591: for (i=0; i<pN;
line1592">1592: osy[i] = oly[i] - s
line1593">1593: oey[i] = oly[i] + ly[i] + s
line1594">1594: if (osy[i]<0)os
line1595">1595: if (oey[i]>M)oe
line1596">1596:
line1597">1597: for (i=0; i<pP;
line1598">1598: osz[i] = olz[i] - s
line1599">1599: oez[i] = olz[i] + lz[i] + s
line1600">1600: if (osz[i]<0)os
line1601">1601: if (oez[i]>P)oe
line1602">1602:
line1604">1604: for (k=0; k<pP;
line1605">1605: for (j=0; j<pN;
line1606">1606: for (i=0; i<pM;
line1607">1607: char name[PETSC_MAX_PAT
/* convert proc(i,j,k) to pid */
line1609">1609: PetscSNPrintf (name,sizeof name,"subdomain-%s-p%1.4d.vts" ,local_file_prefix,p
line1610">1610: for (II=0; II<indent_level;
line1611">1611: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp," "
line1612">1612:
line1613">1613: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp,"<Piece Extent=\"%d %d %d %d %d %d\" Source=\"%s\"/>\n"<
line1614">1614: osx[i],oe
line1615">1615: osy[j],oe
line1616">1616: osz[k],oez[k]-1
line1617">1617:
line1618">1618:
line1619">1619:
line1620">1620: PetscFree
line1621">1621: PetscFree
line1622">1622: PetscFree
line1623">1623: PetscFree
line1624">1624: PetscFree
line1625">1625: PetscFree
line1626">1626: PetscFree
line1627">1627: PetscFree
line1628">1628: PetscFree
line1629">1629: return
line1630">1630
line1634">1634: PetscErrorCode DAView_3DVTK_PStructuredGrid(DM da,const char file_prefix[],const char local_file_prefix[])
line1635">1635
line1636">1636: MPI_Comm
line1637">1637: PetscMPIInt npro
line1638">1638: char vtk_filename[PETSC_MAX_PAT
line1639">1639: FILE *vtk_fp = PETSC_NU
line1640">1640: PetscInt M,N,P,si,sj,sk,nx
line1641">1641: PetscInt
/* only master generates this file */
line1646">1646: PetscObjectGetComm ((PetscObject )da,&
line1647">1647: MPI_Comm_size (comm,&
line1648">1648: MPI_Comm_rank (comm,&
line1650">1650: if (rank != 0) { return
/* create file name */
line1653">1653: PetscSNPrintf (vtk_filename,sizeof vtk_filename,"%s.pvts" ,file_p
line1654">1654: vtk_fp = fopen(vtk_filename,"w"
line1655">1655: if (!vtk_fp) { SETERRQ1 (PETSC_COMM_SELF ,PETSC_ERR_SYS,"Cannot open file = %s \n" ,vtk_filen
/* (VTK) generate pvts header */
line1658">1658: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp,"<?xml version=\"1.0\"?>\n"
line1660">1660: #ifdef PETSC_WORDS_BIGENDIAN
line1661">1661: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp,"<VTKFile type=\"PStructuredGrid\" version=\"0.1\" byte_order=\"BigEndian\">\n"
line1662">1662: #else
line1663">1663: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp,"<VTKFile type=\"PStructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n"
line1664">1664: #endif
/* define size of the nodal mesh based on the cell DM */
line1667">1667: DMDAGetInfo (da,0,&M,&N,&P,0,0,0,&dofs,0,0,
line1668">1668: DMDAGetGhostCorners (da,&si,&sj,&sk,&nx,&ny,&a
/* note overlap = 1 for Q1 */
/* DUMP THE CELL REFERENCES */
line1672">1672: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp," <PCellData>\n"
line1673">1673: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp," </PCellData>\n"
line1675">1675: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp," <PPoints>\n"
line1676">1676: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp," <PDataArray type=\"Float64\" Name=\"Points\" NumberOfComponents=\"%d\"/>\n"
line1677">1677: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp," </PPoints>\n"
line1679">1679: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp," <PPointData>\n"
line1680">1680: for (i=0; i<dofs;
line1681">1681: const char *fie
line1682">1682: DMDAGetFieldName (da,i,&fiel
line1683">1683: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp," <PDataArray type=\"Float64\" Name=\"%s\" NumberOfComponents=\"1\"/>\n" ,fiel
line1684">1684:
line1685">1685: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp," </PPointData>\n"
/* write out the parallel information */
line1688">1688: DAViewVTK_write_PieceExtend(vtk_fp,2,da,local_file_p
/* close the file */
line1691">1691: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp," </PStructuredGrid>\n"
line1692">1692: PetscFPrintf (PETSC_COMM_SELF ,vtk_fp,"</VTKFile>\n"
line1694">1694: if (v
line1695">1695: fclose(v
line1696">1696: vtk_fp
line1697">1697:
line1698">1698: return
line1699">1699
line1703">1703: PetscErrorCode DAView3DPVTS(DM da, Vec x,const char NAME[])
line1704">1704
line1705">1705: char vts_filename[PETSC_MAX_PAT
line1706">1706: char pvts_filename[PETSC_MAX_PAT
line1710">1710: PetscSNPrintf (vts_filename,sizeof vts_filename,"%s-mesh"
line1711">1711: DAView_3DVTK_StructuredGrid_appended(da,x,vts_fil
line1713">1713: PetscSNPrintf (pvts_filename,sizeof pvts_filename,"%s-mesh"
line1714">1714: DAView_3DVTK_PStructuredGrid(da,pvts_filename,vts_fil
line1715">1715: return
line1716">1716
line1720">1720: PetscErrorCode KSPMonitorStokesBlocks(KSP ksp,PetscInt n,PetscReal rnorm,void *dummy)
line1721">1721
line1723">1723: PetscReal no
line1724">1724: Vec
line1725">1725: Mat
line1728">1728: KSPGetOperators (ksp,&
line1729">1729: MatGetVecs (A,&w,&
line1731">1731: KSPBuildResidual (ksp,v,w,&a
line1733">1733: VecStrideNorm (Br,0,NORM_2 ,&nor
line1734">1734: VecStrideNorm (Br,1,NORM_2 ,&nor
line1735">1735: VecStrideNorm (Br,2,NORM_2 ,&nor
line1736">1736: VecStrideNorm (Br,3,NORM_2 ,&nor
line1738">1738: VecDestroy (&
line1739">1739: VecDestroy (&
line1741">1741: PetscPrintf (PETSC_COMM_WORLD ,"%3D KSP Component U,V,W,P residual norm [ %1.12e, %1.12e, %1.12e, %1.12e ]\n" ,n,norms[0],norms[1],norms[2],nor
line1742">1742: return
line1743">1743
line1747">1747: static PetscErrorCode PCMGSetupViaCoarsen(PC pc,DM da_fine)
line1748">1748
line1749">1749: PetscInt nlevels,k,PETSC_UNUSED
line1750">1750: DM *da_list,*d
line1751">1751: Mat
line1755">1755: nleve
line1756">1756: PetscOptionsGetInt (PETSC_NULL ,"-levels" ,&nlev
line1758">1758: PetscMalloc (sizeof (DM)*nlevels,&da
line1759">1759: for (k=0; k<nlevels; k++) { da_list[k] = PETSC_NULL<
line1760">1760: PetscMalloc (sizeof (DM)*nlevels,&da
line1761">1761: for (k=0; k<nlevels; k++) { daclist[k] = PETSC_NULL<
/* finest grid is nlevels - 1 */
line1764">1764: finest = nleve
line1765">1765: daclist[0] = d
line1766">1766: PetscObjectReference ((PetscObject )da
line1767">1767: DMCoarsenHierarchy (da_fine,nlevels-1,&dacli
line1768">1768: for (k=0; k<nlevels;
line1769">1769: da_list[k] = daclist[nlevel
line1770">1770: DMDASetUniformCoordinates (da_list[k],0.0,1.0,0.0,1.0,0.
line1771">1771:
line1773">1773: PCMGSetLevels (pc,nlevels,PETSC_NUL
line1774">1774: PCMGSetType (pc,PC_MG_MULTIPLIC
line1775">1775: PCMGSetGalerkin (pc,PETSC_TRU
line1777">1777: for (k=1; k<nlevels
line1778">1778: DMCreateInterpolation (da_list[k-1],da_list[k],&R,PETSC_NUL
line1779">1779: PCMGSetInterpolation (p
line1780">1780: MatDestroy (&
line1781">1781:
/* tidy up */
line1784">1784: for (k=0; k<nlevels;
line1785">1785: DMDestroy (&da_li
line1786">1786:
line1787">1787: PetscFree (da
line1788">1788: PetscFree (da
line1789">1789: return
line1790">1790
line1794">1794: static PetscErrorCode solve_stokes_3d_coupled(PetscInt mx,PetscInt my,PetscInt mz)
line1795">1795
line1796">1796: DM da_
line1797">1797: PetscInt u_dof,p_dof,dof,stencil
line1798">1798: Mat
line1799">1799: PetscInt mxl,m
line1800">1800: DM v
line1801">1801: Vec vel_
line1802">1802: PetscInt
line1803">1803: Vec
line1804">1804: DMDACoor3d ***_vel_
line1805">1805: PetscInt
line1806">1806: KSP
line1807">1807: PetscInt model_definiti
line1808">1808: PetscInt ei,ej,ek,sex,sey,sez,Imx,J
line1809">1809: CellProperties cell_prop
line1810">1810: PetscBool write_output = PETSC_FAL
line1811">1811: PetscErrorCode
/* Generate the da for velocity and pressure */
/* Num nodes in each direction is mx+1, my+1, mz+1 */
/* Vx, Vy - velocities */
/* p - pressure */
line1818">1818: dof = u_dof
line1819">1819: stencil_wid
line1820">1820: DMDACreate3d (PETSC_COMM_WORLD ,DMDA_BOUNDARY_NONE,DMDA_BOUNDARY_NONE,DMDA_BOUNDARY_NONE,DMDA_STENCIL_B
line1821">1821: mx+1,my+1,mz+1,PETSC_DECIDE ,PETSC_DECIDE ,PETSC_DECIDE ,dof,stencil_width,PETSC_NULL ,PETSC_NULL ,PETSC_NULL ,&da_S
line1822">1822: DMDASetFieldName (da_Stokes,0,"Vx"
line1823">1823: DMDASetFieldName (da_Stokes,1,"Vy"
line1824">1824: DMDASetFieldName (da_Stokes,2,"Vz"
line1825">1825: DMDASetFieldName (da_Stokes,3,"P"
/* unit box [0,1] x [0,1] x [0,1] */
line1828">1828: DMDASetUniformCoordinates (da_Stokes,0.0,1.0,0.0,1.0,0.
/* local number of elements */
line1831">1831: DMDAGetLocalElementSize(da_Stokes,&mxl,&myl,&am
/* create quadrature point info for PDE coefficients */
line1834">1834: CellPropertiesCreate(da_Stokes,&cell_prope
/* interpolate the coordinates to quadrature points */
line1837">1837: DMDAGetCoordinateDA (da_Stokes,&ve
line1838">1838: DMDAGetGhostedCoordinates (da_Stokes,&vel_c
line1839">1839: DMDAVecGetArray (vel_cda,vel_coords,&_vel_c
line1840">1840: DMDAGetElementCorners(da_Stokes,&sex,&sey,&sez,&Imx,&Jmy,&am
line1841">1841: for (ek = sez; ek < sez+Kmz;
line1842">1842: for (ej = sey; ej < sey+Jmy;
line1843">1843: for (ei = sex; ei < sex+Imx;
/* get coords for the element */
line1845">1845: PetscInt
line1846">1846: PetscScalar gp_xi[GAUSS_POINTS][NSD],gp_weight[GAUSS_P
line1847">1847: PetscScalar el_coords[NSD*NODES_P
line1848">1848: GaussPointCoefficients
line1850">1850: CellPropertiesGetCell(cell_properties,ei,ej,ek,&
line1851">1851: GetElementCoords3D(_vel_coords,ei,ej,ek,el_c
line1852">1852: ConstructGaussQuadrature3D(&ngp,gp_xi,gp_w
line1854">1854: for (p = 0; p < GAUSS_POINTS;
line1855">1855: PetscScalar xi_p[NSD],Ni_p[NODES_P
line1856">1856: PetscScalar gp_x,gp_
line1857">1857: PetscInt
line1859">1859: xi_p[0] = gp_xi
line1860">1860: xi_p[1] = gp_xi
line1861">1861: xi_p[2] = gp_xi
line1862">1862: ShapeFunctionQ13D_Evaluate(xi_p
line1864">1864: gp_x = gp_y = gp_z
line1865">1865: for (n = 0; n < NODES_PER_EL;
line1866">1866: gp_x = gp_x+Ni_p[n]*el_coords[NS
line1867">1867: gp_y = gp_y+Ni_p[n]*el_coords[NS
line1868">1868: gp_z = gp_z+Ni_p[n]*el_coords[NS
line1869">1869:
line1870">1870: cell->gp_coords[NSD*p ]
line1871">1871: cell->gp_coords[NSD*p+1]
line1872">1872: cell->gp_coords[NSD*p+2]
line1873">1873:
line1874">1874:
line1875">1875:
line1876">1876:
line1878">1878: PetscOptionsGetInt (PETSC_NULL ,"-model" ,&model_definition,PETSC_NUL
line1880">1880: switch (model_defini
/* isoviscous */
line1882">1882: for (ek = sez; ek < sez+Kmz;
line1883">1883: for (ej = sey; ej < sey+Jmy;
line1884">1884: for (ei = sex; ei < sex+Imx;
line1885">1885: GaussPointCoefficients
line1887">1887: CellPropertiesGetCell(cell_properties,ei,ej,ek,&
line1888">1888: for (p = 0; p < GAUSS_POINTS;
line1889">1889: PetscReal coord_x = PetscRealPart(cell->gp_coords[NSD
line1890">1890: PetscReal coord_y = PetscRealPart(cell->gp_coords[NSD
line1891">1891: PetscReal coord_z = PetscRealPart(cell->gp_coords[NSD
line1893">1893: cell->eta[p]
line1895">1895: cell->fx[p] = 0.0*c
line1896">1896: cell->fy[p] = -sin((double)2.2*M_PI*coord_y)*cos(1.0*M_PI*co
line1897">1897: cell->fz[p] = 0.0*c
line1898">1898: cell->hc[p]
line1899">1899:
line1900">1900:
line1901">1901:
line1902">1902:
line1903">1903: break<
/* manufactured */
line1906">1906: for (ek = sez; ek < sez+Kmz;
line1907">1907: for (ej = sey; ej < sey+Jmy;
line1908">1908: for (ei = sex; ei < sex+Imx;
line1909">1909: PetscReal eta,Fm[NSD],Fc,po
line1910">1910: GaussPointCoefficients
line1912">1912: CellPropertiesGetCell(cell_properties,ei,ej,ek,&
line1913">1913: for (p = 0; p < GAUSS_POINTS;
line1914">1914: PetscReal coord_x = PetscRealPart(cell->gp_coords[NSD
line1915">1915: PetscReal coord_y = PetscRealPart(cell->gp_coords[NSD
line1916">1916: PetscReal coord_z = PetscRealPart(cell->gp_coords[NSD
line1918">1918: pos[0] = c
line1919">1919: pos[1] = c
line1920">1920: pos[2] = c
line1922">1922: evaluate_MS_FrankKamentski(pos,PETSC_NULL ,PETSC_NULL ,&eta,Fm,&a
line1923">1923: cell->eta[p]
line1925">1925: cell->fx[p] =
line1926">1926: cell->fy[p] =
line1927">1927: cell->fz[p] =
line1928">1928: cell->hc[p
line1929">1929:
line1930">1930:
line1931">1931:
line1932">1932:
line1933">1933: break<
/* solcx */
line1936">1936: for (ek = sez; ek < sez+Kmz;
line1937">1937: for (ej = sey; ej < sey+Jmy;
line1938">1938: for (ei = sex; ei < sex+Imx;
line1939">1939: GaussPointCoefficients
line1941">1941: CellPropertiesGetCell(cell_properties,ei,ej,ek,&
line1942">1942: for (p = 0; p < GAUSS_POINTS;
line1943">1943: PetscReal coord_x = PetscRealPart(cell->gp_coords[NSD
line1944">1944: PetscReal coord_y = PetscRealPart(cell->gp_coords[NSD
line1945">1945: PetscReal coord_z = PetscRealPart(cell->gp_coords[NSD
line1947">1947: cell->eta[p]
line1949">1949: cell->fx[p]
line1950">1950: cell->fy[p] = -sin((double)3*M_PI*coord_y)*cos(1.0*M_PI*co
line1951">1951: cell->fz[p] = 0.0*c
line1952">1952: cell->hc[p]
line1953">1953:
line1954">1954:
line1955">1955:
line1956">1956:
line1957">1957: break<
/* sinker */
line1960">1960: for (ek = sez; ek < sez+Kmz;
line1961">1961: for (ej = sey; ej < sey+Jmy;
line1962">1962: for (ei = sex; ei < sex+Imx;
line1963">1963: GaussPointCoefficients
line1965">1965: CellPropertiesGetCell(cell_properties,ei,ej,ek,&
line1966">1966: for (p = 0; p < GAUSS_POINTS;
line1967">1967: PetscReal xp = PetscRealPart(cell->gp_coords[NSD
line1968">1968: PetscReal yp = PetscRealPart(cell->gp_coords[NSD
line1969">1969: PetscReal zp = PetscRealPart(cell->gp_coords[NSD
line1971">1971: cell->eta[p] =
line1972">1972: cell->fx[p]
line1973">1973: cell->fy[p]
line1974">1974: cell->fz[p]
line1975">1975: cell->hc[p]
line1977">1977: if ( (fabs(xp-0.5) < 0.2) &am
line1978">1978: (fabs(yp-0.5) < 0.2) &am
line1979">1979: (fabs(zp-0.5) < 0
line1980">1980: cell->eta[p]
line1981">1981: cell->fz[p]
line1982">1982:
line1984">1984:
line1985">1985:
line1986">1986:
line1987">1987:
line1988">1988: break<
line1990">1990: default:
line1991">1991: SETERRQ (PETSC_COMM_WORLD ,PETSC_ERR_SUP,"No default model is supported. Choose either -model {0,1,2,3}"
line1992">1992: break<
line1993">1993:
line1995">1995: DMDAVecRestoreArray (vel_cda,vel_coords,&_vel_c
/* Generate a matrix with the correct non-zero pattern of type AIJ. This will work in parallel and serial */
line1998">1998: DMCreateMatrix (da_Stokes,MATAIJ ,&
line1999">1999: DMCreateMatrix (da_Stokes,MATAIJ ,&
line2000">2000: DMCreateGlobalVector (da_Stokes,&
line2001">2001: DMCreateGlobalVector (da_Stokes,&
/* assemble A11 */
line2004">2004: MatZeroEntries<
line2005">2005: MatZeroEntries<
line2006">2006: VecZeroEntries<
line2008">2008: AssembleA_Stokes(A,da_Stokes,cell_prope
line2009">2009: AssembleA_PCStokes(B,da_Stokes,cell_prope
/* build force vector */
line2011">2011: AssembleF_Stokes(f,da_Stokes,cell_prope
/* SOLVE */
line2014">2014: KSPCreate (PETSC_COMM_WORLD ,&
/* stokes */
line2016">2016: KSPSetOperators (ksp_S,A,B,SAME_NONZERO_PA
line2017">2017: KSPSetFromOptions (
line2019">2019:
line2020">2020: PC<
line2021">2021: const PetscInt ufields[] = {0,1,2},pfields[]
line2022">2022: KSPGetPC (ksp_S,&a
line2023">2023: PCFieldSplitSetBlockSize
line2024">2024: PCFieldSplitSetFields (pc,"u" ,3,ufields,uf
line2025">2025: PCFieldSplitSetFields (pc,"p" ,1,pfields,pf
line2026">2026:
line2028">2028:
line2029">2029: PC<
line2030">2030: PetscBool same = PETSC_FAL
line2031">2031: KSPGetPC (ksp_S,&a
line2032">2032: PetscObjectTypeCompare ((PetscObject )pc,PCMG ,&
line2033">2033: if (
line2034">2034: PCMGSetupViaCoarsen(pc,da_S
line2035">2035:
line2036">2036:
line2038">2038:
line2039">2039: PetscBool stokes_monitor = PETSC_FAL
line2040">2040: PetscOptionsGetBool (PETSC_NULL ,"-stokes_ksp_monitor_blocks" ,&stokes_moni
line2041">2041: if (stokes_mon
line2042">2042: KSPMonitorSet (ksp_S,KSPMonitorStokesBlocks,PETSC_NULL ,PETSC_NUL
line2043">2043:
line2044">2044:
line2045">2045: KSPSolve (ksp_
line2047">2047: PetscOptionsGetBool (PETSC_NULL ,"-write_pvts" ,&write_output,PETSC_NUL
line2048">2048: if (write_output) {DAView3DPVTS(da_Stokes,X,"up"
line2049">2049:
line2050">2050: PetscBool flg = PETSC_FAL
line2051">2051: char filename[PETSC_MAX_PAT
line2052">2052: PetscOptionsGetString (PETSC_NULL ,"-write_binary" ,filename,sizeof filename,&am
line2053">2053: if
line2054">2054: PetscViewer
line2055">2055: //PetscViewerBinaryOpen (PETSC_COMM_WORLD ,filename[0]?filename:"ex42-binaryoutput" ,FILE_MODE_WRITE,&v
line2056">2056: PetscViewerVTKOpen (PETSC_COMM_WORLD ,"ex42.vts" ,FILE_MODE_WRITE,&v
line2057">2057: VecView (X,v
line2058">2058: PetscViewerDestroy (&v
line2059">2059:
line2060">2060:
line2061">2061: KSPGetIterationNumber (ksp_S,&am
/* verify */
line2064">2064: if (model_definition
line2065">2065: DM da_Stokes_an
line2066">2066: Vec X_an
line2068">2068: DMDACreateManufacturedSolution(mx,my,mz,&da_Stokes_analytic,&X_ana
line2069">2069: if (write_ou
line2070">2070: DAView3DPVTS(da_Stokes_analytic,X_analytic,"ms"
line2071">2071:
line2072">2072: DMDAIntegrateErrors3D(da_Stokes_analytic,X,X_ana
line2073">2073: if (write_ou
line2074">2074: DAView3DPVTS(da_Stokes,X,"up2"
line2075">2075:
line2076">2076: DMDestroy (&da_Stokes_ana
line2077">2077: VecDestroy (&X_ana
line2078">2078:
line2080">2080: KSPDestroy (&
line2081">2081: VecDestroy (&
line2082">2082: VecDestroy (&
line2083">2083: MatDestroy (&
line2084">2084: MatDestroy (&
line2086">2086: CellPropertiesDestroy(&cell_prope
line2087">2087: DMDestroy (&da_S
line2088">2088: return
line2089">2089
line2093">2093: int main(int argc,char **args)
line2094">2094
line2096">2096: PetscInt mx
line2098">2098: PetscInitialize (&argc,&args,(char *)0
line2100">2100: mx = my = m
line2101">2101: PetscOptionsGetInt (PETSC_NULL ,"-mx" ,&mx,PETSC_NUL
line2102">2102: my = mx; m
line2103">2103: PetscOptionsGetInt (PETSC_NULL ,"-my" ,&my,PETSC_NUL
line2104">2104: PetscOptionsGetInt (PETSC_NULL ,"-mz" ,&mz,PETSC_NUL
line2106">2106: solve_stokes_3d_coupled(mx,
line2108">2108: PetscFinalize
line2109">2109: return
line2110">2110