18 {
"Point",
"Segment",
"Triangle",
"Square",
"Tetrahedron",
"Cube" };
21 { 1.0, 1.0, 0.5, 1.0, 1./6, 1.0 };
114 GeomCenter[
POINT].
x = 0.0;
115 GeomCenter[
POINT].
y = 0.0;
116 GeomCenter[
POINT].
z = 0.0;
134 GeomCenter[
CUBE].
x = 0.5;
135 GeomCenter[
CUBE].
y = 0.5;
136 GeomCenter[
CUBE].
z = 0.5;
138 PerfGeomToGeomJac[
POINT] = NULL;
139 PerfGeomToGeomJac[
SEGMENT] = NULL;
141 PerfGeomToGeomJac[
SQUARE] = NULL;
143 PerfGeomToGeomJac[
CUBE] = NULL;
165 for (
int i = 0; i <
NumGeom; i++)
167 delete PerfGeomToGeomJac[i];
198 ip.
x = double(rand()) / RAND_MAX;
201 ip.
x = double(rand()) / RAND_MAX;
202 ip.
y = double(rand()) / RAND_MAX;
203 if (ip.
x + ip.
y > 1.0)
210 ip.
x = double(rand()) / RAND_MAX;
211 ip.
y = double(rand()) / RAND_MAX;
214 ip.
x = double(rand()) / RAND_MAX;
215 ip.
y = double(rand()) / RAND_MAX;
216 ip.
z = double(rand()) / RAND_MAX;
219 if (ip.
x + ip.
y > 1.0)
226 if (ip.
x + ip.
z > 1.0)
229 ip.
x = ip.
x + ip.
z - 1.0;
234 else if (ip.
x + ip.
y + ip.
z > 1.0)
238 ip.
x = 1.0 - x - ip.
z;
239 ip.
y = 1.0 - x - ip.
y;
245 ip.
x = double(rand()) / RAND_MAX;
246 ip.
y = double(rand()) / RAND_MAX;
247 ip.
z = double(rand()) / RAND_MAX;
250 MFEM_ABORT(
"Unknown type of reference element!");
260 if (ip.
x != 0.0) {
return false; }
263 if (ip.
x < 0.0 || ip.
x > 1.0) {
return false; }
266 if (ip.
x < 0.0 || ip.
y < 0.0 || ip.
x+ip.
y > 1.0) {
return false; }
269 if (ip.
x < 0.0 || ip.
x > 1.0 || ip.
y < 0.0 || ip.
y > 1.0)
273 if (ip.
x < 0.0 || ip.
y < 0.0 || ip.
z < 0.0 ||
274 ip.
x+ip.
y+ip.
z > 1.0) {
return false; }
277 if (ip.
x < 0.0 || ip.
x > 1.0 || ip.
y < 0.0 || ip.
y > 1.0 ||
278 ip.
z < 0.0 || ip.
z > 1.0) {
return false; }
281 MFEM_ABORT(
"Unknown type of reference element!");
289 template <
int N,
int dim>
290 inline bool IntersectSegment(
double lbeg[N],
double lend[N],
295 for (
int i = 0; i < N; i++)
297 lbeg[i] = std::max(lbeg[i], 0.0);
301 t = std::min(t, lbeg[i]/(lbeg[i]-lend[i]));
306 if (
dim >= 1) { end.
x = t*lend[0] + (1.0-t)*lbeg[0]; }
307 if (
dim >= 2) { end.
y = t*lend[1] + (1.0-t)*lbeg[1]; }
308 if (
dim >= 3) { end.
z = t*lend[2] + (1.0-t)*lbeg[2]; }
324 if (end.
x != 0.0) { end.
x = 0.0;
return false; }
329 if (end.
x < 0.0) { end.
x = 0.0;
return false; }
330 if (end.
x > 1.0) { end.
x = 1.0;
return false; }
335 double lend[3] = { end.
x, end.
y, 1-end.
x-end.
y };
336 double lbeg[3] = { beg.
x, beg.
y, 1-beg.
x-beg.
y };
337 return internal::IntersectSegment<3,2>(lbeg, lend, end);
341 double lend[4] = { end.
x, end.
y, 1-end.
x, 1.0-end.
y };
342 double lbeg[4] = { beg.
x, beg.
y, 1-beg.
x, 1.0-beg.
y };
343 return internal::IntersectSegment<4,2>(lbeg, lend, end);
347 double lend[4] = { end.
x, end.
y, end.
z, 1.0-end.
x-end.
y-end.
z };
348 double lbeg[4] = { beg.
x, beg.
y, beg.
z, 1.0-beg.
x-beg.
y-beg.
z };
349 return internal::IntersectSegment<4,3>(lbeg, lend, end);
353 double lend[6] = { end.
x, end.
y, end.
z,
354 1.0-end.
x, 1.0-end.
y, 1.0-end.
z
356 double lbeg[6] = { beg.
x, beg.
y, beg.
z,
357 1.0-beg.
x, 1.0-beg.
y, 1.0-beg.
z
359 return internal::IntersectSegment<6,3>(lbeg, lend, end);
362 MFEM_ABORT(
"Unknown type of reference element!");
382 pm(0,0) = 0.0; pm(1,0) = 0.0;
383 pm(0,1) = 1.0; pm(1,1) = 0.0;
384 pm(0,2) = 0.5; pm(1,2) = 0.86602540378443864676;
391 pm(0,0) = 0.0; pm(1,0) = 0.0;
392 pm(0,1) = 1.0; pm(1,1) = 0.0;
393 pm(0,2) = 1.0; pm(1,2) = 1.0;
394 pm(0,3) = 0.0; pm(1,3) = 1.0;
401 pm(0,0) = 0.0; pm(1,0) = 0.0; pm(2,0) = 0.0;
402 pm(0,1) = 1.0; pm(1,1) = 0.0; pm(2,1) = 0.0;
403 pm(0,2) = 0.5; pm(1,2) = 0.86602540378443864676; pm(2,2) = 0.0;
404 pm(0,3) = 0.5; pm(1,3) = 0.28867513459481288225;
405 pm(2,3) = 0.81649658092772603273;
412 pm(0,0) = 0.0; pm(1,0) = 0.0; pm(2,0) = 0.0;
413 pm(0,1) = 1.0; pm(1,1) = 0.0; pm(2,1) = 0.0;
414 pm(0,2) = 1.0; pm(1,2) = 1.0; pm(2,2) = 0.0;
415 pm(0,3) = 0.0; pm(1,3) = 1.0; pm(2,3) = 0.0;
416 pm(0,4) = 0.0; pm(1,4) = 0.0; pm(2,4) = 1.0;
417 pm(0,5) = 1.0; pm(1,5) = 0.0; pm(2,5) = 1.0;
418 pm(0,6) = 1.0; pm(1,6) = 1.0; pm(2,6) = 1.0;
419 pm(0,7) = 0.0; pm(1,7) = 1.0; pm(2,7) = 1.0;
424 mfem_error (
"Geometry::GetPerfPointMat (...)");
431 if (PerfGeomToGeomJac[GeomType])
433 Mult(J, *PerfGeomToGeomJac[GeomType], PJ);
470 {0, 1, 2}, {1, 0, 2}, {2, 0, 1},
471 {2, 1, 0}, {1, 2, 0}, {0, 2, 1}
482 {{1, 0}, {3, -4}, {2, 1}, {3, 2}};
488 {0, 1, 2, 3}, {0, 3, 2, 1}, {1, 2, 3, 0}, {1, 0, 3, 2},
489 {2, 3, 0, 1}, {2, 1, 0, 3}, {3, 0, 1, 2}, {3, 2, 1, 0}
496 {{0, 1}, {0, 2}, {0, 3}, {1, 2}, {1, 3}, {2, 3}};
505 {{1, 2, 3}, {0, 3, 2}, {0, 1, 3}, {0, 2, 1}};
510 {{1, 0}, {2, 1}, {3, 2}, {2, 3}, {3, 4}, {3, 5}};
515 {0, 1}, {1, 2}, {3, 2}, {0, 3}, {4, 5}, {5, 6},
516 {7, 6}, {4, 7}, {0, 4}, {1, 5}, {2, 6}, {3, 7}
527 {3, 2, 1, 0}, {0, 1, 5, 4}, {1, 2, 6, 5},
528 {2, 3, 7, 6}, {3, 0, 4, 7}, {4, 5, 6, 7}
535 {1, 0}, {3, 3}, {4, 8},
570 const double *cp = NULL;
581 if (RGeom[g] != NULL && RGeom[g]->Times == Times)
587 RGeom[g]->
Times = Times;
589 for (i = 0; i <= Times; i++)
592 ip.
x = (type == 0) ?
double(i) / Times : cp[i];
595 for (i = 0; i < Times; i++)
606 if (RGeom[2] != NULL && RGeom[2]->Times == Times &&
607 RGeom[2]->ETimes == ETimes)
612 if (RGeom[2] != NULL)
617 3*Times*(ETimes+1), 3*Times);
618 RGeom[2]->
Times = Times;
619 RGeom[2]->
ETimes = ETimes;
620 for (k = j = 0; j <= Times; j++)
621 for (i = 0; i <= Times-j; i++, k++)
626 ip.
x = double(i) / Times;
627 ip.
y = double(j) / Times;
631 ip.
x = cp[i]/(cp[i] + cp[j] + cp[Times-i-j]);
632 ip.
y = cp[j]/(cp[i] + cp[j] + cp[Times-i-j]);
636 for (l = k = j = 0; j < Times; j++, k++)
637 for (i = 0; i < Times-j; i++, k++)
641 G[l++] = k+Times-j+1;
645 G[l++] = k+Times-j+2;
646 G[l++] = k+Times-j+1;
652 for (k = 0; k < Times; k += Times/ETimes)
654 int < = (k == 0) ? lb : li;
655 j = k*(Times+1)-((k-1)*k)/2;
656 for (i = 0; i < Times-k; i++)
663 for (k = Times; k > 0; k -= Times/ETimes)
665 int < = (k == Times) ? lb : li;
667 for (i = 0; i < k; i++)
669 E[lt++] = j; j += Times-i;
674 for (k = 0; k < Times; k += Times/ETimes)
676 int < = (k == 0) ? lb : li;
678 for (i = 0; i < Times-k; i++)
680 E[lt++] = j; j += Times-i+1;
690 if (RGeom[3] != NULL && RGeom[3]->Times == Times &&
691 RGeom[3]->ETimes == ETimes)
696 if (RGeom[3] != NULL)
701 4*(ETimes+1)*Times, 4*Times);
702 RGeom[3]->
Times = Times;
703 RGeom[3]->
ETimes = ETimes;
704 for (k = j = 0; j <= Times; j++)
705 for (i = 0; i <= Times; i++, k++)
710 ip.
x = double(i) / Times;
711 ip.
y = double(j) / Times;
720 for (l = k = j = 0; j < Times; j++, k++)
721 for (i = 0; i < Times; i++, k++)
731 for (k = 0; k <= Times; k += Times/ETimes)
733 int < = (k == 0 || k == Times) ? lb : li;
734 for (i = 0, j = k*(Times+1); i < Times; i++)
741 for (k = Times; k >= 0; k -= Times/ETimes)
743 int < = (k == Times || k == 0) ? lb : li;
744 for (i = 0, j = k; i < Times; i++)
746 E[lt++] = j; j += Times+1;
757 if (RGeom[g] != NULL && RGeom[g]->Times == Times &&
758 RGeom[g]->ETimes == ETimes)
763 if (RGeom[g] != NULL)
768 8*Times*Times*Times, 0);
769 RGeom[g]->
Times = Times;
770 RGeom[g]->
ETimes = ETimes;
771 for (l = k = 0; k <= Times; k++)
772 for (j = 0; j <= Times; j++)
773 for (i = 0; i <= Times; i++, l++)
778 ip.
x = double(i) / Times;
779 ip.
y = double(j) / Times;
780 ip.
z = double(k) / Times;
790 for (l = k = 0; k < Times; k++)
791 for (j = 0; j < Times; j++)
792 for (i = 0; i < Times; i++)
794 G[l++] = i+0 + (j+0 + (k+0) * (Times+1)) * (Times+1);
795 G[l++] = i+1 + (j+0 + (k+0) * (Times+1)) * (Times+1);
796 G[l++] = i+1 + (j+1 + (k+0) * (Times+1)) * (Times+1);
797 G[l++] = i+0 + (j+1 + (k+0) * (Times+1)) * (Times+1);
798 G[l++] = i+0 + (j+0 + (k+1) * (Times+1)) * (Times+1);
799 G[l++] = i+1 + (j+0 + (k+1) * (Times+1)) * (Times+1);
800 G[l++] = i+1 + (j+1 + (k+1) * (Times+1)) * (Times+1);
801 G[l++] = i+0 + (j+1 + (k+1) * (Times+1)) * (Times+1);
810 if (RGeom[g] != NULL && RGeom[g]->Times == Times &&
811 RGeom[g]->ETimes == ETimes)
816 if (RGeom[g] != NULL)
840 for (k = 0; k <= n; k++)
841 for (j = 0; j <= k; j++)
842 for (i = 0; i <= j; i++)
852 ip.
x = double(k - j) / n;
853 ip.
y = double(i) / n;
854 ip.
z = double(j - i) / n;
858 double w = cp[k-j] + cp[i] + cp[j-i] + cp[Times-k];
863 l = i + (j + k * (n+1)) * (n+1);
867 if (m != (n+3)*(n+2)*(n+1)/6)
869 mfem_error(
"GeometryRefiner::Refine() for TETRAHEDRON #1");
874 for (k = 0; k < n; k++)
875 for (j = 0; j <= k; j++)
876 for (i = 0; i <= j; i++)
886 G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
887 G[m++] = vi[i+0 + (j+0 + (k+1) * (n+1)) * (n+1)];
888 G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
889 G[m++] = vi[i+0 + (j+1 + (k+1) * (n+1)) * (n+1)];
893 G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
894 G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
895 G[m++] = vi[i+0 + (j+1 + (k+0) * (n+1)) * (n+1)];
896 G[m++] = vi[i+0 + (j+1 + (k+1) * (n+1)) * (n+1)];
898 G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
899 G[m++] = vi[i+0 + (j+1 + (k+0) * (n+1)) * (n+1)];
900 G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
901 G[m++] = vi[i+1 + (j+1 + (k+0) * (n+1)) * (n+1)];
906 G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
907 G[m++] = vi[i+1 + (j+0 + (k+0) * (n+1)) * (n+1)];
908 G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
909 G[m++] = vi[i+1 + (j+0 + (k+1) * (n+1)) * (n+1)];
913 G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
914 G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
915 G[m++] = vi[i+1 + (j+0 + (k+0) * (n+1)) * (n+1)];
916 G[m++] = vi[i+1 + (j+1 + (k+0) * (n+1)) * (n+1)];
919 G[m++] = vi[i+0 + (j+0 + (k+0) * (n+1)) * (n+1)];
920 G[m++] = vi[i+1 + (j+1 + (k+1) * (n+1)) * (n+1)];
921 G[m++] = vi[i+0 + (j+0 + (k+1) * (n+1)) * (n+1)];
922 G[m++] = vi[i+1 + (j+0 + (k+1) * (n+1)) * (n+1)];
927 mfem_error(
"GeometryRefiner::Refine() for TETRAHEDRON #2");
929 for (i = 0; i < m; i++)
932 mfem_error(
"GeometryRefiner::Refine() for TETRAHEDRON #3");
956 if (IntPts[g] == NULL || IntPts[g]->GetNPoints() != Times-1)
960 for (
int i = 1; i < Times; i++)
963 ip.
x = double(i) / Times;
976 if (IntPts[g] == NULL ||
977 IntPts[g]->GetNPoints() != ((Times-1)*(Times-2))/2)
981 for (
int k = 0, j = 1; j < Times-1; j++)
982 for (
int i = 1; i < Times-j; i++, k++)
985 ip.
x = double(i) / Times;
986 ip.
y = double(j) / Times;
999 if (IntPts[g] == NULL || IntPts[g]->GetNPoints() != (Times-1)*(Times-1))
1003 for (
int k = 0, j = 1; j < Times; j++)
1004 for (
int i = 1; i < Times; i++, k++)
1007 ip.
x = double(i) / Times;
1008 ip.
y = double(j) / Times;
1016 mfem_error(
"GeometryRefiner::RefineInterior(...)");
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]
void JacToPerfJac(int GeomType, const DenseMatrix &J, DenseMatrix &PJ) const
static void GetRandomPoint(int GeomType, IntegrationPoint &ip)
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]
RefinedGeometry * Refine(int Geom, int Times, int ETimes=1)
Data type dense matrix using column-major storage.
static const double Volume[NumGeom]
static const int I[NumVert]
static const int NumBdrArray[]
static const int NumEdges[NumGeom]
const IntegrationRule * GetVertices(int GeomType)
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]
const IntegrationRule * RefineInterior(int Geom, int Times)
static const int FaceTypes[NumFaces]
static const int NumVerts[NumGeom]
static const int Edges[NumEdges][2]
GeometryRefiner GlobGeometryRefiner
Class for linear FE on tetrahedron.
Class for linear FE on triangle.
static const int InvOrient[NumOrient]
static const int Orient[NumOrient][NumVert]
static const int Edges[NumEdges][2]
static const char * Name[NumGeom]
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)
void GetPerfPointMat(int GeomType, DenseMatrix &pm)
void mfem_error(const char *msg)
static const int FaceVert[NumFaces][MaxFaceVert]
static const int J[NumEdges][2]
static const int I[NumVert]
static const int FaceVert[NumFaces][NumVert]
Class for integration point with weight.
static const int FaceTypes[NumFaces]
static const int FaceVert[NumFaces][NumVert]
static const int Orient[NumOrient][NumVert]
static const int Edges[NumEdges][2]
const double * ClosedPoints(const int p, const int type=Quadrature1D::GaussLobatto)
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.
static const int Orient[NumOrient][NumVert]
static const int J[NumEdges][2]