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);
255template <Geometry::Type GEOM>
259 MFEM_ASSERT(0 <= orientation && orientation < geom_t::NumOrient,
260 "Invalid orientation");
261 return geom_t::InvOrient[orientation];
279 MFEM_ABORT(
"Geometry type does not have inverse orientations");
285 for (
int i = 0; i <
NumGeom; i++)
287 delete PerfGeomToGeomJac[i];
288 delete GeomToPerfGeomJac[i];
327 if (ip.
x + ip.
y > 1.0)
343 if (ip.
x + ip.
y > 1.0)
350 if (ip.
x + ip.
z > 1.0)
353 ip.
x = ip.
x + ip.
z - 1.0;
358 else if (ip.
x + ip.
y + ip.
z > 1.0)
362 ip.
x = 1.0 - x - ip.
z;
363 ip.
y = 1.0 - x - ip.
y;
377 if (ip.
x + ip.
y > 1.0)
387 if (ip.
x + ip.
z > 1.0 && ip.
y < ip.
x)
394 else if (ip.
y + ip.
z > 1.0)
404 MFEM_ABORT(
"Unknown type of reference element!");
415 return std::abs(x-y) <= eps;
422 return (x > y + eps);
429 return (x < y - eps);
440 if (ip.
x != 0.0) {
return false; }
443 if (ip.
x < 0.0 || ip.
x > 1.0) {
return false; }
446 if (ip.
x < 0.0 || ip.
y < 0.0 || ip.
x+ip.
y > 1.0) {
return false; }
449 if (ip.
x < 0.0 || ip.
x > 1.0 || ip.
y < 0.0 || ip.
y > 1.0)
453 if (ip.
x < 0.0 || ip.
y < 0.0 || ip.
z < 0.0 ||
454 ip.
x+ip.
y+ip.
z > 1.0) {
return false; }
457 if (ip.
x < 0.0 || ip.
x > 1.0 || ip.
y < 0.0 || ip.
y > 1.0 ||
458 ip.
z < 0.0 || ip.
z > 1.0) {
return false; }
461 if (ip.
x < 0.0 || ip.
y < 0.0 || ip.
x+ip.
y > 1.0 ||
462 ip.
z < 0.0 || ip.
z > 1.0) {
return false; }
465 if (ip.
x < 0.0 || ip.
y < 0.0 || ip.
x+ip.
z > 1.0 || ip.
y+ip.
z > 1.0 ||
466 ip.
z < 0.0 || ip.
z > 1.0) {
return false; }
470 MFEM_ABORT(
"Unknown type of reference element!");
481 if (! internal::NearlyEqual(ip.
x, 0.0, eps))
487 if ( internal::FuzzyLT(ip.
x, 0.0, eps)
488 || internal::FuzzyGT(ip.
x, 1.0, eps) )
494 if ( internal::FuzzyLT(ip.
x, 0.0, eps)
495 || internal::FuzzyLT(ip.
y, 0.0, eps)
496 || internal::FuzzyGT(ip.
x+ip.
y, 1.0, eps) )
502 if ( internal::FuzzyLT(ip.
x, 0.0, eps)
503 || internal::FuzzyGT(ip.
x, 1.0, eps)
504 || internal::FuzzyLT(ip.
y, 0.0, eps)
505 || internal::FuzzyGT(ip.
y, 1.0, eps) )
511 if ( internal::FuzzyLT(ip.
x, 0.0, eps)
512 || internal::FuzzyLT(ip.
y, 0.0, eps)
513 || internal::FuzzyLT(ip.
z, 0.0, eps)
514 || internal::FuzzyGT(ip.
x+ip.
y+ip.
z, 1.0, eps) )
520 if ( internal::FuzzyLT(ip.
x, 0.0, eps)
521 || internal::FuzzyGT(ip.
x, 1.0, eps)
522 || internal::FuzzyLT(ip.
y, 0.0, eps)
523 || internal::FuzzyGT(ip.
y, 1.0, eps)
524 || internal::FuzzyLT(ip.
z, 0.0, eps)
525 || internal::FuzzyGT(ip.
z, 1.0, eps) )
531 if ( internal::FuzzyLT(ip.
x, 0.0, eps)
532 || internal::FuzzyLT(ip.
y, 0.0, eps)
533 || internal::FuzzyGT(ip.
x+ip.
y, 1.0, eps)
534 || internal::FuzzyLT(ip.
z, 0.0, eps)
535 || internal::FuzzyGT(ip.
z, 1.0, eps) )
541 if (internal::FuzzyLT(ip.
x, 0.0, eps)
542 || internal::FuzzyLT(ip.
y, 0.0, eps)
543 || internal::FuzzyGT(ip.
x+ip.
z, 1.0, eps)
544 || internal::FuzzyGT(ip.
y+ip.
z, 1.0, eps)
545 || internal::FuzzyLT(ip.
z, 0.0, eps)
546 || internal::FuzzyGT(ip.
z, 1.0, eps) )
553 MFEM_ABORT(
"Unknown type of reference element!");
562template <
int N,
int dim>
563inline bool IntersectSegment(
real_t lbeg[N],
real_t lend[N],
568 for (
int i = 0; i < N; i++)
570 lbeg[i] = std::max(lbeg[i], (
real_t) 0.0);
574 t = std::min(
t, lbeg[i]/(lbeg[i]-lend[i]));
579 if (
dim >= 1) { end.
x =
t*lend[0] + (1.0-
t)*lbeg[0]; }
580 if (
dim >= 2) { end.
y =
t*lend[1] + (1.0-
t)*lbeg[1]; }
581 if (
dim >= 3) { end.
z =
t*lend[2] + (1.0-
t)*lbeg[2]; }
592 if (y < 0.0) { y = 0.0; }
593 else if (y > 1.0) { y = 1.0; }
598 if (x > 1.0) { x = 1.0; }
602 const real_t l3 = 1.0-x-y;
605 if (y - x > 1.0) { x = 0.0; y = 1.0; }
606 else if (y - x < -1.0) { x = 1.0; y = 0.0; }
607 else { x += l3/2; y += l3/2; }
619 constexpr real_t fone = 1.0;
625 if (end.
x != 0.0) { end.
x = 0.0;
return false; }
630 if (end.
x < 0.0) { end.
x = 0.0;
return false; }
631 if (end.
x > 1.0) { end.
x = 1.0;
return false; }
636 real_t lend[3] = { end.
x, end.
y, fone-end.
x-end.
y };
637 real_t lbeg[3] = { beg.
x, beg.
y, fone-beg.
x-beg.
y };
638 return internal::IntersectSegment<3,2>(lbeg, lend, end);
642 real_t lend[4] = { end.
x, end.
y, fone-end.
x, fone-end.
y };
643 real_t lbeg[4] = { beg.
x, beg.
y, fone-beg.
x, fone-beg.
y };
644 return internal::IntersectSegment<4,2>(lbeg, lend, end);
648 real_t lend[4] = { end.
x, end.
y, end.
z, fone-end.
x-end.
y-end.
z };
649 real_t lbeg[4] = { beg.
x, beg.
y, beg.
z, fone-beg.
x-beg.
y-beg.
z };
650 return internal::IntersectSegment<4,3>(lbeg, lend, end);
655 fone-end.
x, fone-end.
y, fone-end.
z
658 fone-beg.
x, fone-beg.
y, fone-beg.
z
660 return internal::IntersectSegment<6,3>(lbeg, lend, end);
664 real_t lend[5] = { end.
x, end.
y, end.
z, fone-end.
x-end.
y, fone-end.
z };
665 real_t lbeg[5] = { beg.
x, beg.
y, beg.
z, fone-beg.
x-beg.
y, fone-beg.
z };
666 return internal::IntersectSegment<5,3>(lbeg, lend, end);
671 fone-end.
x-end.
z, fone-end.
y-end.
z, fone-end.
z
674 fone-beg.
x-beg.
z, fone-beg.
y-beg.
z, fone-beg.
z
676 return internal::IntersectSegment<6,3>(lbeg, lend, end);
680 MFEM_ABORT(
"Unknown type of reference element!");
696 if (ip.
x < 0.0) { ip.
x = 0.0;
return false; }
697 else if (ip.
x > 1.0) { ip.
x = 1.0;
return false; }
703 return internal::ProjectTriangle(ip.
x, ip.
y);
709 if (ip.
x < 0.0) { in_x =
false; ip.
x = 0.0; }
710 else if (ip.
x > 1.0) { in_x =
false; ip.
x = 1.0; }
711 else { in_x =
true; }
712 if (ip.
y < 0.0) { in_y =
false; ip.
y = 0.0; }
713 else if (ip.
y > 1.0) { in_y =
false; ip.
y = 1.0; }
714 else { in_y =
true; }
723 internal::ProjectTriangle(ip.
x, ip.
y);
729 internal::ProjectTriangle(ip.
x, ip.
z);
735 internal::ProjectTriangle(ip.
y, ip.
z);
744 internal::ProjectTriangle(ip.
x, ip.
y);
745 ip.
z = 1.0-ip.
x-ip.
y;
753 bool in_x, in_y, in_z;
754 if (ip.
x < 0.0) { in_x =
false; ip.
x = 0.0; }
755 else if (ip.
x > 1.0) { in_x =
false; ip.
x = 1.0; }
756 else { in_x =
true; }
757 if (ip.
y < 0.0) { in_y =
false; ip.
y = 0.0; }
758 else if (ip.
y > 1.0) { in_y =
false; ip.
y = 1.0; }
759 else { in_y =
true; }
760 if (ip.
z < 0.0) { in_z =
false; ip.
z = 0.0; }
761 else if (ip.
z > 1.0) { in_z =
false; ip.
z = 1.0; }
762 else { in_z =
true; }
763 return in_x && in_y && in_z;
769 in_tri = internal::ProjectTriangle(ip.
x, ip.
y);
770 if (ip.
z < 0.0) { in_z =
false; ip.
z = 0.0; }
771 else if (ip.
z > 1.0) { in_z =
false; ip.
z = 1.0; }
772 else { in_z =
true; }
773 return in_tri && in_z;
781 internal::ProjectTriangle(ip.
y, ip.
z);
787 internal::ProjectTriangle(ip.
x, ip.
z);
793 if (ip.
x > 1.0) { ip.
x = 1.0; }
794 if (ip.
y > 1.0) { ip.
y = 1.0; }
800 bool in_tri = internal::ProjectTriangle(ip.
x, ip.
z);
801 if (ip.
y > ip.
z) { in_y =
false; ip.
y = ip.
z; }
802 return in_tri && in_y;
807 bool in_tri = internal::ProjectTriangle(ip.
y, ip.
z);
808 if (ip.
x > ip.
z) { in_x =
false; ip.
x = ip.
z; }
809 return in_tri && in_x;
814 MFEM_ABORT(
"Reference element type is not supported!");
817 MFEM_ABORT(
"Unknown type of reference element!");
837 pm(0,0) = 0.0; pm(1,0) = 0.0;
838 pm(0,1) = 1.0; pm(1,1) = 0.0;
839 pm(0,2) = 0.5; pm(1,2) = 0.86602540378443864676;
846 pm(0,0) = 0.0; pm(1,0) = 0.0;
847 pm(0,1) = 1.0; pm(1,1) = 0.0;
848 pm(0,2) = 1.0; pm(1,2) = 1.0;
849 pm(0,3) = 0.0; pm(1,3) = 1.0;
856 pm(0,0) = 0.0; pm(1,0) = 0.0; pm(2,0) = 0.0;
857 pm(0,1) = 1.0; pm(1,1) = 0.0; pm(2,1) = 0.0;
858 pm(0,2) = 0.5; pm(1,2) = 0.86602540378443864676; pm(2,2) = 0.0;
859 pm(0,3) = 0.5; pm(1,3) = 0.28867513459481288225;
860 pm(2,3) = 0.81649658092772603273;
867 pm(0,0) = 0.0; pm(1,0) = 0.0; pm(2,0) = 0.0;
868 pm(0,1) = 1.0; pm(1,1) = 0.0; pm(2,1) = 0.0;
869 pm(0,2) = 1.0; pm(1,2) = 1.0; pm(2,2) = 0.0;
870 pm(0,3) = 0.0; pm(1,3) = 1.0; pm(2,3) = 0.0;
871 pm(0,4) = 0.0; pm(1,4) = 0.0; pm(2,4) = 1.0;
872 pm(0,5) = 1.0; pm(1,5) = 0.0; pm(2,5) = 1.0;
873 pm(0,6) = 1.0; pm(1,6) = 1.0; pm(2,6) = 1.0;
874 pm(0,7) = 0.0; pm(1,7) = 1.0; pm(2,7) = 1.0;
881 pm(0,0) = 0.0; pm(1,0) = 0.0; pm(2,0) = 0.0;
882 pm(0,1) = 1.0; pm(1,1) = 0.0; pm(2,1) = 0.0;
883 pm(0,2) = 0.5; pm(1,2) = 0.86602540378443864676; pm(2,2) = 0.0;
884 pm(0,3) = 0.0; pm(1,3) = 0.0; pm(2,3) = 1.0;
885 pm(0,4) = 1.0; pm(1,4) = 0.0; pm(2,4) = 1.0;
886 pm(0,5) = 0.5; pm(1,5) = 0.86602540378443864676; pm(2,5) = 1.0;
893 pm(0,0) = 0.0; pm(1,0) = 0.0; pm(2,0) = 0.0;
894 pm(0,1) = 1.0; pm(1,1) = 0.0; pm(2,1) = 0.0;
895 pm(0,2) = 1.0; pm(1,2) = 1.0; pm(2,2) = 0.0;
896 pm(0,3) = 0.0; pm(1,3) = 1.0; pm(2,3) = 0.0;
897 pm(0,4) = 0.5; pm(1,4) = 0.5; pm(2,4) = 0.7071067811865475;
902 MFEM_ABORT(
"Reference element type is not supported!");
905 MFEM_ABORT(
"Unknown type of reference element!");
912 if (PerfGeomToGeomJac[GeomType])
914 Mult(J, *PerfGeomToGeomJac[GeomType], PJ);
925{ POINT, SEGMENT, TRIANGLE, TETRAHEDRON, NUM_GEOMETRIES };
953 {0, 1, 2}, {1, 0, 2}, {2, 0, 1},
954 {2, 1, 0}, {1, 2, 0}, {0, 2, 1}
965{{1, 0}, {3, -4}, {2, 1}, {3, 2}};
971 {0, 1, 2, 3}, {0, 3, 2, 1}, {1, 2, 3, 0}, {1, 0, 3, 2},
972 {2, 3, 0, 1}, {2, 1, 0, 3}, {3, 0, 1, 2}, {3, 2, 1, 0}
979{{0, 1}, {0, 2}, {0, 3}, {1, 2}, {1, 3}, {2, 3}};
988{{1, 2, 3}, {0, 3, 2}, {0, 1, 3}, {0, 2, 1}};
994 {1, 0}, {2, 1}, {3, 2},
1001 {0, 1, 2, 3}, {0, 1, 3, 2}, {0, 2, 3, 1}, {0, 2, 1, 3},
1002 {0, 3, 1, 2}, {0, 3, 2, 1},
1003 {1, 2, 0, 3}, {1, 2, 3, 0}, {1, 3, 2, 0}, {1, 3, 0, 2},
1004 {1, 0, 3, 2}, {1, 0, 2, 3},
1005 {2, 3, 0, 1}, {2, 3, 1, 0}, {2, 0, 1, 3}, {2, 0, 3, 1},
1006 {2, 1, 3, 0}, {2, 1, 0, 3},
1007 {3, 0, 2, 1}, {3, 0, 1, 2}, {3, 1, 0, 2}, {3, 1, 2, 0},
1008 {3, 2, 1, 0}, {3, 2, 0, 1}
1014 14, 19, 18, 15, 10, 11,
1015 12, 23, 6, 9, 20, 17,
1016 8, 7, 16, 21, 22, 13
1022 {0, 1}, {1, 2}, {3, 2}, {0, 3}, {4, 5}, {5, 6},
1023 {7, 6}, {4, 7}, {0, 4}, {1, 5}, {2, 6}, {3, 7}
1034 {3, 2, 1, 0}, {0, 1, 5, 4}, {1, 2, 6, 5},
1035 {2, 3, 7, 6}, {3, 0, 4, 7}, {4, 5, 6, 7}
1042 {1, 0}, {3, 3}, {4, 8},
1053{{0, 1}, {1, 2}, {2, 0}, {3, 4}, {4, 5}, {5, 3}, {0, 3}, {1, 4}, {2, 5}};
1062{{0, 2, 1, -1}, {3, 4, 5, -1}, {0, 1, 4, 3}, {1, 2, 5, 4}, {2, 0, 3, 5}};
1068 {1, 0}, {2, -3}, {3, 6},
1077{{0, 1}, {1, 2}, {3, 2}, {0, 3}, {0, 4}, {1, 4}, {2, 4}, {3, 4}};
1087{{3, 2, 1, 0}, {0, 1, 4, -1}, {1, 2, 4, -1}, {2, 3, 4, -1}, {3, 0, 4, -1}};
1093 {1, 0}, {3, 3}, {4, 4},
1104 for (
int j = 0; j < RGeom[i].Size(); j++) {
delete RGeom[i][j]; }
1105 for (
int j = 0; j < IntPts[i].Size(); j++) {
delete IntPts[i][j]; }
1110 int Times,
int ETimes)
const
1113 for (
int i = 0; i < RGA.
Size(); i++)
1124IntegrationRule *GeometryRefiner::FindInIntPts(
Geometry::Type Geom,
1127 const Array<IntegrationRule *> &IPA = IntPts[Geom];
1128 for (
int i = 0; i < IPA.Size(); i++)
1130 IntegrationRule &ir = *IPA[i];
1131 if (ir.GetNPoints() == NPts) {
return &ir; }
1141 Times = std::max(Times, 1);
1145#if defined(MFEM_THREAD_SAFE) && defined(MFEM_USE_OPENMP)
1146 #pragma omp critical (Refine)
1149 RG = FindInRGeom(Geom, Times, ETimes);
1173 for (i = 0; i <= Times; i++)
1179 for (i = 0; i < Times; i++)
1192 3*Times*(ETimes+1), 3*Times);
1196 for (k = j = 0; j <= Times; j++)
1198 for (i = 0; i <= Times-j; i++, k++)
1201 ip.
x = cp[i]/(cp[i] + cp[j] + cp[Times-i-j]);
1202 ip.
y = cp[j]/(cp[i] + cp[j] + cp[Times-i-j]);
1206 for (l = k = j = 0; j < Times; j++, k++)
1208 for (i = 0; i < Times-j; i++, k++)
1212 G[l++] = k+Times-j+1;
1216 G[l++] = k+Times-j+2;
1217 G[l++] = k+Times-j+1;
1224 for (k = 0; k < Times; k += Times/ETimes)
1226 int < = (k == 0) ? lb : li;
1227 j = k*(Times+1)-((k-1)*k)/2;
1228 for (i = 0; i < Times-k; i++)
1235 for (k = Times; k > 0; k -= Times/ETimes)
1237 int < = (k == Times) ? lb : li;
1239 for (i = 0; i < k; i++)
1241 E[lt++] = j; j += Times-i;
1246 for (k = 0; k < Times; k += Times/ETimes)
1248 int < = (k == 0) ? lb : li;
1250 for (i = 0; i < Times-k; i++)
1252 E[lt++] = j; j += Times-i+1;
1264 4*(ETimes+1)*Times, 4*Times);
1268 for (k = j = 0; j <= Times; j++)
1270 for (i = 0; i <= Times; i++, k++)
1278 for (l = k = j = 0; j < Times; j++, k++)
1280 for (i = 0; i < Times; i++, k++)
1291 for (k = 0; k <= Times; k += Times/ETimes)
1293 int < = (k == 0 || k == Times) ? lb : li;
1294 for (i = 0, j = k*(Times+1); i < Times; i++)
1301 for (k = Times; k >= 0; k -= Times/ETimes)
1303 int < = (k == Times || k == 0) ? lb : li;
1304 for (i = 0, j = k; i < Times; i++)
1306 E[lt++] = j; j += Times+1;
1318 8*Times*Times*Times, 0);
1322 for (l = k = 0; k <= Times; k++)
1324 for (j = 0; j <= Times; j++)
1326 for (i = 0; i <= Times; i++, l++)
1336 for (l = k = 0; k < Times; k++)
1338 for (j = 0; j < Times; j++)
1340 for (i = 0; i < Times; i++)
1342 G[l++] = i+0 + (j+0 + (k+0) * (Times+1)) * (Times+1);
1343 G[l++] = i+1 + (j+0 + (k+0) * (Times+1)) * (Times+1);
1344 G[l++] = i+1 + (j+1 + (k+0) * (Times+1)) * (Times+1);
1345 G[l++] = i+0 + (j+1 + (k+0) * (Times+1)) * (Times+1);
1346 G[l++] = i+0 + (j+0 + (k+1) * (Times+1)) * (Times+1);
1347 G[l++] = i+1 + (j+0 + (k+1) * (Times+1)) * (Times+1);
1348 G[l++] = i+1 + (j+1 + (k+1) * (Times+1)) * (Times+1);
1349 G[l++] = i+0 + (j+1 + (k+1) * (Times+1)) * (Times+1);
1373 const int n = Times;
1385 for (
int kk = 0; kk <= n; kk++)
1387 for (
int jj = 0; jj <= n-kk; jj++)
1389 for (
int ii = 0; ii <= n-jj-kk; ii++)
1392 real_t w = cp[ii] + cp[jj] + cp[kk] + cp[Times-ii-jj-kk];
1402 l = i + (j + k * (n+1)) * (n+1);
1411 if (m != (n+3)*(n+2)*(n+1)/6)
1413 MFEM_ABORT(
"GeometryRefiner::Refine() for TETRAHEDRON #1");
1418 for (k = 0; k < n; k++)
1420 for (j = 0; j <= k; j++)
1422 for (i = 0; i <= j; i++)
1432 G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
1433 G[m++] = vi[i+0 + (j+0 + (k+1) * (n+1)) * (n+1)];
1434 G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
1435 G[m++] = vi[i+0 + (j+1 + (k+1) * (n+1)) * (n+1)];
1439 G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
1440 G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
1441 G[m++] = vi[i+0 + (j+1 + (k+0) * (n+1)) * (n+1)];
1442 G[m++] = vi[i+0 + (j+1 + (k+1) * (n+1)) * (n+1)];
1444 G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
1445 G[m++] = vi[i+0 + (j+1 + (k+0) * (n+1)) * (n+1)];
1446 G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
1447 G[m++] = vi[i+1 + (j+1 + (k+0) * (n+1)) * (n+1)];
1452 G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
1453 G[m++] = vi[i+1 + (j+0 + (k+0) * (n+1)) * (n+1)];
1454 G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
1455 G[m++] = vi[i+1 + (j+0 + (k+1) * (n+1)) * (n+1)];
1459 G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
1460 G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
1461 G[m++] = vi[i+1 + (j+0 + (k+0) * (n+1)) * (n+1)];
1462 G[m++] = vi[i+1 + (j+1 + (k+0) * (n+1)) * (n+1)];
1465 G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
1466 G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
1467 G[m++] = vi[i+0 + (j+0 + (k+1) * (n+1)) * (n+1)];
1468 G[m++] = vi[i+1 + (j+0 + (k+1) * (n+1)) * (n+1)];
1475 MFEM_ABORT(
"GeometryRefiner::Refine() for TETRAHEDRON #2");
1477 for (i = 0; i < m; i++)
1481 MFEM_ABORT(
"GeometryRefiner::Refine() for TETRAHEDRON #3");
1491 const int n = Times;
1493 5*n*(2*n-1)*(2*n+1)/3, 0);
1499 for (k = 0; k <= n; k++)
1503 for (j = 0; j <= n - k; j++)
1505 for (i = 0; i <= n - k; i++)
1510 ip.
x = (n > k) ? (
real_t(i) / (n - k)) : 0.0;
1511 ip.
y = (n > k) ? (
real_t(j) / (n - k)) : 0.0;
1516 ip.
x = cpij[i] * (1.0 - cp[k]);
1517 ip.
y = cpij[j] * (1.0 - cp[k]);
1524 if (m != (n+1)*(n+2)*(2*n+3)/6)
1526 MFEM_ABORT(
"GeometryRefiner::Refine() for PYRAMID #1");
1531 for (k = 0; k < n; k++)
1533 int lk = k * (k * (2 * k - 6 * n - 9) + 6 * n * (n + 3) + 13) / 6;
1534 int lkp1 = (k + 1) *
1535 (k * (2 * k - 6 * n -5) + 6 * n * (n + 2) + 6) / 6;
1536 for (j = 0; j < n - k; j++)
1538 for (i = 0; i < n - k; i++)
1540 G[m++] = lk + j * (n - k + 1) + i;
1541 G[m++] = lk + j * (n - k + 1) + i + 1;
1542 G[m++] = lk + (j + 1) * (n - k + 1) + i + 1;
1543 G[m++] = lk + (j + 1) * (n - k + 1) + i;
1544 G[m++] = lkp1 + j * (n - k) + i;
1547 for (j = 0; j < n - k - 1; j++)
1549 for (i = 0; i < n - k - 1; i++)
1551 G[m++] = lkp1 + j * (n - k) + i;
1552 G[m++] = lkp1 + (j + 1) * (n - k) + i;
1553 G[m++] = lkp1 + (j + 1) * (n - k) + i + 1;
1554 G[m++] = lkp1 + j * (n - k) + i + 1;
1555 G[m++] = lk + (j + 1) * (n - k + 1) + i + 1;
1558 for (j = 0; j < n - k; j++)
1560 for (i = 0; i < n - k - 1; i++)
1562 G[m++] = lk + j * (n - k + 1) + i + 1;
1563 G[m++] = lk + (j + 1) * (n - k + 1) + i + 1;
1564 G[m++] = lkp1 + j * (n - k) + i;
1565 G[m++] = lkp1 + j * (n - k) + i + 1;
1569 for (j = 0; j < n - k - 1; j++)
1571 for (i = 0; i < n - k; i++)
1573 G[m++] = lk + (j + 1) * (n - k + 1) + i;
1574 G[m++] = lk + (j + 1) * (n - k + 1) + i + 1;
1575 G[m++] = lkp1 + (j + 1) * (n - k) + i;
1576 G[m++] = lkp1 + j * (n - k) + i;
1581 if (m != 5*n*(2*n-1)*(2*n+1)/3)
1583 MFEM_ABORT(
"GeometryRefiner::Refine() for PYRAMID #2");
1592 const int n = Times;
1599 for (l = k = 0; k <= n; k++)
1601 for (j = 0; j <= n; j++)
1603 for (i = 0; i <= n-j; i++, l++)
1606 ip.
x = cp[i]/(cp[i] + cp[j] + cp[n-i-j]);
1607 ip.
y = cp[j]/(cp[i] + cp[j] + cp[n-i-j]);
1613 if (m != (n+1)*(n+1)*(n+2)/2)
1615 MFEM_ABORT(
"GeometryRefiner::Refine() for PRISM #1");
1620 for (m = k = 0; k < n; k++)
1622 for (l = j = 0; j < n; j++, l++)
1624 for (i = 0; i < n-j; i++, l++)
1626 G[m++] = l + (k+0) * (n+1) * (n+2) / 2;
1627 G[m++] = l + 1 + (k+0) * (n+1) * (n+2) / 2;
1628 G[m++] = l - j + (2 + (k+0) * (n+2)) * (n+1) / 2;
1629 G[m++] = l + (k+1) * (n+1) * (n+2) / 2;
1630 G[m++] = l + 1 + (k+1) * (n+1) * (Times+2) / 2;
1631 G[m++] = l - j + (2 + (k+1) * (n+2)) * (n+1) / 2;
1634 G[m++] = l + 1 + (k+0) * (n+1) * (n+2)/2;
1635 G[m++] = l - j + (2 + (k+0) * (n+1)) * (n+2) / 2;
1636 G[m++] = l - j + (2 + (k+0) * (n+2)) * (n+1) / 2;
1637 G[m++] = l + 1 + (k+1) * (n+1) * (n+2) / 2;
1638 G[m++] = l - j + (2 + (k+1) * (n+1)) * (n+2) / 2;
1639 G[m++] = l - j + (2 + (k+1) * (n+2)) * (n+1) / 2;
1646 MFEM_ABORT(
"GeometryRefiner::Refine() for PRISM #2");
1648 for (i = 0; i < m; i++)
1652 MFEM_ABORT(
"GeometryRefiner::Refine() for PRISM #3");
1662 MFEM_ABORT(
"Unknown type of reference element!");
1683#if defined(MFEM_THREAD_SAFE) && defined(MFEM_USE_OPENMP)
1684 #pragma omp critical (RefineInterior)
1691 for (
int i = 1; i < Times; i++)
1710#if defined(MFEM_THREAD_SAFE) && defined(MFEM_USE_OPENMP)
1711 #pragma omp critical (RefineInterior)
1718 for (
int k = 0, j = 1; j < Times-1; j++)
1720 for (
int i = 1; i < Times-j; i++, k++)
1741#if defined(MFEM_THREAD_SAFE) && defined(MFEM_USE_OPENMP)
1742 #pragma omp critical (RefineInterior)
1749 for (
int k = 0, j = 1; j < Times; j++)
1751 for (
int i = 1; i < Times; i++, k++)
1771 MFEM_ABORT(
"Reference element type is not supported!");
1774 MFEM_ABORT(
"Unknown type of reference element!");
1795 for (
int n = 0, np = 0; (n < 15) && (np < Npts) ; n++)
1798 if (np == Npts) {
return n; }
1804 for (
int n = 0, np = 0; (n < 15) && (np < Npts) ; n++)
1807 if (np == Npts) {
return n; }
1813 for (
int n = 0, np = 0; (n < 15) && (np < Npts) ; n++)
1815 np = (n+1)*(n+1)*(n+1);
1816 if (np == Npts) {
return n; }
1822 for (
int n = 0, np = 0; (n < 15) && (np < Npts) ; n++)
1824 np = (n+3)*(n+2)*(n+1)/6;
1825 if (np == Npts) {
return n; }
1831 for (
int n = 0, np = 0; (n < 15) && (np < Npts) ; n++)
1833 np = (n+1)*(n+1)*(n+2)/2;
1834 if (np == Npts) {
return n; }
1839 MFEM_ABORT(
"Reference element type is not supported!");
1842 MFEM_ABORT(
"Unknown type of reference element!");
1864 for (
int n = 0; (n < 15) && (n*n < Nels+1) ; n++)
1866 if (n*n == Nels) {
return n-1; }
1874 for (
int n = 0; (n < 15) && (n*n*n < Nels+1) ; n++)
1876 if (n*n*n == Nels) {
return n-1; }
1881 MFEM_ABORT(
"Reference element type is not supported!");
1884 MFEM_ABORT(
"Unknown type of reference element!");
int Size() const
Return the logical size of the array.
static int GetNodalBasis(int qpt_type)
Return the nodal BasisType corresponding to the Quadrature1D type.
Data type dense matrix using column-major storage.
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
void Diag(real_t c, int n)
Creates n x n diagonal matrix with diagonal elements c.
RefinedGeometry * Refine(Geometry::Type Geom, int Times, int ETimes=1)
const IntegrationRule * RefineInterior(Geometry::Type Geom, int Times)
static int GetRefinementLevelFromElems(Geometry::Type geom, int Npts)
Get the Refinement level based on number of elements.
static int GetRefinementLevelFromPoints(Geometry::Type Geom, int Npts)
Get the Refinement level based on number of points.
static const int Dimension[NumGeom]
static const int NumFaces[NumGeom]
void GetPerfPointMat(int GeomType, DenseMatrix &pm) const
static const real_t Volume[NumGeom]
static const char * Name[NumGeom]
static const int NumVerts[NumGeom]
const IntegrationRule * GetVertices(int GeomType) const
Return an IntegrationRule consisting of all vertices of the given Geometry::Type, GeomType.
static const int NumBdrArray[NumGeom]
static void GetRandomPoint(int GeomType, IntegrationPoint &ip)
Get a random point in the reference element specified by GeomType.
void JacToPerfJac(int GeomType, const DenseMatrix &J, DenseMatrix &PJ) const
static bool CheckPoint(int GeomType, const IntegrationPoint &ip)
Check if the given point is inside the given reference element.
static int GetInverseOrientation(Type geom_type, int orientation)
Return the inverse of the given orientation for the specified geometry type.
static const int NumEdges[NumGeom]
static const int DimStart[MaxDim+2]
static bool ProjectPoint(int GeomType, const IntegrationPoint &beg, IntegrationPoint &end)
Project a point end, onto the given Geometry::Type, GeomType.
Class for integration point with weight.
Class for an integration rule - an Array of IntegrationPoint.
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
const real_t * GetPoints(const int p, const int btype)
Get the coordinates of the points of the given BasisType, btype.
void mfem_error(const char *msg)
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
GeometryRefiner GlobGeometryRefiner
int GetInverseOrientation_(int orientation)
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
MFEM_EXPORT class Linear3DFiniteElement TetrahedronFE
MFEM_EXPORT class LinearWedgeFiniteElement WedgeFE
class LinearPyramidFiniteElement PyramidFE
MFEM_EXPORT Linear2DFiniteElement TriangleFE
static const int J[NumEdges][2]
static const int I[NumVert]
static const int FaceVert[NumFaces][MaxFaceVert]
static const int Edges[NumEdges][2]
static const int FaceTypes[NumFaces]
static const int Orient[NumOrient][NumVert]
static const int InvOrient[NumOrient]
static const int I[NumVert]
static const int J[NumEdges][2]
static const int FaceVert[NumFaces][MaxFaceVert]
static const int FaceTypes[NumFaces]
static const int Edges[NumEdges][2]
static const int J[NumEdges][2]
static const int I[NumVert]
static const int FaceTypes[NumFaces]
static const int Edges[NumEdges][2]
static const int FaceVert[NumFaces][MaxFaceVert]
static const int Orient[NumOrient][NumVert]
static const int InvOrient[NumOrient]
static const int Edges[NumEdges][2]
static const int J[NumEdges][2]
static const int I[NumVert]
static const int Orient[NumOrient][NumVert]
static const int FaceVert[NumFaces][NumVert]
static const int InvOrient[NumOrient]
static const int Edges[NumEdges][2]
static const int J[NumEdges][2]
static const int I[NumVert]
static const int Edges[NumEdges][2]
static const int FaceVert[NumFaces][MaxFaceVert]
static const int InvOrient[NumOrient]
static const int FaceTypes[NumFaces]
static const int Orient[NumOrient][NumVert]
static const int I[NumVert]
static const int J[NumEdges][2]
static const int FaceVert[NumFaces][NumVert]
static const int Edges[NumEdges][2]
static const int InvOrient[NumOrient]
static const int Orient[NumOrient][NumVert]