Merge remote-tracking branch 'origin/master' into lo-dim-em-dev

# Conflicts:
#	fem/bilininteg.cpp
#	fem/fe/fe_base.hpp
#	fem/fe/fe_nd.cpp
#	fem/fe/fe_nd.hpp
#	fem/fe/fe_rt.cpp
#	fem/fe/fe_rt.hpp
This commit is contained in:
Stowell, Mark L
2022-02-28 09:49:07 -08:00
119 changed files with 4403 additions and 2379 deletions
+290
View File
@@ -1217,6 +1217,296 @@ void ND_SegmentElement::CalcVShape(const IntegrationPoint &ip,
obasis1d.Eval(ip.x, vshape);
}
const double ND_WedgeElement::tk[15] =
{ 1.,0.,0., -1.,1.,0., 0.,-1.,0., 0.,0.,1., 0.,1.,0. };
ND_WedgeElement::ND_WedgeElement(const int p,
const int cb_type,
const int ob_type)
: VectorFiniteElement(3, Geometry::PRISM,
3 * p * ((p + 1) * (p + 2))/2, p,
H_CURL, FunctionSpace::Qk),
dof2tk(dof),
t_dof(dof),
s_dof(dof),
H1TriangleFE(p, cb_type),
NDTriangleFE(p),
H1SegmentFE(p, cb_type),
NDSegmentFE(p, ob_type)
{
MFEM_ASSERT(H1TriangleFE.GetDof() * NDSegmentFE.GetDof() +
NDTriangleFE.GetDof() * H1SegmentFE.GetDof() == dof,
"Mismatch in number of degrees of freedom "
"when building ND_WedgeElement!");
#ifndef MFEM_THREAD_SAFE
t1_shape.SetSize(H1TriangleFE.GetDof());
s1_shape.SetSize(H1SegmentFE.GetDof());
tn_shape.SetSize(NDTriangleFE.GetDof(), 2);
sn_shape.SetSize(NDSegmentFE.GetDof(), 1);
t1_dshape.SetSize(H1TriangleFE.GetDof(), 2);
s1_dshape.SetSize(H1SegmentFE.GetDof(), 1);
tn_dshape.SetSize(NDTriangleFE.GetDof(), 1);
#endif
const int pm1 = p - 1, pm2 = p - 2;
const IntegrationRule &t1_n = H1TriangleFE.GetNodes();
const IntegrationRule &tn_n = NDTriangleFE.GetNodes();
const IntegrationRule &s1_n = H1SegmentFE.GetNodes();
const IntegrationRule &sn_n = NDSegmentFE.GetNodes();
// edges
int o = 0;
for (int i = 0; i < p; i++) // (0,1)
{
t_dof[o] = i; s_dof[o] = 0; dof2tk[o] = 0;
const IntegrationPoint & t_ip = tn_n.IntPoint(t_dof[o]);
Nodes.IntPoint(o).Set3(t_ip.x, t_ip.y, s1_n.IntPoint(s_dof[o]).x);
o++;
}
for (int i = 0; i < p; i++) // (1,2)
{
t_dof[o] = p + i; s_dof[o] = 0; dof2tk[o] = 1;
const IntegrationPoint & t_ip = tn_n.IntPoint(t_dof[o]);
Nodes.IntPoint(o).Set3(t_ip.x, t_ip.y, s1_n.IntPoint(s_dof[o]).x);
o++;
}
for (int i = 0; i < p; i++) // (2,0)
{
t_dof[o] = 2 * p + i; s_dof[o] = 0; dof2tk[o] = 2;
const IntegrationPoint & t_ip = tn_n.IntPoint(t_dof[o]);
Nodes.IntPoint(o).Set3(t_ip.x, t_ip.y, s1_n.IntPoint(s_dof[o]).x);
o++;
}
for (int i = 0; i < p; i++) // (3,4)
{
t_dof[o] = i; s_dof[o] = 1; dof2tk[o] = 0;
const IntegrationPoint & t_ip = tn_n.IntPoint(t_dof[o]);
Nodes.IntPoint(o).Set3(t_ip.x, t_ip.y, s1_n.IntPoint(s_dof[o]).x);
o++;
}
for (int i = 0; i < p; i++) // (4,5)
{
t_dof[o] = p + i; s_dof[o] = 1; dof2tk[o] = 1;
const IntegrationPoint & t_ip = tn_n.IntPoint(t_dof[o]);
Nodes.IntPoint(o).Set3(t_ip.x, t_ip.y, s1_n.IntPoint(s_dof[o]).x);
o++;
}
for (int i = 0; i < p; i++) // (5,3)
{
t_dof[o] = 2 * p + i; s_dof[o] = 1; dof2tk[o] = 2;
const IntegrationPoint & t_ip = tn_n.IntPoint(t_dof[o]);
Nodes.IntPoint(o).Set3(t_ip.x, t_ip.y, s1_n.IntPoint(s_dof[o]).x);
o++;
}
for (int i = 0; i < p; i++) // (0,3)
{
t_dof[o] = 0; s_dof[o] = i; dof2tk[o] = 3;
const IntegrationPoint & t_ip = t1_n.IntPoint(t_dof[o]);
Nodes.IntPoint(o).Set3(t_ip.x, t_ip.y, sn_n.IntPoint(s_dof[o]).x);
o++;
}
for (int i = 0; i < p; i++) // (1,4)
{
t_dof[o] = 1; s_dof[o] = i; dof2tk[o] = 3;
const IntegrationPoint & t_ip = t1_n.IntPoint(t_dof[o]);
Nodes.IntPoint(o).Set3(t_ip.x, t_ip.y, sn_n.IntPoint(s_dof[o]).x);
o++;
}
for (int i = 0; i < p; i++) // (2,5)
{
t_dof[o] = 2; s_dof[o] = i; dof2tk[o] = 3;
const IntegrationPoint & t_ip = t1_n.IntPoint(t_dof[o]);
Nodes.IntPoint(o).Set3(t_ip.x, t_ip.y, sn_n.IntPoint(s_dof[o]).x);
o++;
}
// faces
// (0,2,1) -- bottom
int l = 0;
for (int j = 0; j <= pm2; j++)
for (int i = 0; i + j <= pm2; i++)
{
l = j + ( 2 * p - 1 - i) * i / 2;
t_dof[o] = 3 * p + 2*l+1; s_dof[o] = 0; dof2tk[o] = 4;
const IntegrationPoint & t_ip0 = tn_n.IntPoint(t_dof[o]);
Nodes.IntPoint(o).Set3(t_ip0.x, t_ip0.y, s1_n.IntPoint(s_dof[o]).x);
o++;
t_dof[o] = 3 * p + 2*l; s_dof[o] = 0; dof2tk[o] = 0;
const IntegrationPoint & t_ip1 = tn_n.IntPoint(t_dof[o]);
Nodes.IntPoint(o).Set3(t_ip1.x, t_ip1.y, s1_n.IntPoint(s_dof[o]).x);
o++;
}
// (3,4,5) -- top
int m = 0;
for (int j = 0; j <= pm2; j++)
for (int i = 0; i + j <= pm2; i++)
{
t_dof[o] = 3 * p + m; s_dof[o] = 1; dof2tk[o] = 0; m++;
const IntegrationPoint & t_ip0 = tn_n.IntPoint(t_dof[o]);
Nodes.IntPoint(o).Set3(t_ip0.x, t_ip0.y, s1_n.IntPoint(s_dof[o]).x);
o++;
t_dof[o] = 3 * p + m; s_dof[o] = 1; dof2tk[o] = 4; m++;
const IntegrationPoint & t_ip1 = tn_n.IntPoint(t_dof[o]);
Nodes.IntPoint(o).Set3(t_ip1.x, t_ip1.y, s1_n.IntPoint(s_dof[o]).x);
o++;
}
// (0, 1, 4, 3) -- xz plane
for (int j = 2; j <= p; j++)
for (int i = 0; i < p; i++)
{
t_dof[o] = i; s_dof[o] = j; dof2tk[o] = 0;
const IntegrationPoint & t_ip = tn_n.IntPoint(t_dof[o]);
Nodes.IntPoint(o).Set3(t_ip.x, t_ip.y, s1_n.IntPoint(s_dof[o]).x);
o++;
}
for (int j = 0; j < p; j++)
for (int i = 0; i < pm1; i++)
{
t_dof[o] = 3 + i; s_dof[o] = j; dof2tk[o] = 3;
const IntegrationPoint & t_ip = t1_n.IntPoint(t_dof[o]);
Nodes.IntPoint(o).Set3(t_ip.x, t_ip.y, sn_n.IntPoint(s_dof[o]).x);
o++;
}
// (1, 2, 5, 4) -- (y-x)z plane
for (int j = 2; j <= p; j++)
for (int i = 0; i < p; i++)
{
t_dof[o] = p + i; s_dof[o] = j; dof2tk[o] = 1;
const IntegrationPoint & t_ip = tn_n.IntPoint(t_dof[o]);
Nodes.IntPoint(o).Set3(t_ip.x, t_ip.y, s1_n.IntPoint(s_dof[o]).x);
o++;
}
for (int j = 0; j < p; j++)
for (int i = 0; i < pm1; i++)
{
t_dof[o] = p + 2 + i; s_dof[o] = j; dof2tk[o] = 3;
const IntegrationPoint & t_ip = t1_n.IntPoint(t_dof[o]);
Nodes.IntPoint(o).Set3(t_ip.x, t_ip.y, sn_n.IntPoint(s_dof[o]).x);
o++;
}
// (2, 0, 3, 5) -- yz plane
for (int j = 2; j <= p; j++)
for (int i = 0; i < p; i++)
{
t_dof[o] = 2 * p + i; s_dof[o] = j; dof2tk[o] = 2;
const IntegrationPoint & t_ip = tn_n.IntPoint(t_dof[o]);
Nodes.IntPoint(o).Set3(t_ip.x, t_ip.y, s1_n.IntPoint(s_dof[o]).x);
o++;
}
for (int j = 0; j < p; j++)
for (int i = 0; i < pm1; i++)
{
t_dof[o] = 2 * p + 1 + i; s_dof[o] = j; dof2tk[o] = 3;
const IntegrationPoint & t_ip = t1_n.IntPoint(t_dof[o]);
Nodes.IntPoint(o).Set3(t_ip.x, t_ip.y, sn_n.IntPoint(s_dof[o]).x);
o++;
}
// interior
for (int k = 2; k <= p; k++)
{
l = 0;
for (int j = 0; j <= pm2; j++)
for (int i = 0; i + j <= pm2; i++)
{
t_dof[o] = 3 * p + l; s_dof[o] = k; dof2tk[o] = 0; l++;
const IntegrationPoint & t_ip0 = tn_n.IntPoint(t_dof[o]);
Nodes.IntPoint(o).Set3(t_ip0.x, t_ip0.y, s1_n.IntPoint(s_dof[o]).x);
o++;
t_dof[o] = 3 * p + l; s_dof[o] = k; dof2tk[o] = 4; l++;
const IntegrationPoint & t_ip1 = tn_n.IntPoint(t_dof[o]);
Nodes.IntPoint(o).Set3(t_ip1.x, t_ip1.y, s1_n.IntPoint(s_dof[o]).x);
o++;
}
}
for (int k = 0; k < p; k++)
{
l = 0;
for (int j = 0; j < pm2; j++)
for (int i = 0; i + j < pm2; i++)
{
t_dof[o] = 3 * p + l; s_dof[o] = k; dof2tk[o] = 3; l++;
const IntegrationPoint & t_ip = t1_n.IntPoint(t_dof[o]);
Nodes.IntPoint(o).Set3(t_ip.x, t_ip.y, sn_n.IntPoint(s_dof[o]).x);
o++;
}
}
}
void ND_WedgeElement::CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const
{
#ifdef MFEM_THREAD_SAFE
Vector t1_shape(H1TriangleFE.GetDof());
Vector s1_shape(H1SegmentFE.GetDof());
DenseMatrix tn_shape(NDTriangleFE.GetDof(), 2);
DenseMatrix sn_shape(NDSegmentFE.GetDof(), 1);
#endif
IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
H1TriangleFE.CalcShape(ip, t1_shape);
NDTriangleFE.CalcVShape(ip, tn_shape);
H1SegmentFE.CalcShape(ipz, s1_shape);
NDSegmentFE.CalcVShape(ipz, sn_shape);
for (int i=0; i<dof; i++)
{
if ( dof2tk[i] != 3 )
{
shape(i, 0) = tn_shape(t_dof[i], 0) * s1_shape[s_dof[i]];
shape(i, 1) = tn_shape(t_dof[i], 1) * s1_shape[s_dof[i]];
shape(i, 2) = 0.0;
}
else
{
shape(i, 0) = 0.0;
shape(i, 1) = 0.0;
shape(i, 2) = t1_shape[t_dof[i]] * sn_shape(s_dof[i], 0);
}
}
}
void ND_WedgeElement::CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const
{
#ifdef MFEM_THREAD_SAFE
Vector s1_shape(H1SegmentFE.GetDof());
DenseMatrix t1_dshape(H1TriangleFE.GetDof(), 2);
DenseMatrix s1_dshape(H1SegmentFE.GetDof(), 1);
DenseMatrix tn_shape(NDTriangleFE.GetDof(), 2);
DenseMatrix sn_shape(NDSegmentFE.GetDof(), 1);
DenseMatrix tn_dshape(NDTriangleFE.GetDof(), 1);
#endif
IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
H1TriangleFE.CalcDShape(ip, t1_dshape);
H1SegmentFE.CalcShape(ipz, s1_shape);
H1SegmentFE.CalcDShape(ipz, s1_dshape);
NDTriangleFE.CalcVShape(ip, tn_shape);
NDTriangleFE.CalcCurlShape(ip, tn_dshape);
NDSegmentFE.CalcVShape(ipz, sn_shape);
for (int i=0; i<dof; i++)
{
if ( dof2tk[i] != 3 )
{
curl_shape(i, 0) = -tn_shape(t_dof[i], 1) * s1_dshape(s_dof[i], 0);
curl_shape(i, 1) = tn_shape(t_dof[i], 0) * s1_dshape(s_dof[i], 0);
curl_shape(i, 2) = tn_dshape(t_dof[i], 0) * s1_shape[s_dof[i]];
}
else
{
curl_shape(i, 0) = t1_dshape(t_dof[i], 1) * sn_shape(s_dof[i], 0);
curl_shape(i, 1) = -t1_dshape(t_dof[i], 0) * sn_shape(s_dof[i], 0);
curl_shape(i, 2) = 0.0;
}
}
}
ND_R1D_PointElement::ND_R1D_PointElement(int p)
: VectorFiniteElement(1, 2, 0, Geometry::POINT, 2, p,
H_CURL, FunctionSpace::Pk)