13 #include "../mesh/wedge.hpp"
14 #include "../mesh/pyramid.hpp"
21 "Point",
"Segment",
"Triangle",
"Square",
"Tetrahedron",
"Cube",
"Prism",
26 { 1.0, 1.0, 0.5, 1.0, 1./6, 1.0, 0.5, 1./3 };
168 GeomCenter[
POINT].
x = 0.0;
169 GeomCenter[
POINT].
y = 0.0;
170 GeomCenter[
POINT].
z = 0.0;
188 GeomCenter[
CUBE].
x = 0.5;
189 GeomCenter[
CUBE].
y = 0.5;
190 GeomCenter[
CUBE].
z = 0.5;
192 GeomCenter[
PRISM].
x = 1.0 / 3.0;
193 GeomCenter[
PRISM].
y = 1.0 / 3.0;
194 GeomCenter[
PRISM].
z = 0.5;
200 GeomToPerfGeomJac[
POINT] = NULL;
209 PerfGeomToGeomJac[
POINT] = NULL;
210 PerfGeomToGeomJac[
SEGMENT] = NULL;
212 PerfGeomToGeomJac[
SQUARE] = NULL;
214 PerfGeomToGeomJac[
CUBE] = NULL;
236 GeomToPerfGeomJac[
CUBE]->
Diag(1.0, 3);
257 for (
int i = 0; i <
NumGeom; i++)
259 delete PerfGeomToGeomJac[i];
260 delete GeomToPerfGeomJac[i];
293 ip.
x = double(rand()) / RAND_MAX;
296 ip.
x = double(rand()) / RAND_MAX;
297 ip.
y = double(rand()) / RAND_MAX;
298 if (ip.
x + ip.
y > 1.0)
305 ip.
x = double(rand()) / RAND_MAX;
306 ip.
y = double(rand()) / RAND_MAX;
309 ip.
x = double(rand()) / RAND_MAX;
310 ip.
y = double(rand()) / RAND_MAX;
311 ip.
z = double(rand()) / RAND_MAX;
314 if (ip.
x + ip.
y > 1.0)
321 if (ip.
x + ip.
z > 1.0)
324 ip.
x = ip.
x + ip.
z - 1.0;
329 else if (ip.
x + ip.
y + ip.
z > 1.0)
333 ip.
x = 1.0 - x - ip.
z;
334 ip.
y = 1.0 - x - ip.
y;
340 ip.
x = double(rand()) / RAND_MAX;
341 ip.
y = double(rand()) / RAND_MAX;
342 ip.
z = double(rand()) / RAND_MAX;
345 ip.
x = double(rand()) / RAND_MAX;
346 ip.
y = double(rand()) / RAND_MAX;
347 ip.
z = double(rand()) / RAND_MAX;
348 if (ip.
x + ip.
y > 1.0)
355 ip.
x = double(rand()) / RAND_MAX;
356 ip.
y = double(rand()) / RAND_MAX;
357 ip.
z = double(rand()) / RAND_MAX;
358 if (ip.
x + ip.
z > 1.0 && ip.
y < ip.
x)
365 else if (ip.
y + ip.
z > 1.0)
374 MFEM_ABORT(
"Unknown type of reference element!");
383 inline bool NearlyEqual(
double x,
double y,
double eps)
385 return std::abs(x-y) <= eps;
390 inline bool FuzzyGT(
double x,
double y,
double eps)
392 return (x > y + eps);
397 inline bool FuzzyLT(
double x,
double y,
double eps)
399 return (x < y - eps);
410 if (ip.
x != 0.0) {
return false; }
413 if (ip.
x < 0.0 || ip.
x > 1.0) {
return false; }
416 if (ip.
x < 0.0 || ip.
y < 0.0 || ip.
x+ip.
y > 1.0) {
return false; }
419 if (ip.
x < 0.0 || ip.
x > 1.0 || ip.
y < 0.0 || ip.
y > 1.0)
423 if (ip.
x < 0.0 || ip.
y < 0.0 || ip.
z < 0.0 ||
424 ip.
x+ip.
y+ip.
z > 1.0) {
return false; }
427 if (ip.
x < 0.0 || ip.
x > 1.0 || ip.
y < 0.0 || ip.
y > 1.0 ||
428 ip.
z < 0.0 || ip.
z > 1.0) {
return false; }
431 if (ip.
x < 0.0 || ip.
y < 0.0 || ip.
x+ip.
y > 1.0 ||
432 ip.
z < 0.0 || ip.
z > 1.0) {
return false; }
435 if (ip.
x < 0.0 || ip.
y < 0.0 || ip.
x+ip.
z > 1.0 || ip.
y+ip.
z > 1.0 ||
436 ip.
z < 0.0 || ip.
z > 1.0) {
return false; }
439 MFEM_ABORT(
"Unknown type of reference element!");
449 if (! internal::NearlyEqual(ip.
x, 0.0, eps))
455 if ( internal::FuzzyLT(ip.
x, 0.0, eps)
456 || internal::FuzzyGT(ip.
x, 1.0, eps) )
462 if ( internal::FuzzyLT(ip.
x, 0.0, eps)
463 || internal::FuzzyLT(ip.
y, 0.0, eps)
464 || internal::FuzzyGT(ip.
x+ip.
y, 1.0, eps) )
470 if ( internal::FuzzyLT(ip.
x, 0.0, eps)
471 || internal::FuzzyGT(ip.
x, 1.0, eps)
472 || internal::FuzzyLT(ip.
y, 0.0, eps)
473 || internal::FuzzyGT(ip.
y, 1.0, eps) )
479 if ( internal::FuzzyLT(ip.
x, 0.0, eps)
480 || internal::FuzzyLT(ip.
y, 0.0, eps)
481 || internal::FuzzyLT(ip.
z, 0.0, eps)
482 || internal::FuzzyGT(ip.
x+ip.
y+ip.
z, 1.0, eps) )
488 if ( internal::FuzzyLT(ip.
x, 0.0, eps)
489 || internal::FuzzyGT(ip.
x, 1.0, eps)
490 || internal::FuzzyLT(ip.
y, 0.0, eps)
491 || internal::FuzzyGT(ip.
y, 1.0, eps)
492 || internal::FuzzyLT(ip.
z, 0.0, eps)
493 || internal::FuzzyGT(ip.
z, 1.0, eps) )
499 if ( internal::FuzzyLT(ip.
x, 0.0, eps)
500 || internal::FuzzyLT(ip.
y, 0.0, eps)
501 || internal::FuzzyGT(ip.
x+ip.
y, 1.0, eps)
502 || internal::FuzzyLT(ip.
z, 0.0, eps)
503 || internal::FuzzyGT(ip.
z, 1.0, eps) )
509 if (internal::FuzzyLT(ip.
x, 0.0, eps)
510 || internal::FuzzyLT(ip.
y, 0.0, eps)
511 || internal::FuzzyGT(ip.
x+ip.
z, 1.0, eps)
512 || internal::FuzzyGT(ip.
y+ip.
z, 1.0, eps)
513 || internal::FuzzyLT(ip.
z, 0.0, eps)
514 || internal::FuzzyGT(ip.
z, 1.0, eps) )
520 MFEM_ABORT(
"Unknown type of reference element!");
529 template <
int N,
int dim>
530 inline bool IntersectSegment(
double lbeg[N],
double lend[N],
535 for (
int i = 0; i < N; i++)
537 lbeg[i] = std::max(lbeg[i], 0.0);
541 t = std::min(t, lbeg[i]/(lbeg[i]-lend[i]));
546 if (
dim >= 1) { end.
x = t*lend[0] + (1.0-
t)*lbeg[0]; }
547 if (
dim >= 2) { end.
y = t*lend[1] + (1.0-
t)*lbeg[1]; }
548 if (
dim >= 3) { end.
z = t*lend[2] + (1.0-
t)*lbeg[2]; }
554 inline bool ProjectTriangle(
double &x,
double &y)
559 if (y < 0.0) { y = 0.0; }
560 else if (y > 1.0) { y = 1.0; }
565 if (x > 1.0) { x = 1.0; }
569 const double l3 = 1.0-x-y;
572 if (y - x > 1.0) { x = 0.0; y = 1.0; }
573 else if (y - x < -1.0) { x = 1.0; y = 0.0; }
574 else { x += l3/2; y += l3/2; }
590 if (end.
x != 0.0) { end.
x = 0.0;
return false; }
595 if (end.
x < 0.0) { end.
x = 0.0;
return false; }
596 if (end.
x > 1.0) { end.
x = 1.0;
return false; }
601 double lend[3] = { end.
x, end.
y, 1.0-end.
x-end.
y };
602 double lbeg[3] = { beg.
x, beg.
y, 1.0-beg.
x-beg.
y };
603 return internal::IntersectSegment<3,2>(lbeg, lend, end);
607 double lend[4] = { end.
x, end.
y, 1.0-end.
x, 1.0-end.
y };
608 double lbeg[4] = { beg.
x, beg.
y, 1.0-beg.
x, 1.0-beg.
y };
609 return internal::IntersectSegment<4,2>(lbeg, lend, end);
613 double lend[4] = { end.
x, end.
y, end.
z, 1.0-end.
x-end.
y-end.
z };
614 double lbeg[4] = { beg.
x, beg.
y, beg.
z, 1.0-beg.
x-beg.
y-beg.
z };
615 return internal::IntersectSegment<4,3>(lbeg, lend, end);
619 double lend[6] = { end.
x, end.
y, end.
z,
620 1.0-end.
x, 1.0-end.
y, 1.0-end.
z
622 double lbeg[6] = { beg.
x, beg.
y, beg.
z,
623 1.0-beg.
x, 1.0-beg.
y, 1.0-beg.
z
625 return internal::IntersectSegment<6,3>(lbeg, lend, end);
629 double lend[5] = { end.
x, end.
y, end.
z, 1.0-end.
x-end.
y, 1.0-end.
z };
630 double lbeg[5] = { beg.
x, beg.
y, beg.
z, 1.0-beg.
x-beg.
y, 1.0-beg.
z };
631 return internal::IntersectSegment<5,3>(lbeg, lend, end);
635 double lend[6] = { end.
x, end.
y, end.
z,
636 1.0-end.
x-end.
z, 1.0-end.
y-end.
z, 1.0-end.
z
638 double lbeg[6] = { beg.
x, beg.
y, beg.
z,
639 1.0-beg.
x-beg.
z, 1.0-beg.
y-beg.
z, 1.0-beg.
z
641 return internal::IntersectSegment<6,3>(lbeg, lend, end);
644 MFEM_ABORT(
"Unknown type of reference element!");
660 if (ip.
x < 0.0) { ip.
x = 0.0;
return false; }
661 else if (ip.
x > 1.0) { ip.
x = 1.0;
return false; }
667 return internal::ProjectTriangle(ip.
x, ip.
y);
673 if (ip.
x < 0.0) { in_x =
false; ip.
x = 0.0; }
674 else if (ip.
x > 1.0) { in_x =
false; ip.
x = 1.0; }
675 else { in_x =
true; }
676 if (ip.
y < 0.0) { in_y =
false; ip.
y = 0.0; }
677 else if (ip.
y > 1.0) { in_y =
false; ip.
y = 1.0; }
678 else { in_y =
true; }
687 internal::ProjectTriangle(ip.
x, ip.
y);
693 internal::ProjectTriangle(ip.
x, ip.
z);
699 internal::ProjectTriangle(ip.
y, ip.
z);
702 const double l4 = 1.0-ip.
x-ip.
y-ip.
z;
705 const double l4_3 = l4/3;
708 internal::ProjectTriangle(ip.
x, ip.
y);
709 ip.
z = 1.0-ip.
x-ip.
y;
717 bool in_x, in_y, in_z;
718 if (ip.
x < 0.0) { in_x =
false; ip.
x = 0.0; }
719 else if (ip.
x > 1.0) { in_x =
false; ip.
x = 1.0; }
720 else { in_x =
true; }
721 if (ip.
y < 0.0) { in_y =
false; ip.
y = 0.0; }
722 else if (ip.
y > 1.0) { in_y =
false; ip.
y = 1.0; }
723 else { in_y =
true; }
724 if (ip.
z < 0.0) { in_z =
false; ip.
z = 0.0; }
725 else if (ip.
z > 1.0) { in_z =
false; ip.
z = 1.0; }
726 else { in_z =
true; }
727 return in_x && in_y && in_z;
733 in_tri = internal::ProjectTriangle(ip.
x, ip.
y);
734 if (ip.
z < 0.0) { in_z =
false; ip.
z = 0.0; }
735 else if (ip.
z > 1.0) { in_z =
false; ip.
z = 1.0; }
736 else { in_z =
true; }
737 return in_tri && in_z;
745 internal::ProjectTriangle(ip.
y, ip.
z);
751 internal::ProjectTriangle(ip.
x, ip.
z);
757 if (ip.
x > 1.0) { ip.
x = 1.0; }
758 if (ip.
y > 1.0) { ip.
y = 1.0; }
764 bool in_tri = internal::ProjectTriangle(ip.
x, ip.
z);
765 if (ip.
y > ip.
z) { in_y =
false; ip.
y = ip.
z; }
766 return in_tri && in_y;
771 bool in_tri = internal::ProjectTriangle(ip.
y, ip.
z);
772 if (ip.
x > ip.
z) { in_x =
false; ip.
x = ip.
z; }
773 return in_tri && in_x;
778 MFEM_ABORT(
"Reference element type is not supported!");
798 pm(0,0) = 0.0; pm(1,0) = 0.0;
799 pm(0,1) = 1.0; pm(1,1) = 0.0;
800 pm(0,2) = 0.5; pm(1,2) = 0.86602540378443864676;
807 pm(0,0) = 0.0; pm(1,0) = 0.0;
808 pm(0,1) = 1.0; pm(1,1) = 0.0;
809 pm(0,2) = 1.0; pm(1,2) = 1.0;
810 pm(0,3) = 0.0; pm(1,3) = 1.0;
817 pm(0,0) = 0.0; pm(1,0) = 0.0; pm(2,0) = 0.0;
818 pm(0,1) = 1.0; pm(1,1) = 0.0; pm(2,1) = 0.0;
819 pm(0,2) = 0.5; pm(1,2) = 0.86602540378443864676; pm(2,2) = 0.0;
820 pm(0,3) = 0.5; pm(1,3) = 0.28867513459481288225;
821 pm(2,3) = 0.81649658092772603273;
828 pm(0,0) = 0.0; pm(1,0) = 0.0; pm(2,0) = 0.0;
829 pm(0,1) = 1.0; pm(1,1) = 0.0; pm(2,1) = 0.0;
830 pm(0,2) = 1.0; pm(1,2) = 1.0; pm(2,2) = 0.0;
831 pm(0,3) = 0.0; pm(1,3) = 1.0; pm(2,3) = 0.0;
832 pm(0,4) = 0.0; pm(1,4) = 0.0; pm(2,4) = 1.0;
833 pm(0,5) = 1.0; pm(1,5) = 0.0; pm(2,5) = 1.0;
834 pm(0,6) = 1.0; pm(1,6) = 1.0; pm(2,6) = 1.0;
835 pm(0,7) = 0.0; pm(1,7) = 1.0; pm(2,7) = 1.0;
842 pm(0,0) = 0.0; pm(1,0) = 0.0; pm(2,0) = 0.0;
843 pm(0,1) = 1.0; pm(1,1) = 0.0; pm(2,1) = 0.0;
844 pm(0,2) = 0.5; pm(1,2) = 0.86602540378443864676; pm(2,2) = 0.0;
845 pm(0,3) = 0.0; pm(1,3) = 0.0; pm(2,3) = 1.0;
846 pm(0,4) = 1.0; pm(1,4) = 0.0; pm(2,4) = 1.0;
847 pm(0,5) = 0.5; pm(1,5) = 0.86602540378443864676; pm(2,5) = 1.0;
854 pm(0,0) = 0.0; pm(1,0) = 0.0; pm(2,0) = 0.0;
855 pm(0,1) = 1.0; pm(1,1) = 0.0; pm(2,1) = 0.0;
856 pm(0,2) = 1.0; pm(1,2) = 1.0; pm(2,2) = 0.0;
857 pm(0,3) = 0.0; pm(1,3) = 1.0; pm(2,3) = 0.0;
858 pm(0,4) = 0.5; pm(1,4) = 0.5; pm(2,4) = 0.7071067811865475;
863 mfem_error (
"Geometry::GetPerfPointMat (...)");
870 if (PerfGeomToGeomJac[GeomType])
872 Mult(J, *PerfGeomToGeomJac[GeomType], PJ);
883 { POINT, SEGMENT, TRIANGLE, TETRAHEDRON, NUM_GEOMETRIES };
911 {0, 1, 2}, {1, 0, 2}, {2, 0, 1},
912 {2, 1, 0}, {1, 2, 0}, {0, 2, 1}
923 {{1, 0}, {3, -4}, {2, 1}, {3, 2}};
929 {0, 1, 2, 3}, {0, 3, 2, 1}, {1, 2, 3, 0}, {1, 0, 3, 2},
930 {2, 3, 0, 1}, {2, 1, 0, 3}, {3, 0, 1, 2}, {3, 2, 1, 0}
937 {{0, 1}, {0, 2}, {0, 3}, {1, 2}, {1, 3}, {2, 3}};
946 {{1, 2, 3}, {0, 3, 2}, {0, 1, 3}, {0, 2, 1}};
952 {1, 0}, {2, 1}, {3, 2},
959 {0, 1, 2, 3}, {0, 1, 3, 2}, {0, 2, 3, 1}, {0, 2, 1, 3},
960 {0, 3, 1, 2}, {0, 3, 2, 1},
961 {1, 2, 0, 3}, {1, 2, 3, 0}, {1, 3, 2, 0}, {1, 3, 0, 2},
962 {1, 0, 3, 2}, {1, 0, 2, 3},
963 {2, 3, 0, 1}, {2, 3, 1, 0}, {2, 0, 1, 3}, {2, 0, 3, 1},
964 {2, 1, 3, 0}, {2, 1, 0, 3},
965 {3, 0, 2, 1}, {3, 0, 1, 2}, {3, 1, 0, 2}, {3, 1, 2, 0},
966 {3, 2, 1, 0}, {3, 2, 0, 1}
972 14, 19, 18, 15, 10, 11,
973 12, 23, 6, 9, 20, 17,
980 {0, 1}, {1, 2}, {3, 2}, {0, 3}, {4, 5}, {5, 6},
981 {7, 6}, {4, 7}, {0, 4}, {1, 5}, {2, 6}, {3, 7}
992 {3, 2, 1, 0}, {0, 1, 5, 4}, {1, 2, 6, 5},
993 {2, 3, 7, 6}, {3, 0, 4, 7}, {4, 5, 6, 7}
1000 {1, 0}, {3, 3}, {4, 8},
1011 {{0, 1}, {1, 2}, {2, 0}, {3, 4}, {4, 5}, {5, 3}, {0, 3}, {1, 4}, {2, 5}};
1020 {{0, 2, 1, -1}, {3, 4, 5, -1}, {0, 1, 4, 3}, {1, 2, 5, 4}, {2, 0, 3, 5}};
1026 {1, 0}, {2, -3}, {3, 6},
1035 {{0, 1}, {1, 2}, {3, 2}, {0, 3}, {0, 4}, {1, 4}, {2, 4}, {3, 4}};
1045 {{3, 2, 1, 0}, {0, 1, 4, -1}, {1, 2, 4, -1}, {2, 3, 4, -1}, {3, 0, 4, -1}};
1051 {1, 0}, {3, 3}, {4, 4},
1067 for (
int j = 0; j < RGeom[i].Size(); j++) {
delete RGeom[i][j]; }
1068 for (
int j = 0; j < IntPts[i].Size(); j++) {
delete IntPts[i][j]; }
1073 int Times,
int ETimes,
1077 for (
int i = 0; i < RGA.
Size(); i++)
1088 IntegrationRule *GeometryRefiner::FindInIntPts(
Geometry::Type Geom,
int NPts)
1090 Array<IntegrationRule *> &IPA = IntPts[Geom];
1091 for (
int i = 0; i < IPA.Size(); i++)
1093 IntegrationRule &ir = *IPA[i];
1094 if (ir.GetNPoints() == NPts) {
return &ir; }
1100 int Times,
int ETimes)
1104 Times = std::max(Times, 1);
1109 if (RG) {
return RG; }
1132 for (i = 0; i <= Times; i++)
1138 for (i = 0; i < Times; i++)
1151 3*Times*(ETimes+1), 3*Times);
1155 for (k = j = 0; j <= Times; j++)
1156 for (i = 0; i <= Times-j; i++, k++)
1159 ip.
x = cp[i]/(cp[i] + cp[j] + cp[Times-i-j]);
1160 ip.
y = cp[j]/(cp[i] + cp[j] + cp[Times-i-j]);
1163 for (l = k = j = 0; j < Times; j++, k++)
1164 for (i = 0; i < Times-j; i++, k++)
1168 G[l++] = k+Times-j+1;
1172 G[l++] = k+Times-j+2;
1173 G[l++] = k+Times-j+1;
1179 for (k = 0; k < Times; k += Times/ETimes)
1181 int < = (k == 0) ? lb : li;
1182 j = k*(Times+1)-((k-1)*k)/2;
1183 for (i = 0; i < Times-k; i++)
1190 for (k = Times; k > 0; k -= Times/ETimes)
1192 int < = (k == Times) ? lb : li;
1194 for (i = 0; i < k; i++)
1196 E[lt++] = j; j += Times-i;
1201 for (k = 0; k < Times; k += Times/ETimes)
1203 int < = (k == 0) ? lb : li;
1205 for (i = 0; i < Times-k; i++)
1207 E[lt++] = j; j += Times-i+1;
1219 4*(ETimes+1)*Times, 4*Times);
1223 for (k = j = 0; j <= Times; j++)
1224 for (i = 0; i <= Times; i++, k++)
1231 for (l = k = j = 0; j < Times; j++, k++)
1232 for (i = 0; i < Times; i++, k++)
1242 for (k = 0; k <= Times; k += Times/ETimes)
1244 int < = (k == 0 || k == Times) ? lb : li;
1245 for (i = 0, j = k*(Times+1); i < Times; i++)
1252 for (k = Times; k >= 0; k -= Times/ETimes)
1254 int < = (k == Times || k == 0) ? lb : li;
1255 for (i = 0, j = k; i < Times; i++)
1257 E[lt++] = j; j += Times+1;
1269 8*Times*Times*Times, 0);
1273 for (l = k = 0; k <= Times; k++)
1274 for (j = 0; j <= Times; j++)
1275 for (i = 0; i <= Times; i++, l++)
1283 for (l = k = 0; k < Times; k++)
1284 for (j = 0; j < Times; j++)
1285 for (i = 0; i < Times; i++)
1287 G[l++] = i+0 + (j+0 + (k+0) * (Times+1)) * (Times+1);
1288 G[l++] = i+1 + (j+0 + (k+0) * (Times+1)) * (Times+1);
1289 G[l++] = i+1 + (j+1 + (k+0) * (Times+1)) * (Times+1);
1290 G[l++] = i+0 + (j+1 + (k+0) * (Times+1)) * (Times+1);
1291 G[l++] = i+0 + (j+0 + (k+1) * (Times+1)) * (Times+1);
1292 G[l++] = i+1 + (j+0 + (k+1) * (Times+1)) * (Times+1);
1293 G[l++] = i+1 + (j+1 + (k+1) * (Times+1)) * (Times+1);
1294 G[l++] = i+0 + (j+1 + (k+1) * (Times+1)) * (Times+1);
1316 const int n = Times;
1328 for (
int kk = 0; kk <= n; kk++)
1329 for (
int jj = 0; jj <= n-kk; jj++)
1330 for (
int ii = 0; ii <= n-jj-kk; ii++)
1333 double w = cp[ii] + cp[jj] + cp[kk] + cp[Times-ii-jj-kk];
1343 l = i + (j + k * (n+1)) * (n+1);
1350 if (m != (n+3)*(n+2)*(n+1)/6)
1352 mfem_error(
"GeometryRefiner::Refine() for TETRAHEDRON #1");
1357 for (k = 0; k < n; k++)
1358 for (j = 0; j <= k; j++)
1359 for (i = 0; i <= j; i++)
1369 G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
1370 G[m++] = vi[i+0 + (j+0 + (k+1) * (n+1)) * (n+1)];
1371 G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
1372 G[m++] = vi[i+0 + (j+1 + (k+1) * (n+1)) * (n+1)];
1376 G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
1377 G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
1378 G[m++] = vi[i+0 + (j+1 + (k+0) * (n+1)) * (n+1)];
1379 G[m++] = vi[i+0 + (j+1 + (k+1) * (n+1)) * (n+1)];
1381 G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
1382 G[m++] = vi[i+0 + (j+1 + (k+0) * (n+1)) * (n+1)];
1383 G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
1384 G[m++] = vi[i+1 + (j+1 + (k+0) * (n+1)) * (n+1)];
1389 G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
1390 G[m++] = vi[i+1 + (j+0 + (k+0) * (n+1)) * (n+1)];
1391 G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
1392 G[m++] = vi[i+1 + (j+0 + (k+1) * (n+1)) * (n+1)];
1396 G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
1397 G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
1398 G[m++] = vi[i+1 + (j+0 + (k+0) * (n+1)) * (n+1)];
1399 G[m++] = vi[i+1 + (j+1 + (k+0) * (n+1)) * (n+1)];
1402 G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
1403 G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
1404 G[m++] = vi[i+0 + (j+0 + (k+1) * (n+1)) * (n+1)];
1405 G[m++] = vi[i+1 + (j+0 + (k+1) * (n+1)) * (n+1)];
1410 mfem_error(
"GeometryRefiner::Refine() for TETRAHEDRON #2");
1412 for (i = 0; i < m; i++)
1415 mfem_error(
"GeometryRefiner::Refine() for TETRAHEDRON #3");
1424 const int n = Times;
1426 5*n*(2*n-1)*(2*n+1)/3, 0);
1432 for (k = 0; k <= n; k++)
1434 const double *cpij =
1436 for (j = 0; j <= n - k; j++)
1437 for (i = 0; i <= n - k; i++)
1442 ip.
x = (n > k) ? (
double(i) / (n - k)) : 0.0;
1443 ip.
y = (n > k) ? (
double(j) / (n - k)) : 0.0;
1444 ip.
z = double(k) / n;
1448 ip.
x = cpij[i] * (1.0 - cp[k]);
1449 ip.
y = cpij[j] * (1.0 - cp[k]);
1455 if (m != (n+1)*(n+2)*(2*n+3)/6)
1457 mfem_error(
"GeometryRefiner::Refine() for PYRAMID #1");
1462 for (k = 0; k < n; k++)
1464 int lk = k * (k * (2 * k - 6 * n - 9) + 6 * n * (n + 3) + 13) / 6;
1465 int lkp1 = (k + 1) *
1466 (k * (2 * k - 6 * n -5) + 6 * n * (n + 2) + 6) / 6;
1467 for (j = 0; j < n - k; j++)
1469 for (i = 0; i < n - k; i++)
1471 G[m++] = lk + j * (n - k + 1) + i;
1472 G[m++] = lk + j * (n - k + 1) + i + 1;
1473 G[m++] = lk + (j + 1) * (n - k + 1) + i + 1;
1474 G[m++] = lk + (j + 1) * (n - k + 1) + i;
1475 G[m++] = lkp1 + j * (n - k) + i;
1478 for (j = 0; j < n - k - 1; j++)
1480 for (i = 0; i < n - k - 1; i++)
1482 G[m++] = lkp1 + j * (n - k) + i;
1483 G[m++] = lkp1 + (j + 1) * (n - k) + i;
1484 G[m++] = lkp1 + (j + 1) * (n - k) + i + 1;
1485 G[m++] = lkp1 + j * (n - k) + i + 1;
1486 G[m++] = lk + (j + 1) * (n - k + 1) + i + 1;
1489 for (j = 0; j < n - k; j++)
1491 for (i = 0; i < n - k - 1; i++)
1493 G[m++] = lk + j * (n - k + 1) + i + 1;
1494 G[m++] = lk + (j + 1) * (n - k + 1) + i + 1;
1495 G[m++] = lkp1 + j * (n - k) + i;
1496 G[m++] = lkp1 + j * (n - k) + i + 1;
1500 for (j = 0; j < n - k - 1; j++)
1502 for (i = 0; i < n - k; i++)
1504 G[m++] = lk + (j + 1) * (n - k + 1) + i;
1505 G[m++] = lk + (j + 1) * (n - k + 1) + i + 1;
1506 G[m++] = lkp1 + (j + 1) * (n - k) + i;
1507 G[m++] = lkp1 + j * (n - k) + i;
1512 if (m != 5*n*(2*n-1)*(2*n+1)/3)
1514 mfem_error(
"GeometryRefiner::Refine() for PYRAMID #2");
1522 const int n = Times;
1529 for (l = k = 0; k <= n; k++)
1530 for (j = 0; j <= n; j++)
1531 for (i = 0; i <= n-j; i++, l++)
1534 ip.
x = cp[i]/(cp[i] + cp[j] + cp[n-i-j]);
1535 ip.
y = cp[j]/(cp[i] + cp[j] + cp[n-i-j]);
1539 if (m != (n+1)*(n+1)*(n+2)/2)
1541 mfem_error(
"GeometryRefiner::Refine() for PRISM #1");
1546 for (m = k = 0; k < n; k++)
1547 for (l = j = 0; j < n; j++, l++)
1548 for (i = 0; i < n-j; i++, l++)
1550 G[m++] = l + (k+0) * (n+1) * (n+2) / 2;
1551 G[m++] = l + 1 + (k+0) * (n+1) * (n+2) / 2;
1552 G[m++] = l - j + (2 + (k+0) * (n+2)) * (n+1) / 2;
1553 G[m++] = l + (k+1) * (n+1) * (n+2) / 2;
1554 G[m++] = l + 1 + (k+1) * (n+1) * (Times+2) / 2;
1555 G[m++] = l - j + (2 + (k+1) * (n+2)) * (n+1) / 2;
1558 G[m++] = l + 1 + (k+0) * (n+1) * (n+2)/2;
1559 G[m++] = l - j + (2 + (k+0) * (n+1)) * (n+2) / 2;
1560 G[m++] = l - j + (2 + (k+0) * (n+2)) * (n+1) / 2;
1561 G[m++] = l + 1 + (k+1) * (n+1) * (n+2) / 2;
1562 G[m++] = l - j + (2 + (k+1) * (n+1)) * (n+2) / 2;
1563 G[m++] = l - j + (2 + (k+1) * (n+2)) * (n+1) / 2;
1568 mfem_error(
"GeometryRefiner::Refine() for PRISM #2");
1570 for (i = 0; i < m; i++)
1573 mfem_error(
"GeometryRefiner::Refine() for PRISM #3");
1599 ir = FindInIntPts(Geom, Times-1);
1600 if (ir) {
return ir; }
1603 for (
int i = 1; i < Times; i++)
1606 ip.
x = double(i) / Times;
1618 ir = FindInIntPts(Geom, ((Times-1)*(Times-2))/2);
1619 if (ir) {
return ir; }
1622 for (
int k = 0, j = 1; j < Times-1; j++)
1623 for (
int i = 1; i < Times-j; i++, k++)
1626 ip.
x = double(i) / Times;
1627 ip.
y = double(j) / Times;
1639 ir = FindInIntPts(Geom, (Times-1)*(Times-1));
1640 if (ir) {
return ir; }
1643 for (
int k = 0, j = 1; j < Times; j++)
1644 for (
int i = 1; i < Times; i++, k++)
1647 ip.
x = double(i) / Times;
1648 ip.
y = double(j) / Times;
1655 mfem_error(
"GeometryRefiner::RefineInterior(...)");
1658 MFEM_ASSERT(ir != NULL,
"Failed to construct the refined IntegrationRule.");
1659 IntPts[Geom].Append(ir);
1679 for (
int n = 0, np = 0; (n < 15) && (np < Npts) ; n++)
1682 if (np == Npts) {
return n; }
1688 for (
int n = 0, np = 0; (n < 15) && (np < Npts) ; n++)
1691 if (np == Npts) {
return n; }
1697 for (
int n = 0, np = 0; (n < 15) && (np < Npts) ; n++)
1699 np = (n+1)*(n+1)*(n+1);
1700 if (np == Npts) {
return n; }
1706 for (
int n = 0, np = 0; (n < 15) && (np < Npts) ; n++)
1708 np = (n+3)*(n+2)*(n+1)/6;
1709 if (np == Npts) {
return n; }
1715 for (
int n = 0, np = 0; (n < 15) && (np < Npts) ; n++)
1717 np = (n+1)*(n+1)*(n+2)/2;
1718 if (np == Npts) {
return n; }
1747 for (
int n = 0; (n < 15) && (n*n < Nels+1) ; n++)
1749 if (n*n == Nels) {
return n-1; }
1757 for (
int n = 0; (n < 15) && (n*n*n < Nels+1) ; n++)
1759 if (n*n*n == Nels) {
return n-1; }
int Size() const
Return the logical size of the array.
static const int InvOrient[NumOrient]
Class for an integration rule - an Array of IntegrationPoint.
static const int I[NumVert]
static const int J[NumEdges][2]
static int GetNodalBasis(int qpt_type)
Return the nodal BasisType corresponding to the Quadrature1D type.
class LinearPyramidFiniteElement PyramidFE
void JacToPerfJac(int GeomType, const DenseMatrix &J, DenseMatrix &PJ) const
static void GetRandomPoint(int GeomType, IntegrationPoint &ip)
Get a random point in the reference element specified by GeomType.
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
static const int J[NumEdges][2]
static const int FaceVert[NumFaces][MaxFaceVert]
static const int FaceVert[NumFaces][MaxFaceVert]
static const int Edges[NumEdges][2]
Data type dense matrix using column-major storage.
static const double Volume[NumGeom]
static const int I[NumVert]
static const int NumEdges[NumGeom]
const IntegrationRule * GetVertices(int GeomType)
Return an IntegrationRule consisting of all vertices of the given Geometry::Type, GeomType...
const IntegrationRule * RefineInterior(Geometry::Type Geom, int Times)
const double * GetPoints(const int p, const int btype)
Get the coordinates of the points of the given BasisType, btype.
static const int NumFaces[NumGeom]
static const int InvOrient[NumOrient]
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
static const int Edges[NumEdges][2]
static const int Dimension[NumGeom]
static const int FaceTypes[NumFaces]
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
static const int J[NumEdges][2]
static const int FaceTypes[NumFaces]
static const int NumVerts[NumGeom]
static const int FaceTypes[NumFaces]
static const int Edges[NumEdges][2]
GeometryRefiner GlobGeometryRefiner
static const int NumBdrArray[NumGeom]
RefinedGeometry * Refine(Geometry::Type Geom, int Times, int ETimes=1)
static const int InvOrient[NumOrient]
static const int Orient[NumOrient][NumVert]
virtual int GetRefinementLevelFromElems(Geometry::Type geom, int Npts)
Get the Refinement level based on number of elements.
static const int Edges[NumEdges][2]
static const char * Name[NumGeom]
static const int J[NumEdges][2]
static const int InvOrient[NumOrient]
static const int I[NumVert]
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
static const int InvOrient[NumOrient]
static const int Edges[NumEdges][2]
static bool ProjectPoint(int GeomType, const IntegrationPoint &beg, IntegrationPoint &end)
Project a point end, onto the given Geometry::Type, GeomType.
void GetPerfPointMat(int GeomType, DenseMatrix &pm)
class Linear3DFiniteElement TetrahedronFE
Linear2DFiniteElement TriangleFE
static const int I[NumVert]
static const int FaceVert[NumFaces][MaxFaceVert]
static const int J[NumEdges][2]
static const int I[NumVert]
static const int FaceVert[NumFaces][NumVert]
static const int Edges[NumEdges][2]
Class for integration point with weight.
virtual int GetRefinementLevelFromPoints(Geometry::Type Geom, int Npts)
Get the Refinement level based on number of points.
static const int DimStart[MaxDim+2]
void Diag(double c, int n)
Creates n x n diagonal matrix with diagonal elements c.
static const int FaceTypes[NumFaces]
class LinearWedgeFiniteElement WedgeFE
static const int FaceVert[NumFaces][NumVert]
static const int Orient[NumOrient][NumVert]
static const int Edges[NumEdges][2]
static const int Orient[NumOrient][NumVert]
static const int Orient[NumOrient][NumVert]
static bool CheckPoint(int GeomType, const IntegrationPoint &ip)
Check if the given point is inside the given reference element.
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
static const int I[NumVert]
static const int Orient[NumOrient][NumVert]
static const int J[NumEdges][2]
static const int FaceVert[NumFaces][MaxFaceVert]