25 #define SF_MAX_ELEM_NODES 10
48 if (order == 1) ndof = 2;
49 else if (order == 2) ndof = 3;
51 fprintf(stderr,
"Line element order %d not implemented yet.\n", order);
56 if (order == 1) ndof = 3;
57 else if (order == 2) ndof = 6;
59 fprintf(stderr,
"Tri element order %d not implemented yet.\n", order);
64 if (order == 1) ndof = 4;
65 else if (order == 2) ndof = 8;
67 fprintf(stderr,
"Quad element order %d not implemented yet.\n", order);
72 if (order == 1) ndof = 4;
73 else if (order == 2) ndof = 10;
75 fprintf(stderr,
"Tetra element order %d not implemented yet.\n", order);
80 if (order == 1) ndof = 8;
81 else if (order == 2) ndof = 20;
83 fprintf(stderr,
"Hexa element order %d not implemented yet.\n", order);
89 fprintf(stderr,
"%s error: Unsupported element type.\n", __func__);
115 ip[0].
x = 0.; ip[0].
y = 0.; ip[0].
z = 0.;
117 }
else if (order == 2) {
118 const double sqrt3 = 0.577350269189626;
119 ip[0].
x = -sqrt3; ip[0].
y = 0.; ip[0].
z = 0.;
120 ip[1].
x = +sqrt3; ip[1].
y = 0.; ip[1].
z = 0.;
121 w[0] = 1.; w[1] = 1.; nint = 2;
127 ip[0].
x = 1. / 3.; ip[0].
y = 1. / 3.; ip[0].
z = 0.;
130 }
else if (order == 2) {
131 ip[0].
x = 1. / 6.; ip[0].
y = 1. / 6.; ip[0].
z = 0.;
132 ip[1].
x = 4. / 6.; ip[1].
y = 1. / 6.; ip[1].
z = 0.;
133 ip[2].
x = 1. / 6.; ip[2].
y = 4. / 6.; ip[2].
z = 0.;
134 w[0] = 1. / 6.; w[1] = 1. / 6.; w[2] = 1. / 6.;
136 }
else if (order == 3 || order == 4) {
138 ip[0].
x = 0.188409405952072339650, ip[0].
y = 0.787659461760847001700, ip[0].
z = 0;
139 ip[1].
x = 0.523979067720100721850, ip[1].
y = 0.409466864440734712450, ip[1].
z = 0;
140 ip[2].
x = 0.808694385677669824730, ip[2].
y = 0.088587959512703928766, ip[2].
z = 0;
141 ip[3].
x = 0.106170269119576471390, ip[3].
y = 0.787659461760847001700, ip[3].
z = 0;
142 ip[4].
x = 0.295266567779632616020, ip[4].
y = 0.409466864440734712450, ip[4].
z = 0;
143 ip[5].
x = 0.455706020243648035620, ip[5].
y = 0.088587959512703928766, ip[5].
z = 0;
144 ip[6].
x = 0.023931132287080617016, ip[6].
y = 0.787659461760847001700, ip[6].
z = 0;
145 ip[7].
x = 0.066554067839164496312, ip[7].
y = 0.409466864440734712450, ip[7].
z = 0;
146 ip[8].
x = 0.102717654809626260380, ip[8].
y = 0.088587959512703928766, ip[8].
z = 0;
148 w[0] = 0.019396383305959434551;
149 w[1] = 0.063678085099884929043;
150 w[2] = 0.055814420483044288601;
151 w[3] = 0.03103421328953510222;
152 w[4] = 0.1018849361598159059;
153 w[5] = 0.089303072772870889517;
154 w[6] = 0.019396383305959434551;
155 w[7] = 0.063678085099884929043;
156 w[8] = 0.055814420483044288601;
163 ip[0].
x = 0.; ip[0].
y = 0.; ip[0].
z = 0.;
166 }
else if (order == 2 || order == 3) {
167 const double sqrt3 = 0.577350269189626;
168 ip[0].
x = -sqrt3; ip[0].
y = -sqrt3; ip[0].
z = 0.;
169 ip[1].
x = +sqrt3; ip[1].
y = -sqrt3; ip[1].
z = 0.;
170 ip[2].
x = +sqrt3; ip[2].
y = +sqrt3; ip[2].
z = 0.;
171 ip[3].
x = -sqrt3; ip[3].
y = +sqrt3; ip[3].
z = 0.;
172 w[0] = 1.; w[1] = 1.; w[2] = 1.; w[3] = 1.;
174 }
else if (order == 4) {
176 ip[0].
x = 0.88729833462074170214, ip[0].
y = 0.88729833462074170214, ip[0].
z = 0;
177 ip[1].
x = 0.88729833462074170214, ip[1].
y = 0.5, ip[1].
z = 0;
178 ip[2].
x = 0.88729833462074170214, ip[2].
y = 0.11270166537925829786, ip[2].
z = 0;
179 ip[3].
x = 0.5, ip[3].
y = 0.88729833462074170214, ip[3].
z = 0;
180 ip[4].
x = 0.5, ip[4].
y = 0.5, ip[4].
z = 0;
181 ip[5].
x = 0.5, ip[5].
y = 0.11270166537925829786, ip[5].
z = 0;
182 ip[6].
x = 0.11270166537925829786, ip[6].
y = 0.88729833462074170214, ip[6].
z = 0;
183 ip[7].
x = 0.11270166537925829786, ip[7].
y = 0.5, ip[7].
z = 0;
184 ip[8].
x = 0.11270166537925829786, ip[8].
y = 0.11270166537925829786, ip[8].
z = 0;
186 w[0] = 0.077160493827160225866;
187 w[1] = 0.12345679012345638081;
188 w[2] = 0.077160493827160225866;
189 w[3] = 0.12345679012345638081;
190 w[4] = 0.19753086419753024261;
191 w[5] = 0.12345679012345638081;
192 w[6] = 0.077160493827160225866;
193 w[7] = 0.12345679012345638081;
194 w[8] = 0.077160493827160225866;
201 if (order == 0 || order == 1) {
203 ip[0].
x = 0.25; ip[0].
y = 0.25; ip[0].
z = 0.25;
204 w[0] = .16666666666666666666;
206 }
else if (order == 2) {
208 double gauss1 = 0.13819660112501051518;
209 double gauss2 = 0.58541019662496845446;
210 double weight = 0.0416666666666666666666666666666666;
211 ip[0].
x = gauss1; ip[0].
y = gauss1; ip[0].
z = gauss1;
212 ip[1].
x = gauss2; ip[1].
y = gauss1; ip[1].
z = gauss1;
213 ip[2].
x = gauss1; ip[2].
y = gauss2; ip[2].
z = gauss1;
214 ip[3].
x = gauss1; ip[3].
y = gauss1; ip[3].
z = gauss2;
215 w[0] = weight; w[1] = weight; w[2] = weight; w[3] = weight;
217 }
else if (order == 3 || order == 4) {
219 ip[0].
x = 0.12764656212038541505, ip[0].
y = 0.29399880063162286969, ip[0].
z = 0.54415184401122529412;
220 ip[1].
x = 0.2457133252117133515, ip[1].
y = 0.56593316507280100325, ip[1].
z = 0.12251482265544139105;
221 ip[2].
x = 0.30377276481470755209, ip[2].
y = 0.070679724159396897787, ip[2].
z = 0.54415184401122529412;
222 ip[3].
x = 0.58474756320489440498, ip[3].
y = 0.13605497680284600603, ip[3].
z = 0.12251482265544139105;
223 ip[4].
x = 0.034202793236766414198, ip[4].
y = 0.29399880063162286969, ip[4].
z = 0.54415184401122529412;
224 ip[5].
x = 0.065838687060044420729, ip[5].
y = 0.56593316507280100325, ip[5].
z = 0.12251482265544139105;
225 ip[6].
x = 0.081395667014670256001, ip[6].
y = 0.070679724159396897787, ip[6].
z = 0.54415184401122529412;
226 ip[7].
x = 0.15668263733681833672, ip[7].
y = 0.13605497680284600603, ip[7].
z = 0.12251482265544139105;
228 w[0] = 0.0091694299214797256314;
229 w[1] = 0.0211570064545240181520;
230 w[2] = 0.0160270405984766287080;
231 w[3] = 0.0369798563588529458080;
232 w[4] = 0.0091694299214797291009;
233 w[5] = 0.0211570064545240285600;
234 w[6] = 0.0160270405984766356470;
235 w[7] = 0.0369798563588529666250;
243 ip[0].
x = 0.; ip[0].
y = 0.; ip[0].
z = 0.;
246 }
else if (order == 1 || order == 2) {
247 const double sqrt3 = 0.577350269189626;
248 ip[0].
x = -sqrt3; ip[0].
y = -sqrt3; ip[0].
z = -sqrt3;
249 ip[1].
x = +sqrt3; ip[1].
y = -sqrt3; ip[1].
z = -sqrt3;
250 ip[2].
x = +sqrt3; ip[2].
y = +sqrt3; ip[2].
z = -sqrt3;
251 ip[3].
x = -sqrt3; ip[3].
y = +sqrt3; ip[3].
z = -sqrt3;
252 ip[4].
x = -sqrt3; ip[4].
y = -sqrt3; ip[4].
z = +sqrt3;
253 ip[5].
x = +sqrt3; ip[5].
y = -sqrt3; ip[5].
z = +sqrt3;
254 ip[6].
x = +sqrt3; ip[6].
y = +sqrt3; ip[6].
z = +sqrt3;
255 ip[7].
x = -sqrt3; ip[7].
y = +sqrt3; ip[7].
z = +sqrt3;
256 w[0] = 1.; w[1] = 1.; w[2] = 1.; w[3] = 1.;
257 w[4] = 1.; w[5] = 1.; w[6] = 1.; w[7] = 1.;
264 ip[0].
x = 0.33333333333333331, ip[0].
y = 0.33333333333333337, ip[0].
z = 0.5;
267 }
else if(order == 1 || order == 2) {
269 ip[0].
x = 0.8168475628; ip[0].
y = 0.0915762112; ip[0].
z = 0.2113248706;
270 ip[1].
x = 0.8168475628; ip[1].
y = 0.0915762112; ip[1].
z = 0.7886751294;
271 ip[2].
x = 0.0915762112; ip[2].
y = 0.8168475628; ip[2].
z = 0.2113248706;
272 ip[3].
x = 0.0915762112; ip[3].
y = 0.8168475628; ip[3].
z = 0.7886751294;
273 ip[4].
x = 0.0915762112; ip[4].
y = 0.0915762112; ip[4].
z = 0.2113248706;
274 ip[5].
x = 0.0915762112; ip[5].
y = 0.0915762112; ip[5].
z = 0.7886751294;
283 ip[0].
x = 0.28001991549907407, ip[0].
y = 0.64494897427831788, ip[0].
z = 0.78867513459481287;
284 ip[1].
x = 0.28001991549907407, ip[1].
y = 0.64494897427831788, ip[1].
z = 0.21132486540518713;
285 ip[2].
x = 0.66639024601470143, ip[2].
y = 0.15505102572168217, ip[2].
z = 0.78867513459481287;
286 ip[3].
x = 0.66639024601470143, ip[3].
y = 0.15505102572168217, ip[3].
z = 0.21132486540518713;
287 ip[4].
x = 0.075031110222608124, ip[4].
y = 0.64494897427831788, ip[4].
z = 0.78867513459481287;
288 ip[5].
x = 0.075031110222608124, ip[5].
y = 0.64494897427831788, ip[5].
z = 0.21132486540518713;
289 ip[6].
x = 0.17855872826361643, ip[6].
y = 0.15505102572168217, ip[6].
z = 0.78867513459481287;
290 ip[7].
x = 0.17855872826361643, ip[7].
y = 0.15505102572168217, ip[7].
z = 0.21132486540518713;
291 w[0] = 0.045489654564005534;
292 w[1] = 0.045489654564005548;
293 w[2] = 0.079510345435994237;
294 w[3] = 0.079510345435994265;
295 w[4] = 0.045489654564005548;
296 w[5] = 0.045489654564005562;
297 w[6] = 0.079510345435994265;
298 w[7] = 0.079510345435994292;
306 ip[0].
x = -0.433013; ip[0].
y = -0.433013; ip[0].
z = 0.25;
307 ip[1].
x = 0.433013; ip[1].
y = -0.433013; ip[1].
z = 0.25;
308 ip[2].
x = 0.433013; ip[2].
y = 0.433013; ip[2].
z = 0.25;
309 ip[3].
x = -0.433013; ip[3].
y = 0.433013; ip[3].
z = 0.25;
315 }
else if (order == 2) {
316 ip[0 ].
x = 0.040086493940919059, ip[0 ].
y = 0.040086493940919059, ip[0 ].
z = 0.93056815579702623;
317 ip[1 ].
x = 0.19053106107826956, ip[1 ].
y = 0.19053106107826956, ip[1 ].
z = 0.66999052179242813;
318 ip[2 ].
x = 0.38681920811135617, ip[2 ].
y = 0.38681920811135617, ip[2 ].
z = 0.33000947820757187;
319 ip[3 ].
x = 0.53726377524870672, ip[3 ].
y = 0.53726377524870672, ip[3 ].
z = 0.069431844202973714;
320 ip[4 ].
x = 0.040086493940919059, ip[4 ].
y = -0.040086493940919059, ip[4 ].
z = 0.93056815579702623;
321 ip[5 ].
x = 0.19053106107826956, ip[5 ].
y = -0.19053106107826956, ip[5 ].
z = 0.66999052179242813;
322 ip[6 ].
x = 0.38681920811135617, ip[6 ].
y = -0.38681920811135617, ip[6 ].
z = 0.33000947820757187;
323 ip[7 ].
x = 0.53726377524870672, ip[7 ].
y = -0.53726377524870672, ip[7 ].
z = 0.069431844202973714;
324 ip[8 ].
x = -0.040086493940919059, ip[8 ].
y = 0.040086493940919059, ip[8 ].
z = 0.93056815579702623;
325 ip[9 ].
x = -0.19053106107826956, ip[9 ].
y = 0.19053106107826956, ip[9 ].
z = 0.66999052179242813;
326 ip[10].
x = -0.38681920811135617, ip[10].
y = 0.38681920811135617, ip[10].
z = 0.33000947820757187;
327 ip[11].
x = -0.53726377524870672, ip[11].
y = 0.53726377524870672, ip[11].
z = 0.069431844202973714;
328 ip[12].
x = -0.040086493940919059, ip[12].
y = -0.040086493940919059, ip[12].
z = 0.93056815579702623;
329 ip[13].
x = -0.19053106107826956, ip[13].
y = -0.19053106107826956, ip[13].
z = 0.66999052179242813;
330 ip[14].
x = -0.38681920811135617, ip[14].
y = -0.38681920811135617, ip[14].
z = 0.33000947820757187;
331 ip[15].
x = -0.53726377524870672, ip[15].
y = -0.53726377524870672, ip[15].
z = 0.069431844202973714;
333 w[0 ] = 0.000838466012258970;
334 w[1 ] = 0.035511343496716564;
335 w[2 ] = 0.14636983865620462;
336 w[3 ] = 0.15061368516815288;
337 w[4 ] = 0.000838466012258971;
338 w[5 ] = 0.035511343496716585;
339 w[6 ] = 0.1463698386562047;
340 w[7 ] = 0.15061368516815296;
341 w[8 ] = 0.000838466012258971;
342 w[9 ] = 0.035511343496716585;
343 w[10] = 0.1463698386562047;
344 w[11] = 0.15061368516815296;
345 w[12] = 0.000838466012258971;
346 w[13] = 0.035511343496716599;
347 w[14] = 0.14636983865620476;
348 w[15] = 0.15061368516815302;
354 fprintf(stderr,
"%s error: Unsupported element type.\n", __func__);
375 rshape[0][0] = 0.5 * (1.0 - ip.
x);
376 rshape[0][1] = 0.5 * (1.0 + ip.
x);
391 double lam0 = (1.0 - ip.
x - ip.
y);
418 const double node[4][2] =
427 int v[4] = {0, 1, 2, 3};
429 for (
int i = 0; i < 4; i++) {
431 rshape[0][i] = qrtr * (1. + ip.
x * node[v[i]][0]) * (1. + ip.
y * node[v[i]][1]);
433 rshape[1][i] = node[v[i]][0] * qrtr * (1. + ip.
y * node[v[i]][1]);
435 rshape[2][i] = node[v[i]][1] * qrtr * (1. + ip.
x * node[v[i]][0]);
444 double lam0 = 1.0 - ip.
x - ip.
y - ip.
z;
478 const double oito = 1.0 / 8.0;
479 static const double node[8][3] =
493 static int v[8] = {4, 7, 6, 5, 0, 1, 2, 3};
495 for (
int i = 0; i < 8; i++) {
497 rshape[0][i] = oito * (1. + ip.
x * node[v[i]][0]) * (1. + ip.
y * node[v[i]][1]) * (1. + ip.
z * node[v[i]][2]);
499 rshape[1][i] = node[v[i]][0] * oito * (1. + ip.
y * node[v[i]][1]) * (1. + ip.
z * node[v[i]][2]);
501 rshape[2][i] = node[v[i]][1] * oito * (1. + ip.
x * node[v[i]][0]) * (1. + ip.
z * node[v[i]][2]);
503 rshape[3][i] = node[v[i]][2] * oito * (1. + ip.
x * node[v[i]][0]) * (1. + ip.
y * node[v[i]][1]);
511 rshape[0][0] = (1.0 - ip.
x - ip.
y) * ip.
z;
512 rshape[0][1] = ip.
y * ip.
z;
513 rshape[0][2] = ip.
x * ip.
z;
514 rshape[0][3] = (1.0 - ip.
x - ip.
y) * (1. - ip.
z);
515 rshape[0][4] = ip.
x * (1. - ip.
z);
516 rshape[0][5] = ip.
y * (1. - ip.
z);
519 rshape[1][0] = -ip.
z;
522 rshape[1][3] = ip.
z - 1.0;
523 rshape[1][4] = 1. - ip.
z;
527 rshape[2][0] = -ip.
z;
530 rshape[2][3] = ip.
z - 1.0;
532 rshape[2][5] = 1. - ip.
z;
535 rshape[3][0] = 1.0 - ip.
x - ip.
y;
538 rshape[3][3] = ip.
x + ip.
y - 1.0;
539 rshape[3][4] = -ip.
x;
540 rshape[3][5] = -ip.
y;
546 const double qrtr = 0.25;
548 const double lterm0 = ip.
x * ip.
y * ip.
z / (1.0 - ip.
z);
549 rshape[0][0] = qrtr * ( (1.0 + ip.
x) * (1.0 + ip.
y) - ip.
z + lterm0 );
550 rshape[0][1] = qrtr * ( (1.0 - ip.
x) * (1.0 + ip.
y) - ip.
z - lterm0 );
551 rshape[0][2] = qrtr * ( (1.0 - ip.
x) * (1.0 - ip.
y) - ip.
z + lterm0 );
552 rshape[0][3] = qrtr * ( (1.0 + ip.
x) * (1.0 - ip.
y) - ip.
z - lterm0 );
556 const double lterm1 = (ip.
y * ip.
z) / (1.0 - ip.
z);
557 rshape[1][0] = qrtr * ( (1.0 + ip.
y) + lterm1 );
558 rshape[1][1] = qrtr * ( -(1.0 + ip.
y) - lterm1 );
559 rshape[1][2] = qrtr * ( -(1.0 - ip.
y) + lterm1 );
560 rshape[1][3] = qrtr * ( (1.0 - ip.
y) - lterm1 );
564 const double lterm2 = (ip.
x * ip.
z) / (1.0 - ip.
z);
565 rshape[2][0] = qrtr * ( (1.0 + ip.
x) + lterm2 );
566 rshape[2][1] = qrtr * ( (1.0 - ip.
x) - lterm2 );
567 rshape[2][2] = qrtr * ( -(1.0 - ip.
x) + lterm2 );
568 rshape[2][3] = qrtr * ( -(1.0 + ip.
x) - lterm2 );
572 const double lterm3 = ((ip.
x * ip.
y * ip.
z) / (1.0 - ip.
z) * (1.0 - ip.
z)) + (ip.
x * ip.
y / (1.0 - ip.
z));
573 rshape[3][0] = qrtr * ( -1.0 + lterm3 );
574 rshape[3][1] = qrtr * ( -1.0 - lterm3 );
575 rshape[3][2] = qrtr * ( -1.0 + lterm3 );
576 rshape[3][3] = qrtr * ( -1.0 - lterm3 );
582 fprintf(stderr,
"%s: Unimplemented element type! Aborting!\n", __func__);
601 memset (J, 0, 9 *
sizeof(
double) );
604 for (
int i = 0; i < npts; i++)
606 J[0] += rshape[1][i] * pts[i].
x;
607 J[1] += rshape[1][i] * pts[i].
y;
608 J[2] += rshape[1][i] * pts[i].
z;
609 J[3] += rshape[2][i] * pts[i].
x;
610 J[4] += rshape[2][i] * pts[i].
y;
611 J[5] += rshape[2][i] * pts[i].
z;
612 J[6] += rshape[3][i] * pts[i].
x;
613 J[7] += rshape[3][i] * pts[i].
y;
614 J[8] += rshape[3][i] * pts[i].
z;
631 double J2[4] = {J[0], J[1], J[3], J[4]};
636 J[0] = J2[0]; J[1] = J2[1]; J[2] = 0.0;
637 J[3] = J2[2]; J[4] = J2[3]; J[5] = 0.0;
638 J[6] = 0.0; J[7] = 0.0; J[8] = 0.0;
664 for (
int in = 0; in < ndof; in++)
666 shape[1][in] = iJ[0] * rshape[1][in] +
667 iJ[1] * rshape[2][in] +
668 iJ[2] * rshape[3][in];
670 shape[2][in] = iJ[3] * rshape[1][in] +
671 iJ[4] * rshape[2][in] +
672 iJ[5] * rshape[3][in];
674 shape[3][in] = iJ[6] * rshape[1][in] +
675 iJ[7] * rshape[2][in] +
676 iJ[8] * rshape[3][in];
687 template<
class T,
class S>
694 const T* _offset_con;
705 _mesh(mesh), _glob_numbr(_mesh.get_numbering(nbr))
708 MPI_Comm_rank(_mesh.
comm, &_rank);
720 T offset = _mesh.
dsp[_eidx];
721 _esize = _mesh.
dsp[_eidx+1] - offset;
722 _offset_con = _mesh.
con.data() + offset;
758 return _mesh.
type[_eidx];
768 return _mesh.
tag[_eidx];
778 inline const T &
node(
short nidx)
const
780 return _offset_con[nidx];
792 return _glob_numbr[_offset_con[nidx]];
805 return n[_offset_con[nidx]];
826 T idx = _offset_con[nidx];
827 return {_mesh.
xyz[idx*3+0], _mesh.
xyz[idx*3+1], _mesh.
xyz[idx*3+2]};
838 return {_mesh.
fib[_eidx*3+0], _mesh.
fib[_eidx*3+1], _mesh.
fib[_eidx*3+2]};
850 return {_mesh.
she[_eidx*3+0], _mesh.
she[_eidx*3+1], _mesh.
she[_eidx*3+2]};
882 return _mesh.
epl.algebraic_layout()[_rank] + _eidx;
909 switch(_mesh.
type[_eidx])
931 template<
class T,
class S>
938 virtual void dpn(T & row_dpn, T & col_dpn) = 0;
946 template<
class T,
class S>
952 for(T i=0; i<nrows; i++) buff[i] = 0.0;
972 template<
typename T,
typename V>
inline
979 for(T i=0; i<esize; i++)
980 for(
short j=0; j<dpn; j++)
981 cidx[i*dpn + j] = nbr[nidx[i]]*dpn + j;
994 template<
class T,
class S>
1000 MPI_Comm_rank(domain.
comm, &rank);
1004 integrator.
dpn(row_dpn, col_dpn);
1017 for(
size_t eidx=0; eidx < domain.
l_numelem; eidx++)
1025 row_idx.resize(nnodes*row_dpn);
1026 col_idx.
resize(nnodes*col_dpn);
1027 canonic_indices<mesh_int_t,SF_int>(view.
nodes(), petsc_nbr.
data(), nnodes, row_dpn, row_idx.data());
1028 canonic_indices<mesh_int_t,SF_int>(view.
nodes(), petsc_nbr.
data(), nnodes, col_dpn, col_idx.
data());
1031 integrator(view, ebuff);
1034 const bool add =
true;
1041 template<
class T,
class S>
1047 MPI_Comm_rank(domain.
comm, &rank);
1051 integrator.
dpn(row_dpn, col_dpn);
1053 assert(row_dpn == 1 && row_dpn == mat.
dpn_row());
1064 for(
size_t eidx=0; eidx < domain.
l_numelem; eidx++)
1071 row_idx.
resize(nnodes*row_dpn);
1072 canonic_indices<mesh_int_t,T>(view.
nodes(), petsc_nbr.
data(), nnodes, row_dpn, row_idx.
data());
1075 integrator(view, ebuff);
1078 for(
int i=0; i<nnodes; i++) {
1081 for(
int j=0; j<nnodes; j++)
1082 rowsum += ebuff[i][j];
1085 mat.
set_value(row_idx[i], row_idx[i], rowsum,
true);
1103 template<
class T,
class S>
1109 MPI_Comm_rank(vec.
mesh->
comm, &rank);
1113 integrator.
dpn(dpn);
1114 assert(vec.
dpn == dpn);
1125 for(
size_t eidx=0; eidx < domain.
l_numelem; eidx++)
1132 canonic_indices<mesh_int_t,T>(view.
nodes(), petsc_nbr.
data(), nnodes, dpn, idx.
data());
1135 integrator(view, ebuff.
data());
1138 vec.
set(idx, ebuff, ADD_VALUES);
1144 template<
class T,
class S>
inline
1151 assert(vec.
layout == nodaltype);
1154 for(
int j=0; j<dpn; j++) {
1155 int idx = view.
node(i)*dpn+j;
1156 buffer[i*dpn+j] = vec.
get(idx);
1160 template<
class T,
class S>
inline
1167 assert(vec.
layout == nodaltype);
1172 for(
int j=0; j<dpn; j++) {
1173 int idx = view.
node(i)*dpn+j;
1174 pvec[idx] = buffer[i*dpn+j];
1180 template<
class T,
class S>
inline
1189 loc_pts[0] = {0, 0, 0};
1190 loc_pts[1] = {
mag(p1 - p0), 0, 0};
1191 trsf_fibre = {1, 0, 0};
1197 Point f = trsf_fibre;
1199 Point p01 = p1 - p0, p02 = p2 - p0;
1205 loc_pts[0] = {0, 0, 0};
1206 loc_pts[1] = {
mag(p01), 0, 0};
1210 if((fabs(trsf_fibre.
x) + fabs(trsf_fibre.
y)) < 1e-8 and orthogonal) {
1211 fprintf(stderr,
"Fibre direction is orthogonal to triangle. Assigning (1,0,0) fiber direction.\n");
1212 trsf_fibre = {1, 0, 0};
1214 else trsf_fibre =
normalize(trsf_fibre);
1220 Point f = trsf_fibre;
1222 Point p01 = p1 - p0, p02 = p2 - p0, p03 = p3 - p0;
1228 loc_pts[0] = {0, 0, 0};
1229 loc_pts[1] = {
mag(p01), 0, 0};
1235 if((fabs(trsf_fibre.
x) + fabs(trsf_fibre.
y)) < 1e-8 and orthogonal) {
1236 fprintf(stderr,
"Fibre direction is orthogonal to quad. Assigning (1,0,0) fiber direction.\n");
1237 trsf_fibre = {1, 0, 0};
1239 else trsf_fibre =
normalize(trsf_fibre);
1246 loc_pts[i] = view.
coord(i);
opencarp::local_index_t mesh_int_t
#define SF_MAX_ELEM_NODES
max #nodes defining an element
opencarp::real_t SF_real
Global scalar type.
opencarp::global_index_t SF_int
Global algebraic index type.
virtual void finish_assembly()=0
virtual void set_values(const vector< T > &row_idx, const vector< T > &col_idx, const vector< S > &vals, bool add)=0
virtual void set_value(T row_idx, T col_idx, S val, bool add)=0
virtual void get(const vector< T > &idx, S *out)=0
virtual void release_ptr(S *&p)=0
ltype layout
used vector layout (nodal, algebraic, unset)
int dpn
d.o.f. per mesh vertex; data is stored node-major (index = node*dpn + component).
virtual void set(const vector< T > &idx, const vector< S > &vals, const bool additive=false, const bool local=false)=0
virtual void finish_assembly()=0
const meshdata< mesh_int_t, mesh_real_t > * mesh
the connected mesh
Comfort class. Provides getter functions to access the mesh member variables more comfortably.
const T & node(short nidx) const
Access the connectivity information.
Point fiber() const
Get element fiber direction.
void integration_points(const short order, Point *ip, double *w, int &nint) const
short num_dof(short order) const
const T * nodes() const
Access the connectivity information.
bool next()
Select next element if possible.
void set_elem(size_t eidx)
Set the view to a new element.
element_view(const meshdata< T, S > &mesh, const SF_nbr nbr)
Constructor. Initializes to element index 0.
elem_t type() const
Getter function for the element type.
const T & global_node(short nidx) const
Access the connectivity information.
const T & global_node(short nidx, SF_nbr nbr) const
Access the connectivity information.
T tag() const
Getter function for the element tag.
size_t global_element_index(SF_nbr nbr) const
Get currently selected element index.
Point coord(short nidx) const
Access vertex coordinates.
size_t global_element_index() const
Get currently selected element index.
size_t element_index() const
Get currently selected element index.
bool has_sheet() const
Check if a sheet direction is present.
T num_nodes() const
Getter function for the number of nodes.
Point sheet() const
Get element sheet direction.
Abstract matrix integration base class.
virtual void operator()(const element_view< T, S > &elem, dmat< double > &buff)=0
compute the element matrix for a given element.
virtual void dpn(T &row_dpn, T &col_dpn)=0
return (by reference) the row and column dimensions
The mesh storage class. It contains both element and vertex data.
vector< T > dsp
connectivity starting index of each element
vector< S > she
sheet direction
vector< S > fib
fiber direction
size_t l_numelem
local number of elements
vector< elem_t > type
element type
vector< S > xyz
node cooridnates
MPI_Comm comm
the parallel mesh is defined on a MPI world
vector< T > & get_numbering(SF_nbr nbr_type)
Get the vector defining a certain numbering.
vector< T > tag
element tag
non_overlapping_layout< T > epl
element parallel layout
Abstract vector integration base class.
void zero_buff(double *buff, T nrows)
virtual void operator()(const element_view< T, S > &elem, double *buff)=0
compute the element matrix for a given element.
virtual void dpn(T &dpn)=0
return (by reference) the row and column dimensions
A vector storing arbitrary data.
size_t size() const
The current size of the vector.
void resize(size_t n)
Resize a vector.
T * data()
Pointer to the vector's start.
double mag(const Point &vect)
vector magnitude
void invert_3x3(S *ele, S &det)
void shape_deriv(const double *iJ, const dmat< double > &rshape, const int ndof, dmat< double > &shape)
Compute shape derivatives for an element, based on the shape derivatives of the associated reference ...
double inner_prod(const Point &a, const Point &b)
void assemble_vector(abstract_vector< T, S > &vec, meshdata< mesh_int_t, mesh_real_t > &domain, vector_integrator< mesh_int_t, mesh_real_t > &integrator)
Generalized vector assembly.
void extract_element_data(const element_view< mesh_int_t, mesh_real_t > &view, abstract_vector< T, S > &vec, SF_real *buffer)
void canonic_indices(const T *nidx, const T *nbr, const T esize, const short dpn, V *cidx)
Compute canonical indices from nodal indices and dpn.
dmat< S > invert_2x2(const dmat< S > &m)
void assemble_matrix(abstract_matrix< T, S > &mat, meshdata< mesh_int_t, mesh_real_t > &domain, matrix_integrator< mesh_int_t, mesh_real_t > &integrator)
Generalized matrix assembly.
void jacobian_matrix(const dmat< double > &rshape, const int npts, const Point *pts, double *J)
Compute Jacobian matrix from the real element to the reference element.
short num_dof(elem_t type, short order)
Get number of d.o.f. for an element type and an Ansatz function order.
Point normalize(const Point &vect)
void assemble_lumped_matrix(abstract_matrix< T, S > &mat, meshdata< mesh_int_t, mesh_real_t > &domain, matrix_integrator< mesh_int_t, mesh_real_t > &integrator)
void set_element_data(const element_view< mesh_int_t, mesh_real_t > &view, SF_real *buffer, abstract_vector< T, S > &vec)
Point cross(const Point &a, const Point &b)
cross product
void general_integration_points(const elem_t type, const short order, Point *ip, double *w, int &nint)
Compute the integration point locations and weights.
void get_transformed_pts(const element_view< T, S > &view, Point *loc_pts, Point &trsf_fibre, bool orthogonal=true)
void reference_shape(const elem_t type, const Point ip, dmat< double > &rshape)
Compute shape function and its derivatives on a reference element.
SF_nbr
Enumeration encoding the different supported numberings.
@ NBR_PETSC
PETSc numbering of nodes.
void invert_jacobian_matrix(const elem_t type, double *J, double &detJ)