Compare commits
185
Commits
bazel
...
hypsys-dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6497f4d829 | ||
|
|
3b533595b8 | ||
|
|
d21491f91e | ||
|
|
0a1f3a0b0a | ||
|
|
438a9968ce | ||
|
|
b1a343f514 | ||
|
|
a0a29e3303 | ||
|
|
a921f56177 | ||
|
|
2a6edf7d43 | ||
|
|
d6fa604631 | ||
|
|
3add636a18 | ||
|
|
21000a319e | ||
|
|
95703e3a6d | ||
|
|
39dfcac5b3 | ||
|
|
45b618fab2 | ||
|
|
22838a13af | ||
|
|
ee58c6828a | ||
|
|
b50b0c0ac1 | ||
|
|
6c40560766 | ||
|
|
cadc4516ef | ||
|
|
bb584f04f8 | ||
|
|
cec500bb11 | ||
|
|
a88917276a | ||
|
|
2227958c30 | ||
|
|
8c0d8c3708 | ||
|
|
d9c7e28444 | ||
|
|
5dd725f5f0 | ||
|
|
9405bc04b3 | ||
|
|
6ddaa46fc2 | ||
|
|
4400dc08ae | ||
|
|
e90095d854 | ||
|
|
c1154025e3 | ||
|
|
fcfe3c8353 | ||
|
|
143da8287a | ||
|
|
23d0f0b637 | ||
|
|
08af14793b | ||
|
|
6b6b871999 | ||
|
|
02d9c69c0d | ||
|
|
efd7aa8686 | ||
|
|
4abec105c3 | ||
|
|
723f891e37 | ||
|
|
889a7598f4 | ||
|
|
6a76844b4f | ||
|
|
d8550d7309 | ||
|
|
a86534bba6 | ||
|
|
a01a4ace7a | ||
|
|
070cdb3c6a | ||
|
|
13818643c1 | ||
|
|
61f60d2f88 | ||
|
|
3c1cf15c04 | ||
|
|
6624e2250c | ||
|
|
eff0a9c79f | ||
|
|
b814cf96d5 | ||
|
|
5ff5022af3 | ||
|
|
3623bd2994 | ||
|
|
cccbb11057 | ||
|
|
0de495cc3c | ||
|
|
c95db258bd | ||
|
|
2aa2759192 | ||
|
|
1fa4323498 | ||
|
|
fde74a329b | ||
|
|
319d4e7f05 | ||
|
|
ecb9d77a29 | ||
|
|
c7d5ee2654 | ||
|
|
a0e0c15913 | ||
|
|
4fda37f739 | ||
|
|
7b5e078731 | ||
|
|
7511d65aa9 | ||
|
|
18adf880d7 | ||
|
|
8df51cbc3f | ||
|
|
a8634a7fa0 | ||
|
|
0541c74f08 | ||
|
|
95f77d6c9a | ||
|
|
f469d54afa | ||
|
|
b4951bd02d | ||
|
|
f5137a5eed | ||
|
|
9ad28ce2c8 | ||
|
|
92aa5d65e2 | ||
|
|
d4c7b609b1 | ||
|
|
3c53e9a9c5 | ||
|
|
fb9726d4f8 | ||
|
|
84bdebeb8c | ||
|
|
8448b32bb1 | ||
|
|
5bf4712efd | ||
|
|
1d571c04a8 | ||
|
|
4aec552eeb | ||
|
|
a9c9808b49 | ||
|
|
0aff563810 | ||
|
|
a3ce5422d9 | ||
|
|
2f3010f2f0 | ||
|
|
b4dd6b5997 | ||
|
|
a739bcd2f8 | ||
|
|
ffbe7710b9 | ||
|
|
22a9fa0892 | ||
|
|
45ca17f09c | ||
|
|
3014937c08 | ||
|
|
c29c742a29 | ||
|
|
2e0d1d89bc | ||
|
|
c35ad8f18a | ||
|
|
2d289a1a0a | ||
|
|
53634954d6 | ||
|
|
b880107442 | ||
|
|
a25fbaa530 | ||
|
|
17c653afae | ||
|
|
3567ff10af | ||
|
|
f2b1c68fd3 | ||
|
|
a996e039a0 | ||
|
|
c2f300a13b | ||
|
|
a63c2adeac | ||
|
|
c14d057b33 | ||
|
|
268dabe5b3 | ||
|
|
89adf31fa9 | ||
|
|
1818159e6e | ||
|
|
39c4b2c6eb | ||
|
|
26f28aef94 | ||
|
|
14ff697e6d | ||
|
|
0024f03b36 | ||
|
|
7cf631f2ae | ||
|
|
bf6660abe7 | ||
|
|
aab7cbd0ba | ||
|
|
5e04c9e759 | ||
|
|
78deadd0b2 | ||
|
|
c88d99a660 | ||
|
|
ef5e133a06 | ||
|
|
97e2e04ef1 | ||
|
|
1c87d3aec9 | ||
|
|
5944bc1e98 | ||
|
|
a92b985363 | ||
|
|
a71d9f4aa2 | ||
|
|
438f5cd0f1 | ||
|
|
ccee9d48ba | ||
|
|
f7d2aad9dd | ||
|
|
420af6dacd | ||
|
|
0e05495bad | ||
|
|
d70fe9904e | ||
|
|
2591ff1f61 | ||
|
|
77407972c0 | ||
|
|
8e3dda40eb | ||
|
|
fcc0bcbd4c | ||
|
|
c60edb07f4 | ||
|
|
6cdf650c44 | ||
|
|
85651b4737 | ||
|
|
055d9f1052 | ||
|
|
7b92942e96 | ||
|
|
679739b1e3 | ||
|
|
7abd2a94e8 | ||
|
|
1f119edde1 | ||
|
|
ad86262437 | ||
|
|
07497cae07 | ||
|
|
c617b3afd4 | ||
|
|
bc27a94112 | ||
|
|
460492012e | ||
|
|
bc258e1d94 | ||
|
|
e0b0472bf2 | ||
|
|
71855ba554 | ||
|
|
229fe92b41 | ||
|
|
2b8cf51e09 | ||
|
|
bfffa918f7 | ||
|
|
a40bd2f790 | ||
|
|
b2382119da | ||
|
|
7995844fb9 | ||
|
|
5225e2dea3 | ||
|
|
0ba34e52e3 | ||
|
|
baaddcf782 | ||
|
|
ab2251197f | ||
|
|
3f9dc61322 | ||
|
|
421f43f6ec | ||
|
|
101cb10b18 | ||
|
|
265aa483ca | ||
|
|
d685787c50 | ||
|
|
0741c02a38 | ||
|
|
eb3c078e94 | ||
|
|
50c56fdc83 | ||
|
|
35331da9c9 | ||
|
|
3fc885ed73 | ||
|
|
d09d927b86 | ||
|
|
32b67c327c | ||
|
|
39827e802f | ||
|
|
cac649144f | ||
|
|
7903b11b9b | ||
|
|
8d17794793 | ||
|
|
175c47d8ff | ||
|
|
f3bdd37ecf | ||
|
|
5e943f7998 | ||
|
|
43555a801d |
+14
@@ -163,6 +163,20 @@ miniapps/electromagnetics/Tesla-AMR*
|
||||
miniapps/electromagnetics/Maxwell-Parallel*
|
||||
miniapps/electromagnetics/Joule_*
|
||||
|
||||
miniapps/hypsys/build
|
||||
miniapps/hypsys/errors.txt
|
||||
miniapps/hypsys/grid*
|
||||
miniapps/hypsys/hypsys
|
||||
miniapps/hypsys/initial*
|
||||
miniapps/hypsys/output
|
||||
miniapps/hypsys/phypsys
|
||||
miniapps/hypsys/pressure*
|
||||
miniapps/hypsys/results
|
||||
miniapps/hypsys/scripts/gridfunc-scatter
|
||||
miniapps/hypsys/ultimate*
|
||||
miniapps/hypsys/velocity*
|
||||
miniapps/hypsys/various
|
||||
|
||||
miniapps/meshing/mobius-strip
|
||||
miniapps/meshing/klein-bottle
|
||||
miniapps/meshing/toroid
|
||||
|
||||
+8
-1
@@ -254,7 +254,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
// 5. Define the discontinuous DG finite element space of the given
|
||||
// polynomial order on the refined mesh.
|
||||
DG_FECollection fec(order, dim, BasisType::GaussLobatto);
|
||||
DG_FECollection fec(order, dim, BasisType::Positive);
|
||||
FiniteElementSpace fes(&mesh, &fec);
|
||||
|
||||
cout << "Number of unknowns: " << fes.GetVSize() << endl;
|
||||
@@ -378,6 +378,10 @@ int main(int argc, char *argv[])
|
||||
// iterations, ti, with a time-step dt).
|
||||
FE_Evolution adv(m, k, b);
|
||||
|
||||
Vector masses(u.Size());
|
||||
m.SpMat().Mult(u, masses);
|
||||
double mass = masses.Sum();
|
||||
|
||||
double t = 0.0;
|
||||
adv.SetTime(t);
|
||||
ode_solver->Init(adv);
|
||||
@@ -424,6 +428,9 @@ int main(int argc, char *argv[])
|
||||
u.Save(osol);
|
||||
}
|
||||
|
||||
m.SpMat().Mult(u, masses);
|
||||
cout << "Mass difference:" << abs(mass - masses.Sum()) << endl;
|
||||
|
||||
// 10. Free the used memory.
|
||||
delete ode_solver;
|
||||
delete pd;
|
||||
|
||||
+2
-2
@@ -2984,7 +2984,7 @@ double GridFunction::ComputeLpError(const double p, Coefficient &exsol,
|
||||
}
|
||||
else
|
||||
{
|
||||
int intorder = 2*fe->GetOrder() + 3; // <----------
|
||||
int intorder = 2*fe->GetOrder() + 1; // <----------
|
||||
ir = &(IntRules.Get(fe->GetGeomType(), intorder));
|
||||
}
|
||||
GetValues(i, *ir, vals);
|
||||
@@ -3117,7 +3117,7 @@ double GridFunction::ComputeLpError(const double p, VectorCoefficient &exsol,
|
||||
}
|
||||
else
|
||||
{
|
||||
int intorder = 2*fe->GetOrder() + 3; // <----------
|
||||
int intorder = 2*fe->GetOrder() + 1; // <----------
|
||||
ir = &(IntRules.Get(fe->GetGeomType(), intorder));
|
||||
}
|
||||
T = fes->GetElementTransformation(i);
|
||||
|
||||
@@ -0,0 +1,371 @@
|
||||
#include "advection.hpp"
|
||||
|
||||
Configuration ConfigAdv;
|
||||
|
||||
void AnalyticalSolutionAdv(const Vector &x, double t, Vector &u);
|
||||
void InitialConditionAdv(const Vector &x, Vector &u);
|
||||
void InflowFunctionAdv(const Vector &x, double t, Vector &u);
|
||||
void VelocityFunctionAdv(const Vector &x, Vector &v);
|
||||
|
||||
Advection::Advection(FiniteElementSpace *fes_, BlockVector &u_block,
|
||||
Configuration &config_, bool NodalQuadRule)
|
||||
: HyperbolicSystem(fes_, u_block, 1, config_,
|
||||
VectorFunctionCoefficient (1, InflowFunctionAdv))
|
||||
{
|
||||
DiscreteUpwinding = true;
|
||||
|
||||
ConfigAdv = config_;
|
||||
VectorFunctionCoefficient ic(NumEq, InitialConditionAdv);
|
||||
|
||||
switch (ConfigAdv.ConfigNum)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
ProblemName = "Advection - Smooth Circular Convection";
|
||||
glvis_scale = "on";
|
||||
SolutionKnown = true;
|
||||
SteadyState = true;
|
||||
TimeDepBC = false;
|
||||
ProjType = 0;
|
||||
L2_Projection(ic, u0);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
ProblemName = "Advection - Solid Body Rotation";
|
||||
glvis_scale = "on";
|
||||
SolutionKnown = true;
|
||||
SteadyState = false;
|
||||
TimeDepBC = false;
|
||||
ProjType = 1;
|
||||
u0.ProjectCoefficient(ic);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
ProblemName = "Advection - Step function";
|
||||
glvis_scale = "on";
|
||||
SolutionKnown = true;
|
||||
SteadyState = false;
|
||||
TimeDepBC = false;
|
||||
ProjType = 1;
|
||||
u0.ProjectCoefficient(ic);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
ProblemName = "Advection - Smooth profile";
|
||||
glvis_scale = "on";
|
||||
SolutionKnown = true;
|
||||
SteadyState = false;
|
||||
TimeDepBC = false;
|
||||
ProjType = 0;
|
||||
L2_Projection(ic, u0);;
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
ProblemName = "Advection - Discontinuous and Smooth profile";
|
||||
glvis_scale = "on";
|
||||
SolutionKnown = true;
|
||||
SteadyState = false;
|
||||
TimeDepBC = false;
|
||||
ProjType = 1;
|
||||
u0.ProjectCoefficient(ic);
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
ProblemName = "Advection - C1 curve";
|
||||
glvis_scale = "on";
|
||||
SolutionKnown = true;
|
||||
SteadyState = false;
|
||||
TimeDepBC = false;
|
||||
ProjType = 1;
|
||||
u0.ProjectCoefficient(ic);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MFEM_ABORT("No such test case implemented.");
|
||||
}
|
||||
|
||||
// The following computes and stores all necessary evaluations of the time-independent velocity.
|
||||
Mesh *mesh = fes->GetMesh();
|
||||
DofInfo dofs(fes);
|
||||
const int ne = fes->GetNE();
|
||||
const IntegrationRule *IntRuleElem = GetElementIntegrationRule(fes);
|
||||
const IntegrationRule *IntRuleFace = GetFaceIntegrationRule(fes);
|
||||
const IntegrationRule *nodes = GetElementIntegrationRule(fes, true);
|
||||
|
||||
const int nqe = IntRuleElem->GetNPoints();
|
||||
nqf = IntRuleFace->GetNPoints();
|
||||
Vector vec, vval;
|
||||
VelocityVector.SetSize(dim);
|
||||
DenseMatrix VelEval, mat(dim, nqe);
|
||||
|
||||
VelElem.SetSize(dim, nqe, ne);
|
||||
VelFace.SetSize(dim, dofs.NumBdrs, ne*nqf);
|
||||
VelNode.SetSize(dim, nd, ne);
|
||||
VectorFunctionCoefficient velocity(dim, VelocityFunctionAdv);
|
||||
|
||||
Array<int> bdrs, orientation;
|
||||
Array<IntegrationPoint> eip(nqf*dofs.NumBdrs);
|
||||
|
||||
if (dim==1) { mesh->GetElementVertices(0, bdrs); }
|
||||
else if (dim==2) { mesh->GetElementEdges(0, bdrs, orientation); }
|
||||
else if (dim==3) { mesh->GetElementFaces(0, bdrs, orientation); }
|
||||
|
||||
for (int i = 0; i < dofs.NumBdrs; i++)
|
||||
{
|
||||
FaceElementTransformations *help
|
||||
= mesh->GetFaceElementTransformations(bdrs[i]);
|
||||
|
||||
if (help->Elem1No != 0)
|
||||
{
|
||||
// NOTE: If this error ever occurs, use neighbor element to
|
||||
// obtain the correct quadrature points and weight.
|
||||
MFEM_ABORT("First element has inward pointing normal.");
|
||||
}
|
||||
for (int k = 0; k < nqf; k++)
|
||||
{
|
||||
const IntegrationPoint &ip = IntRuleFace->IntPoint(k);
|
||||
help->Loc1.Transform(ip, eip[i*nqf + k]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int e = 0; e < ne; e++)
|
||||
{
|
||||
ElementTransformation *eltrans = fes->GetElementTransformation(e);
|
||||
velocity.Eval(VelEval, *eltrans, *IntRuleElem);
|
||||
|
||||
for (int k = 0; k < nqe; k++)
|
||||
{
|
||||
VelEval.GetColumnReference(k, vec);
|
||||
mat.SetCol(k, vec);
|
||||
}
|
||||
|
||||
VelElem(e) = mat;
|
||||
|
||||
for (int i = 0; i < nd; i++)
|
||||
{
|
||||
const IntegrationPoint ip = nodes->IntPoint(i);
|
||||
velocity.Eval(vec, *eltrans, ip);
|
||||
VelNode(e).SetCol(i, vec);
|
||||
}
|
||||
|
||||
if (dim==1) { mesh->GetElementVertices(e, bdrs); }
|
||||
else if (dim==2) { mesh->GetElementEdges(e, bdrs, orientation); }
|
||||
else if (dim==3) { mesh->GetElementFaces(e, bdrs, orientation); }
|
||||
|
||||
for (int i = 0; i < dofs.NumBdrs; i++)
|
||||
{
|
||||
FaceElementTransformations *facetrans
|
||||
= mesh->GetFaceElementTransformations(bdrs[i]);
|
||||
|
||||
for (int k = 0; k < nqf; k++)
|
||||
{
|
||||
if (facetrans->Elem1No != e)
|
||||
{
|
||||
velocity.Eval(vval, *facetrans->Elem2, eip[i * nqf + k]);
|
||||
}
|
||||
else
|
||||
{
|
||||
velocity.Eval(vval, *facetrans->Elem1, eip[i * nqf + k]);
|
||||
}
|
||||
|
||||
for (int l = 0; l < dim; l++)
|
||||
{
|
||||
VelFace(l, i, e * nqf + k) = vval(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Advection::EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
|
||||
int e, int k, int i) const
|
||||
{
|
||||
Vector x(dim), v(dim);
|
||||
VelocityFunctionAdv(x, v);
|
||||
v *= u(0);
|
||||
FluxEval.SetRow(0, v);
|
||||
if (i == -1) // Element terms
|
||||
{
|
||||
VelocityVector = VelElem(e).GetColumn(k);
|
||||
VelocityVector *= u(0);
|
||||
FluxEval.SetRow(0, VelocityVector);
|
||||
}
|
||||
else
|
||||
{
|
||||
VelocityVector = VelFace(e*nqf+k).GetColumn(i);
|
||||
VelocityVector *= u(0);
|
||||
FluxEval.SetRow(0, VelocityVector);
|
||||
}
|
||||
}
|
||||
|
||||
double Advection::GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
|
||||
int i) const
|
||||
{
|
||||
if (i == -1) // Element terms
|
||||
{
|
||||
VelocityVector = VelElem(e).GetColumn(k);
|
||||
}
|
||||
else
|
||||
{
|
||||
VelocityVector = VelFace(e*nqf+k).GetColumn(i);
|
||||
}
|
||||
|
||||
return abs(VelocityVector * n);
|
||||
}
|
||||
|
||||
void Advection::ComputeErrors(Array<double> &errors, const GridFunction &u,
|
||||
double DomainSize, double t) const
|
||||
{
|
||||
errors.SetSize(3);
|
||||
VectorFunctionCoefficient uAnalytic(NumEq, AnalyticalSolutionAdv);
|
||||
uAnalytic.SetTime(t);
|
||||
errors[0] = u.ComputeLpError(1., uAnalytic) / DomainSize;
|
||||
errors[1] = u.ComputeLpError(2., uAnalytic) / DomainSize;
|
||||
errors[2] = u.ComputeLpError(numeric_limits<double>::infinity(), uAnalytic);
|
||||
}
|
||||
|
||||
|
||||
void VelocityFunctionAdv(const Vector &x, Vector &v)
|
||||
{
|
||||
const int dim = x.Size();
|
||||
Vector X(dim);
|
||||
double s = 1.0;
|
||||
|
||||
for (int i = 0; i < dim; i++)
|
||||
{
|
||||
switch (ConfigAdv.ConfigNum)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 4:
|
||||
case 5: // Map to the reference domain [0,1]^d.
|
||||
{
|
||||
X(i) = (x(i) - ConfigAdv.bbMin(i)) / (ConfigAdv.bbMax(i) - ConfigAdv.bbMin(i));
|
||||
s *= ConfigAdv.bbMax(i) - ConfigAdv.bbMin(i);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
case 3: // Map to the reference domain [-1,1]^d.
|
||||
{
|
||||
double center = 0.5 * (ConfigAdv.bbMin(i) + ConfigAdv.bbMax(i));
|
||||
X(i) = 2. * (x(i) - center) / (ConfigAdv.bbMax(i) - ConfigAdv.bbMin(i));
|
||||
s *= ConfigAdv.bbMax(i) - ConfigAdv.bbMin(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scale to be normed to a full revolution.
|
||||
s = pow(s, 1./dim);
|
||||
|
||||
switch (ConfigAdv.ConfigNum)
|
||||
{
|
||||
case 0: // Rotation around corner.
|
||||
{
|
||||
switch (dim)
|
||||
{
|
||||
case 1: v(0) = s; break;
|
||||
case 2: s *= 2.0 * M_PI; v(0) = s*X(1); v(1) = -s*X(0); break;
|
||||
case 3: s *= 2.0 * M_PI; v(0) = s*X(1); v(1) = -s*X(0); v(2) = 0.0; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1: // Rotation around center.
|
||||
{
|
||||
switch (dim)
|
||||
{
|
||||
case 1: v(0) = s; break;
|
||||
case 2: s *= 2.0 * M_PI; v(0) = s * (0.5-X(1)); v(1) = s*(X(0)-0.5); break;
|
||||
case 3: s *= 2.0 * M_PI; v(0) = s * (0.5-X(1)); v(1) = s*(X(0)-0.5); v(2) = 0.0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
{
|
||||
switch (dim)
|
||||
{
|
||||
case 1: v(0) = s; break;
|
||||
case 2: v(0) = s; v(1) = -0.5*s; break;
|
||||
case 3: v(0) = s; v(1) = -0.5*s; v(2) = 0.25*s; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnalyticalSolutionAdv(const Vector &x, double t, Vector &u)
|
||||
{
|
||||
const int dim = x.Size();
|
||||
Vector X(dim);
|
||||
|
||||
for (int i = 0; i < dim; i++)
|
||||
{
|
||||
switch (ConfigAdv.ConfigNum)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 4:
|
||||
case 5: // Map to the reference domain [0,1]^d.
|
||||
{
|
||||
X(i) = (x(i) - ConfigAdv.bbMin(i)) / (ConfigAdv.bbMax(i) - ConfigAdv.bbMin(i));
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
case 3: // Map to the reference domain [-1,1]^d.
|
||||
{
|
||||
double center = 0.5 * (ConfigAdv.bbMin(i) + ConfigAdv.bbMax(i));
|
||||
X(i) = 2.0 * (x(i) - center) / (ConfigAdv.bbMax(i) - ConfigAdv.bbMin(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double r = X.Norml2();
|
||||
|
||||
switch (ConfigAdv.ConfigNum)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
double a = 0.5, b = 0.03, c = 0.1;
|
||||
u(0) = 0.25 * (1. + tanh((r+c-a)/b)) * (1. - tanh((r-c-a)/b));
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (dim==1) { MFEM_ABORT("Test case not implemented in 1D."); }
|
||||
|
||||
double s = 0.15;
|
||||
double cone = sqrt(pow(X(0)-0.5, 2.) + pow(X(1)-0.25, 2.));
|
||||
double hump = sqrt(pow(X(0)-0.25, 2.) + pow(X(1)-0.5, 2.));
|
||||
|
||||
u(0) = (1. - cone / s) * (cone <= s) +
|
||||
0.25 * (1. + cos(M_PI*hump / s)) * (hump <= s) +
|
||||
( ( sqrt(pow(X(0)-0.5, 2.) + pow(X(1)-0.75, 2.)) <= s ) &&
|
||||
( abs(X(0)-0.5) >= 0.025 || (X(1) >= 0.85) ) ? 1. : 0. );
|
||||
break;
|
||||
}
|
||||
case 2: { u(0) = r < 0.2 ? 1. : 0.; break; }
|
||||
case 3: { u(0) = exp(-25.0 * r*r); break; }
|
||||
case 4: { u(0) = abs(r - 0.3) < 0.1 ? 1. : ( (abs(r-0.7) < 0.2) ? (exp(10.)*exp(-1./(r-0.5))*exp(1./(r-0.9))) : 0. ); break; }
|
||||
case 5: { u(0) = abs(r-0.25) <= 0.15 ? 0.5*(1.+cos(M_PI*(r-0.25)/0.15)) : 0.; break; }
|
||||
}
|
||||
}
|
||||
|
||||
void InitialConditionAdv(const Vector &x, Vector &u)
|
||||
{
|
||||
AnalyticalSolutionAdv(x, 0.0, u);
|
||||
}
|
||||
|
||||
void InflowFunctionAdv(const Vector &x, double t, Vector &u)
|
||||
{
|
||||
AnalyticalSolutionAdv(x, t, u);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef HYPSYS_ADVECTION
|
||||
#define HYPSYS_ADVECTION
|
||||
|
||||
#include "hyperbolic_system.hpp"
|
||||
#include "../lib/dofs.hpp"
|
||||
|
||||
class Advection : public HyperbolicSystem
|
||||
{
|
||||
public:
|
||||
explicit Advection(FiniteElementSpace *fes_, BlockVector &u_block,
|
||||
Configuration &config_, bool NodalQuadRule);
|
||||
~Advection() { };
|
||||
|
||||
virtual void EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
|
||||
int e, int k, int i = -1) const;
|
||||
virtual double GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
|
||||
int i) const;
|
||||
virtual void ComputeErrors(Array<double> &errors, const GridFunction &u,
|
||||
double DomainSize, double t) const override;
|
||||
|
||||
int nqf;
|
||||
DenseTensor VelElem, VelFace;
|
||||
mutable Vector VelocityVector;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,118 @@
|
||||
#include "buckley_leverett.hpp"
|
||||
|
||||
Configuration ConfigBL;
|
||||
double BLConst;
|
||||
|
||||
void InitialConditionBuckleyLeverett(const Vector &x, Vector &u);
|
||||
void InflowFunctionBuckleyLeverett(const Vector &x, double t, Vector &u);
|
||||
|
||||
BuckleyLeverett::BuckleyLeverett(FiniteElementSpace *fes_, BlockVector &u_block,
|
||||
Configuration &config_)
|
||||
: HyperbolicSystem(fes_, u_block, 1, config_,
|
||||
VectorFunctionCoefficient(1, InflowFunctionBuckleyLeverett))
|
||||
{
|
||||
ConfigBL = config_;
|
||||
VectorFunctionCoefficient ic(NumEq, InitialConditionBuckleyLeverett);
|
||||
|
||||
switch (ConfigBL.ConfigNum)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
ProblemName = "Buckley-Leverett - 1D";
|
||||
glvis_scale = "on";
|
||||
BLConst = 0.5;
|
||||
SolutionKnown = false;
|
||||
SteadyState = false;
|
||||
TimeDepBC = false;
|
||||
ProjType = 0;
|
||||
L2_Projection(ic, u0);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
ProblemName = "Buckley-Leverett - 2D";
|
||||
glvis_scale = "on";
|
||||
BLConst = 1.0;
|
||||
SolutionKnown = false;
|
||||
SteadyState = false;
|
||||
TimeDepBC = false;
|
||||
ProjType = 1;
|
||||
u0.ProjectCoefficient(ic);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MFEM_ABORT("No such test case implemented.");
|
||||
}
|
||||
}
|
||||
|
||||
void BuckleyLeverett::EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
|
||||
int e, int k, int i) const
|
||||
{
|
||||
double coef = u(0)*u(0) / (u(0)*u(0) + BLConst * (1.0-u(0))*(1.0-u(0)));
|
||||
FluxEval(0,0) = coef;
|
||||
if (dim > 1)
|
||||
{
|
||||
FluxEval(0,1) = coef * (1.0 - 5.0 * (1.0-u(0))*(1.0-u(0)));
|
||||
}
|
||||
if (dim > 2) { MFEM_ABORT("Not implemented."); }
|
||||
}
|
||||
|
||||
double BuckleyLeverett::GetWaveSpeed(const Vector &u, const Vector n, int e,
|
||||
int k,
|
||||
int i) const
|
||||
{
|
||||
if (dim == 1)
|
||||
{
|
||||
return abs( 2.0 * BLConst * u(0) * (1.0-u(0)) / pow(u(0)*u(0) + BLConst *
|
||||
(1.0-u(0))*(1.0-u(0)), 2.0) );
|
||||
}
|
||||
else if (dim == 2)
|
||||
{
|
||||
return 3.4;
|
||||
}
|
||||
else { MFEM_ABORT("Not implemented."); }
|
||||
}
|
||||
|
||||
void InitialConditionBuckleyLeverett(const Vector &x, Vector &u)
|
||||
{
|
||||
const int dim = x.Size();
|
||||
|
||||
// Map to the reference domain [-1,1]^d.
|
||||
Vector X(dim);
|
||||
for (int i = 0; i < dim; i++)
|
||||
{
|
||||
double center = 0.5 * (ConfigBL.bbMin(i) + ConfigBL.bbMax(i));
|
||||
X(i) = 2. * (x(i) - center) / (ConfigBL.bbMax(i) - ConfigBL.bbMin(i));
|
||||
}
|
||||
|
||||
switch (ConfigBL.ConfigNum)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
u(0) = X(0) < 0.0 ? -3.0 : 3.0;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
u(0) = X.Norml2()*X.Norml2() < 2.0 / 9.0 ? 1.0 : 0.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InflowFunctionBuckleyLeverett(const Vector &x, double t, Vector &u)
|
||||
{
|
||||
switch (ConfigBL.ConfigNum)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
u(0) = x(0) < 0.0 ? 3.0 : -3.0;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
u(0) = 0.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef HYPSYS_BUCKLEYLEVERETT
|
||||
#define HYPSYS_BUCKLEYLEVERETT
|
||||
|
||||
#include "hyperbolic_system.hpp"
|
||||
|
||||
class BuckleyLeverett : public HyperbolicSystem
|
||||
{
|
||||
public:
|
||||
explicit BuckleyLeverett(FiniteElementSpace *fes_, BlockVector &u_block,
|
||||
Configuration &config_);
|
||||
~BuckleyLeverett() { };
|
||||
|
||||
virtual void EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
|
||||
int e, int k, int i = -1) const;
|
||||
virtual double GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
|
||||
int i) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,175 @@
|
||||
#include "burgers.hpp"
|
||||
|
||||
Configuration ConfigBurgers;
|
||||
|
||||
void AnalyticalSolutionBurgers(const Vector &x, double t, Vector &u);
|
||||
void InitialConditionBurgers(const Vector &x, Vector &u);
|
||||
void InflowFunctionBurgers(const Vector &x, double t, Vector &u);
|
||||
|
||||
Burgers::Burgers(FiniteElementSpace *fes_, BlockVector &u_block,
|
||||
Configuration &config_)
|
||||
: HyperbolicSystem(fes_, u_block, 1, config_,
|
||||
VectorFunctionCoefficient (1, InflowFunctionBurgers))
|
||||
{
|
||||
ConfigBurgers = config_;
|
||||
VectorFunctionCoefficient ic(NumEq, InitialConditionBurgers);
|
||||
|
||||
switch (ConfigBurgers.ConfigNum)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
ProblemName = "Burgers Equation - 1D";
|
||||
glvis_scale = "on";
|
||||
SolutionKnown = true;
|
||||
SteadyState = false;
|
||||
TimeDepBC = false;
|
||||
ProjType = 1;
|
||||
L2_Projection(ic, u0);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
ProblemName = "Burgers Equation - Riemann Problem";
|
||||
glvis_scale = "on";
|
||||
SolutionKnown = true;
|
||||
SteadyState = false;
|
||||
TimeDepBC = true;
|
||||
ProjType = 1;
|
||||
L2_Projection(ic, u0);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
ProblemName = "Burgers Equation - Steady State";
|
||||
glvis_scale = "on";
|
||||
SolutionKnown = true;
|
||||
SteadyState = true;
|
||||
TimeDepBC = false;
|
||||
ProjType = 1;
|
||||
u0.ProjectCoefficient(ic);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MFEM_ABORT("No such test case implemented.");
|
||||
}
|
||||
}
|
||||
|
||||
void Burgers::EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
|
||||
int e, int k, int i) const
|
||||
{
|
||||
FluxEval = 0.5 * u(0) * u(0);
|
||||
}
|
||||
|
||||
double Burgers::GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
|
||||
int i) const
|
||||
{
|
||||
return abs(u(0) * double(n.Size()));
|
||||
}
|
||||
|
||||
void Burgers::ComputeErrors(Array<double> &errors, const GridFunction &u,
|
||||
double DomainSize, double t) const
|
||||
{
|
||||
errors.SetSize(3);
|
||||
VectorFunctionCoefficient uAnalytic(NumEq, AnalyticalSolutionBurgers);
|
||||
uAnalytic.SetTime(t);
|
||||
errors[0] = u.ComputeLpError(1., uAnalytic) / DomainSize;
|
||||
errors[1] = u.ComputeLpError(2., uAnalytic) / DomainSize;
|
||||
errors[2] = u.ComputeLpError(numeric_limits<double>::infinity(), uAnalytic);
|
||||
}
|
||||
|
||||
|
||||
void AnalyticalSolutionBurgers(const Vector &x, double t, Vector &u)
|
||||
{
|
||||
const int dim = x.Size();
|
||||
Vector X(dim);
|
||||
|
||||
// Map to the reference domain [0,1]^d.
|
||||
for (int i = 0; i < dim; i++)
|
||||
{
|
||||
double factor = 1.0 / ( ConfigBurgers.bbMax(i) - ConfigBurgers.bbMin(i));
|
||||
X(i) = factor * (x(i) - ConfigBurgers.bbMin(i));
|
||||
t *= pow(factor, 1.0 / (double(dim)));
|
||||
}
|
||||
|
||||
switch (ConfigBurgers.ConfigNum)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if (dim != 1) { MFEM_ABORT("Test case only implemented in 1D."); }
|
||||
|
||||
double un = sin(2.0*M_PI*X(0));
|
||||
double fn, fpn;
|
||||
double tol = 1.E-15;
|
||||
double error = 1.0;
|
||||
int iter = 0, maxiter = 100;
|
||||
|
||||
while (error > tol)
|
||||
{
|
||||
// Do not trust this solution at a time later than t = 0.1.
|
||||
if (iter == maxiter) { break; }
|
||||
|
||||
fn = sin(2.0*M_PI*(X(0)-un*t))-un;
|
||||
fpn = -2.0*M_PI*t*cos(2.*M_PI*(X(0)-un*t))-1.0;
|
||||
un -= fn/fpn;
|
||||
error = abs(sin(2.*M_PI*(X(0)-un*t))-un);
|
||||
iter++;
|
||||
}
|
||||
|
||||
u(0) = un;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (dim != 2) { MFEM_ABORT("Test case only implemented in 2D."); }
|
||||
|
||||
if (X(0) <= 0.5 - 0.6 * t)
|
||||
{
|
||||
u(0) = X(1) >= 0.5 + 0.15 * t ? -0.2 : 0.5;
|
||||
}
|
||||
else if (X(0) < 0.5 - 0.25 * t)
|
||||
{
|
||||
u(0) = X(1) > -8. / 7. * X(0) + 15. / 14. - 15. / 28. * t ? -1. : 0.5;
|
||||
}
|
||||
else if (X(0) < 0.5 + 0.5 * t)
|
||||
{
|
||||
u(0) = X(1) > X(0) / 6. + 5. / 12. - 5. / 24. * t ? -1. : 0.5;
|
||||
}
|
||||
else if (X(0) < 0.5 + 0.8 * t)
|
||||
{
|
||||
u(0) = X(1) > X(0) - 5. / (18. * t) * (X(0) + t - 0.5)
|
||||
* (X(0) + t - 0.5) ? -1. : (2. * X(0) - 1.) / (2 * t);
|
||||
}
|
||||
else
|
||||
{
|
||||
u(0) = X(1) >= 0.5 - 0.1 * t ? -1 : 0.8;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
u(0) = X.Sum() < 0.5 ? 1.0 : -1.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InitialConditionBurgers(const Vector &x,Vector &u)
|
||||
{
|
||||
switch (ConfigBurgers.ConfigNum)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2: { AnalyticalSolutionBurgers(x, 0.0, u); break; }
|
||||
}
|
||||
}
|
||||
|
||||
void InflowFunctionBurgers(const Vector &x, double t, Vector &u)
|
||||
{
|
||||
switch (ConfigBurgers.ConfigNum)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2: { AnalyticalSolutionBurgers(x, t, u); break; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef HYPSYS_BURGERS
|
||||
#define HYPSYS_BURGERS
|
||||
|
||||
#include "hyperbolic_system.hpp"
|
||||
|
||||
class Burgers : public HyperbolicSystem
|
||||
{
|
||||
public:
|
||||
explicit Burgers(FiniteElementSpace *fes_, BlockVector &u_block,
|
||||
Configuration &config_);
|
||||
~Burgers() { };
|
||||
|
||||
virtual void EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
|
||||
int e, int k, int i = -1) const;
|
||||
virtual double GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
|
||||
int i) const;
|
||||
virtual void ComputeErrors(Array<double> &errors, const GridFunction &u,
|
||||
double DomainSize, double t) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,647 @@
|
||||
#include "euler.hpp"
|
||||
|
||||
Configuration ConfigEuler;
|
||||
|
||||
double SpHeatRatio;
|
||||
|
||||
void AnalyticalSolutionEuler(const Vector &x, double t, Vector &u);
|
||||
void InitialConditionEuler(const Vector &x, Vector &u);
|
||||
void InflowFunctionEuler(const Vector &x, double t, Vector &u);
|
||||
|
||||
Euler::Euler(FiniteElementSpace *fes_, BlockVector &u_block,
|
||||
Configuration &config_)
|
||||
: HyperbolicSystem(fes_, u_block, fes_->GetMesh()->Dimension() + 2, config_,
|
||||
VectorFunctionCoefficient(fes_->GetMesh()->Dimension() + 2,
|
||||
InflowFunctionEuler))
|
||||
{
|
||||
ConfigEuler = config_;
|
||||
VectorFunctionCoefficient ic(NumEq, InitialConditionEuler);
|
||||
|
||||
switch (ConfigEuler.ConfigNum)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// Periodic meshes must be used for this problem.
|
||||
ProblemName = "Euler Equations of Gas dynamics - Smooth Vortex";
|
||||
glvis_scale = "on";
|
||||
SpHeatRatio = 1.4;
|
||||
SolutionKnown = true;
|
||||
SteadyState = false;
|
||||
TimeDepBC = false;
|
||||
ProjType = 0;
|
||||
L2_Projection(ic, u0);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
ProblemName = "Euler Equations of Gas dynamics - SOD Shock Tube";
|
||||
glvis_scale = "on";
|
||||
SpHeatRatio = 1.4;
|
||||
SolutionKnown = false;
|
||||
SteadyState = false;
|
||||
TimeDepBC = false;
|
||||
ProjType = 1;
|
||||
L2_Projection(ic, u0);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
ProblemName = "Euler Equations of Gas dynamics - Woodward Colella";
|
||||
glvis_scale = "on";
|
||||
SpHeatRatio = 1.4;
|
||||
SolutionKnown = false;
|
||||
SteadyState = false;
|
||||
TimeDepBC = false;
|
||||
ProjType = 1;
|
||||
u0.ProjectCoefficient(ic);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
ProblemName = "Euler Equations of Gas dynamics - Double Mach Reflection";
|
||||
glvis_scale = "on";
|
||||
SpHeatRatio = 1.4;
|
||||
SolutionKnown = false;
|
||||
SteadyState = false;
|
||||
TimeDepBC = true;
|
||||
ProjType = 1;
|
||||
u0.ProjectCoefficient(ic);
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
ProblemName = "Euler Equations of Gas dynamics - Sedov Blast";
|
||||
glvis_scale = "on";
|
||||
SpHeatRatio = 5.0 / 3.0;
|
||||
SolutionKnown = false;
|
||||
SteadyState = false;
|
||||
TimeDepBC = true;
|
||||
ProjType = 1;
|
||||
u0.ProjectCoefficient(ic);
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
ProblemName = "Euler Equations of Gas dynamics - Noh Problem";
|
||||
glvis_scale = "on";
|
||||
SpHeatRatio = 5.0 / 3.0;
|
||||
SolutionKnown = true;
|
||||
SteadyState = false;
|
||||
TimeDepBC = true;
|
||||
ProjType = 1;
|
||||
u0.ProjectCoefficient(ic);
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
ProblemName = "Euler Equations of Gas dynamics - Gresho Vortex";
|
||||
glvis_scale = "on";
|
||||
SpHeatRatio = 1.4;
|
||||
SolutionKnown = true;
|
||||
SteadyState = true;
|
||||
TimeDepBC = false;
|
||||
ProjType = 0;
|
||||
u0.ProjectCoefficient(ic);
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
ProblemName = "Euler Equations of Gas dynamics - Constricted Channel";
|
||||
glvis_scale = "on";
|
||||
SpHeatRatio = 1.4;
|
||||
SolutionKnown = false;
|
||||
SteadyState = true;
|
||||
TimeDepBC = false;
|
||||
ProjType = 0;
|
||||
u0.ProjectCoefficient(ic);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MFEM_ABORT("No such test case implemented.");
|
||||
}
|
||||
}
|
||||
|
||||
double Euler::EvaluatePressure(const Vector &u) const
|
||||
{
|
||||
double aux = 0.0;
|
||||
for (int l = 0; l < dim; l++)
|
||||
{
|
||||
aux += u(1+l) * u(1+l);
|
||||
}
|
||||
double pressure = (SpHeatRatio - 1.0) * (u(dim+1) - 0.5 * aux / u(0));
|
||||
if (pressure < 0.)
|
||||
{
|
||||
ostringstream press_str;
|
||||
press_str << pressure;
|
||||
string err_msg = "Negative pressure p = ";
|
||||
MFEM_ABORT(err_msg << press_str.str());
|
||||
}
|
||||
return pressure;
|
||||
}
|
||||
|
||||
void Euler::EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
|
||||
int e, int k, int i) const
|
||||
{
|
||||
double pressure = EvaluatePressure(u);
|
||||
CheckAdmissibility(u);
|
||||
|
||||
switch (dim)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
double vx = u(1) / u(0);
|
||||
FluxEval(0,0) = u(1);
|
||||
FluxEval(1,0) = u(1) * vx + pressure;
|
||||
FluxEval(2,0) = (u(2) + pressure) * vx;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
double vx = u(1) / u(0);
|
||||
double vy = u(2) / u(0);
|
||||
double energy = u(3) + pressure;
|
||||
|
||||
FluxEval(0,0) = u(1);
|
||||
FluxEval(0,1) = u(2);
|
||||
|
||||
FluxEval(1,0) = u(1) * vx + pressure;
|
||||
FluxEval(1,1) = u(1) * vy;
|
||||
|
||||
FluxEval(2,0) = u(2) * vx;
|
||||
FluxEval(2,1) = u(2) * vy + pressure;
|
||||
|
||||
FluxEval(3,0) = energy * vx;
|
||||
FluxEval(3,1) = energy * vy;
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
double vx = u(1) / u(0);
|
||||
double vy = u(2) / u(0);
|
||||
double vz = u(3) / u(0);
|
||||
double energy = u(4) + pressure;
|
||||
|
||||
FluxEval(0,0) = u(1);
|
||||
FluxEval(0,1) = u(2);
|
||||
FluxEval(0,2) = u(3);
|
||||
|
||||
FluxEval(1,0) = u(1) * vx + pressure;
|
||||
FluxEval(1,1) = u(1) * vy;
|
||||
FluxEval(1,2) = u(1) * vz;
|
||||
|
||||
FluxEval(2,0) = u(2) * vx;
|
||||
FluxEval(2,1) = u(2) * vy + pressure;
|
||||
FluxEval(2,2) = u(2) * vz;
|
||||
|
||||
FluxEval(3,0) = u(3) * vx;
|
||||
FluxEval(3,1) = u(3) * vy;
|
||||
FluxEval(3,2) = u(3) * vz + pressure;
|
||||
|
||||
FluxEval(4,0) = energy * vx;
|
||||
FluxEval(4,1) = energy * vy;
|
||||
FluxEval(4,2) = energy * vz;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MFEM_ABORT("Invalid space dimension.");
|
||||
}
|
||||
}
|
||||
|
||||
double Euler::GetGMS(const Vector &uL, const Vector &uR,
|
||||
const Vector &normal) const
|
||||
{
|
||||
CheckAdmissibility(uL);
|
||||
CheckAdmissibility(uR);
|
||||
double pL = EvaluatePressure(uL);
|
||||
double pR = EvaluatePressure(uR);
|
||||
double aL = sqrt(SpHeatRatio * pL / uL(0));
|
||||
double aR = sqrt(SpHeatRatio * pR / uR(0));
|
||||
double vL = uL(1)/uL(0) * normal(0);
|
||||
double vR = uR(1)/uR(0) * normal(0);
|
||||
|
||||
double p = pow( (aL+aR-0.5*(SpHeatRatio-1.)*(vR-vL)) / (aL*pow(pL,
|
||||
(1.-SpHeatRatio)/(2.*SpHeatRatio)) + aR*pow(pR,
|
||||
(1.-SpHeatRatio)/(2.*SpHeatRatio)) ), 2.*SpHeatRatio/(SpHeatRatio-1.) );
|
||||
|
||||
double lambda1 = vL - aL * sqrt( 1. + (SpHeatRatio+1.)/(2.*SpHeatRatio) * max(
|
||||
0., (p-pL)/pL) );
|
||||
double lambda3 = vR + aR * sqrt( 1. + (SpHeatRatio+1.)/(2.*SpHeatRatio) * max(
|
||||
0., (p-pR)/pR) );
|
||||
return max(abs(lambda1), abs(lambda3));
|
||||
}
|
||||
|
||||
double Euler::GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
|
||||
int i) const
|
||||
{
|
||||
CheckAdmissibility(u);
|
||||
switch (u.Size())
|
||||
{
|
||||
case 3:
|
||||
return abs( u(1)*n(0) / u(0) ) + sqrt(SpHeatRatio * EvaluatePressure(u) / u(0));
|
||||
case 4:
|
||||
return abs( (u(1)*n(0) + u(2)*n(1)) / u(0) )
|
||||
+ sqrt(SpHeatRatio * EvaluatePressure(u) / u(0));
|
||||
case 5:
|
||||
return abs( (u(1)*n(0) + u(2)*n(1) + u(3)*n(2)) / u(0) )
|
||||
+ sqrt(SpHeatRatio * EvaluatePressure(u) / u(0));
|
||||
}
|
||||
}
|
||||
|
||||
void Euler::CheckAdmissibility(const Vector &u) const
|
||||
{
|
||||
double RhoMin = 1.e-12;
|
||||
|
||||
if (u.Size() != NumEq) { MFEM_ABORT("Invalid solution vector."); }
|
||||
|
||||
if (u(0) < RhoMin)
|
||||
{
|
||||
ostringstream rho_str;
|
||||
rho_str << u(0);
|
||||
string err_msg = "Density too small rho = ";
|
||||
MFEM_ABORT(err_msg << rho_str.str());
|
||||
}
|
||||
}
|
||||
|
||||
void Euler::SetBdrCond(const Vector &y1, Vector &y2, const Vector &normal,
|
||||
int attr) const
|
||||
{
|
||||
switch (attr)
|
||||
{
|
||||
case -1: // wall boundary
|
||||
{
|
||||
if (dim == 1)
|
||||
{
|
||||
y2(0) = y1(0);
|
||||
y2(1) = -y1(1);
|
||||
y2(2) = y1(2);
|
||||
}
|
||||
else if (dim == 2)
|
||||
{
|
||||
double MomTimesNorm = y1(1) * normal(0) + y1(2) * normal(1);
|
||||
y2(0) = y1(0);
|
||||
y2(1) = y1(1) - 2. * MomTimesNorm * normal(0);
|
||||
y2(2) = y1(2) - 2. * MomTimesNorm * normal(1);
|
||||
y2(3) = y1(3);
|
||||
}
|
||||
else
|
||||
{
|
||||
double MomTimesNorm = y1(1) * normal(0) + y1(2) * normal(1) + y1(3) * normal(2);
|
||||
y2(0) = y1(0);
|
||||
y2(1) = y1(1) - 2. * MomTimesNorm * normal(0);
|
||||
y2(2) = y1(2) - 2. * MomTimesNorm * normal(1);
|
||||
y2(3) = y1(3) - 2. * MomTimesNorm * normal(2);
|
||||
y2(4) = y1(4);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case -2: // supersonic outlet
|
||||
{
|
||||
y2 = y1;
|
||||
break;
|
||||
}
|
||||
case -3: // supersonic inlet
|
||||
{
|
||||
break;
|
||||
}
|
||||
// TODO subsonic in- and outlet
|
||||
default:
|
||||
MFEM_ABORT("Invalid boundary attribute.");
|
||||
}
|
||||
}
|
||||
|
||||
void Euler::ComputeDerivedQuantities(const GridFunction &u, GridFunction &d1,
|
||||
GridFunction &d2) const
|
||||
{
|
||||
double density, momentum;
|
||||
const IntegrationRule ir = u.FESpace()->GetFE(0)->GetNodes();
|
||||
|
||||
for (int e = 0; e < ne; e++)
|
||||
{
|
||||
for (int i = 0; i < nd; i++)
|
||||
{
|
||||
const IntegrationPoint &ip = ir.IntPoint(i);
|
||||
density = u.GetValue(e, ip, 1);
|
||||
momentum = u.GetValue(e, ip, 2);
|
||||
d1(e*nd + i) = pow(momentum / density, 2.0);
|
||||
|
||||
if (dim > 1)
|
||||
{
|
||||
momentum = u.GetValue(e, ip, 3);
|
||||
d1(e*nd + i) += pow(momentum / density, 2.0);
|
||||
}
|
||||
if (dim > 2)
|
||||
{
|
||||
momentum = u.GetValue(e, ip, 4);
|
||||
d1(e*nd + i) += pow(momentum / density, 2.0);
|
||||
}
|
||||
|
||||
d2(e*nd + i) = (SpHeatRatio - 1.0) * (u.GetValue(e, ip,
|
||||
dim+2) - 0.5 * density * d1(e*nd + i));
|
||||
d1(e*nd + i) = sqrt(d1(e*nd + i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Euler::ComputeErrors(Array<double> & errors, const GridFunction &u,
|
||||
double DomainSize, double t) const
|
||||
{
|
||||
errors.SetSize(NumEq*3);
|
||||
Vector component(dim+2);
|
||||
VectorFunctionCoefficient uAnalytic(NumEq, AnalyticalSolutionEuler);
|
||||
|
||||
if (ConfigEuler.ConfigNum == 0) { uAnalytic.SetTime(0); }
|
||||
else { uAnalytic.SetTime(t); }
|
||||
|
||||
component = 0.0;
|
||||
component(0) = 1.0;
|
||||
VectorConstantCoefficient weight1(component);
|
||||
errors[0] = u.ComputeLpError(1.0, uAnalytic, NULL, &weight1) / DomainSize;
|
||||
errors[1] = u.ComputeLpError(2.0, uAnalytic, NULL, &weight1) / DomainSize;
|
||||
errors[2] = u.ComputeLpError(numeric_limits<double>::infinity(), uAnalytic,
|
||||
NULL, &weight1);
|
||||
|
||||
component = 0.0;
|
||||
component(1) = 1.0;
|
||||
VectorConstantCoefficient weight2(component);
|
||||
errors[3] = u.ComputeLpError(1.0, uAnalytic, NULL, &weight2) / DomainSize;
|
||||
errors[4] = u.ComputeLpError(2.0, uAnalytic, NULL, &weight2) / DomainSize;
|
||||
errors[5] = u.ComputeLpError(numeric_limits<double>::infinity(), uAnalytic,
|
||||
NULL, &weight2);
|
||||
|
||||
component = 0.0;
|
||||
component(2) = 1.0;
|
||||
VectorConstantCoefficient weight3(component);
|
||||
errors[6] = u.ComputeLpError(1.0, uAnalytic, NULL, &weight3) / DomainSize;
|
||||
errors[7] = u.ComputeLpError(2.0, uAnalytic, NULL, &weight3) / DomainSize;
|
||||
errors[8] = u.ComputeLpError(numeric_limits<double>::infinity(), uAnalytic,
|
||||
NULL, &weight3);
|
||||
|
||||
if (dim > 1)
|
||||
{
|
||||
component = 0.0;
|
||||
component(3) = 1.0;
|
||||
VectorConstantCoefficient weight4(component);
|
||||
errors[9] = u.ComputeLpError(1.0, uAnalytic, NULL, &weight4) / DomainSize;
|
||||
errors[10] = u.ComputeLpError(2.0, uAnalytic, NULL, &weight4) / DomainSize;
|
||||
errors[11] = u.ComputeLpError(numeric_limits<double>::infinity(), uAnalytic,
|
||||
NULL, &weight4);
|
||||
}
|
||||
|
||||
if (dim > 2)
|
||||
{
|
||||
component = 0.0;
|
||||
component(4) = 1.0;
|
||||
VectorConstantCoefficient weight5(component);
|
||||
errors[12] = u.ComputeLpError(1.0, uAnalytic, NULL, &weight5) / DomainSize;
|
||||
errors[13] = u.ComputeLpError(2.0, uAnalytic, NULL, &weight5) / DomainSize;
|
||||
errors[14] = u.ComputeLpError(numeric_limits<double>::infinity(), uAnalytic,
|
||||
NULL, &weight5);
|
||||
}
|
||||
}
|
||||
|
||||
void EvaluateEnergy(Vector &u, const double &pressure)
|
||||
{
|
||||
const int dim = u.Size() - 2;
|
||||
double aux = 0.0;
|
||||
for (int l = 0; l < dim; l++)
|
||||
{
|
||||
aux += u(1+l)*u(1+l);
|
||||
}
|
||||
u(dim+1) = pressure / (SpHeatRatio - 1.0) + 0.5 * aux / u(0);
|
||||
}
|
||||
|
||||
void AnalyticalSolutionEuler(const Vector &x, double t, Vector &u)
|
||||
{
|
||||
const int dim = x.Size();
|
||||
Vector X(dim);
|
||||
|
||||
for (int i = 0; i < dim; i++)
|
||||
{
|
||||
switch (ConfigEuler.ConfigNum)
|
||||
{
|
||||
case 0:
|
||||
case 5:
|
||||
case 6: // Map to the reference domain [-1,1]^d.
|
||||
{
|
||||
double center = 0.5 * (ConfigEuler.bbMin(i) + ConfigEuler.bbMax(i));
|
||||
double factor = 2.0 / (ConfigEuler.bbMax(i) - ConfigEuler.bbMin(i));
|
||||
X(i) = factor * (x(i) - center);
|
||||
t *= pow(factor, 1.0 / (double(dim)));
|
||||
break;
|
||||
}
|
||||
case 3: // Map to the reference domain [0,1]^d.
|
||||
{
|
||||
double factor = 1.0 / (ConfigEuler.bbMax(i) - ConfigEuler.bbMin(i));
|
||||
X(i) = factor * (x(i) - ConfigEuler.bbMin(i));
|
||||
t *= pow(factor, 1.0 / (double(dim)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (ConfigEuler.ConfigNum)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if (dim != 2) { MFEM_ABORT("Test case works only in 2D."); }
|
||||
|
||||
// Map to test case specific domain [-5,5]^d.
|
||||
X *= 5.0;
|
||||
t *= 5.0;
|
||||
|
||||
double beta = 5.0;
|
||||
double r = X.Norml2();
|
||||
double T0 = 1.0 - (SpHeatRatio - 1.0) * beta * beta
|
||||
/ (8.0 * SpHeatRatio * M_PI * M_PI) * exp(1.0 - r*r);
|
||||
|
||||
u(0) = pow(T0, 1.0 / (SpHeatRatio - 1.0));
|
||||
u(1) = (1.0 - beta / (2.0 * M_PI) * exp(0.5 * (1.0 - r*r)) * X(1)) * u(0);
|
||||
u(2) = (1.0 + beta / (2.0 * M_PI) * exp(0.5 * (1.0 - r*r)) * X(0)) * u(0);
|
||||
EvaluateEnergy(u, u(0) * T0);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
if (dim != 2) { MFEM_ABORT("Test case works only in 2D."); }
|
||||
|
||||
// Map to test case specific domain [0,4] x [0,1].
|
||||
X(0) = 4.0 * X(0);
|
||||
t *= 2.0;
|
||||
|
||||
bool PostShock = X(0) < 1.0/6.0 + (X(1) + 20.0*t) / sqrt(3.0);
|
||||
|
||||
if (PostShock)
|
||||
{
|
||||
u(0) = 8.0;
|
||||
u(1) = 66.0 * cos(M_PI / 6.0);
|
||||
u(2) = -66.0 * sin(M_PI / 6.0);
|
||||
EvaluateEnergy(u, 116.5);
|
||||
}
|
||||
else
|
||||
{
|
||||
u = 0.0;
|
||||
u(0) = 1.4;
|
||||
EvaluateEnergy(u, 1.0);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
double r = X.Norml2();
|
||||
|
||||
if (r > t / 3.)
|
||||
{
|
||||
u(0) = 1.0 + t / r;
|
||||
for (int l = 0; l < dim; l++) { u(l+1) = -X(l) / r * u(0); }
|
||||
EvaluateEnergy(u, 1.0E-6);
|
||||
}
|
||||
else
|
||||
{
|
||||
u(0) = 1.0;
|
||||
for (int l = 0; l < dim; l++) { u(l+1) = 0.0; }
|
||||
EvaluateEnergy(u, 16.0 / 3.0);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
if (dim != 2) { MFEM_ABORT("Test case works only in 2D."); }
|
||||
|
||||
double pressure = 3.0 + 4.0*log(2.0);
|
||||
double r = X.Norml2();
|
||||
|
||||
u = 0.0;
|
||||
u(0) = 1.0;
|
||||
|
||||
if (r < 0.2)
|
||||
{
|
||||
u(1) = -5.0 * X(1);
|
||||
u(2) = 5.0 * X(0);
|
||||
pressure = 5.0 + 12.5*r*r;
|
||||
}
|
||||
else if (r < 0.4)
|
||||
{
|
||||
u(1) = -(2.0 / r - 5.0) * X(1);
|
||||
u(2) = (2.0 / r - 5.0) * X(0);
|
||||
pressure = 9.0 + 4.0 * (log(r) - log(0.2)) + 12.5*r*r - 20.0*r;
|
||||
}
|
||||
|
||||
EvaluateEnergy(u, pressure);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MFEM_ABORT("Analytical solution not known.");
|
||||
}
|
||||
}
|
||||
|
||||
void InitialConditionEuler(const Vector &x, Vector &u)
|
||||
{
|
||||
const int dim = x.Size();
|
||||
Vector X(dim);
|
||||
|
||||
for (int i = 0; i < dim; i++)
|
||||
{
|
||||
switch (ConfigEuler.ConfigNum)
|
||||
{
|
||||
case 4: // Map to the reference domain [-1,1]^d.
|
||||
{
|
||||
double center = 0.5 * (ConfigEuler.bbMin(i) + ConfigEuler.bbMax(i));
|
||||
double factor = 2.0 / (ConfigEuler.bbMax(i) - ConfigEuler.bbMin(i));
|
||||
X(i) = factor * (x(i) - center);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
case 2: // Map to the reference domain [0,1]^d.
|
||||
{
|
||||
double factor = 1.0 / (ConfigEuler.bbMax(i) - ConfigEuler.bbMin(i));
|
||||
X(i) = factor * (x(i) - ConfigEuler.bbMin(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (ConfigEuler.ConfigNum)
|
||||
{
|
||||
case 0:
|
||||
case 3:
|
||||
case 5:
|
||||
case 6:
|
||||
{
|
||||
AnalyticalSolutionEuler(x, 0.0, u);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (dim != 1) { MFEM_ABORT("Test case works only in 1D."); }
|
||||
|
||||
u = 0.0;
|
||||
u(0) = X.Norml2() < 0.5 ? 1.0 : 0.125;
|
||||
EvaluateEnergy(u, X.Norml2() < 0.5 ? 1.0 : 0.1);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
if (dim != 1) { MFEM_ABORT("Test case works only in 1D."); }
|
||||
|
||||
u = 0.0;
|
||||
u(0) = 1.0;
|
||||
if (X(0) < 0.1)
|
||||
{
|
||||
EvaluateEnergy(u, 1000.);
|
||||
}
|
||||
else if (X(0) < 0.9)
|
||||
{
|
||||
EvaluateEnergy(u, 0.01);
|
||||
}
|
||||
else
|
||||
{
|
||||
EvaluateEnergy(u, 100.);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
// Map to test case specific domain [-5,5]^d.
|
||||
X *= 5.0;
|
||||
|
||||
u = 0.0;
|
||||
u(0) = 1.0;
|
||||
// TODO make sure that energy is essentially a delta distribution.
|
||||
u(dim+1) = X.Norml2() < 1.0E-1 ? 1000.0 : 1.0E-8;
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
u = 0.0;
|
||||
u(0) = 1.0;
|
||||
u(1) = 1.0;
|
||||
EvaluateEnergy(u, 0.1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InflowFunctionEuler(const Vector &x, double t, Vector &u)
|
||||
{
|
||||
switch (ConfigEuler.ConfigNum)
|
||||
{
|
||||
case 0:
|
||||
case 3:
|
||||
case 5:
|
||||
case 6:
|
||||
{
|
||||
AnalyticalSolutionEuler(x, t, u);
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
InitialConditionEuler(x, u);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
case 2:
|
||||
case 4: break; // No boundary conditions needed.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef HYPSYS_EULER
|
||||
#define HYPSYS_EULER
|
||||
|
||||
#include "hyperbolic_system.hpp"
|
||||
|
||||
class Euler : public HyperbolicSystem
|
||||
{
|
||||
public:
|
||||
explicit Euler(FiniteElementSpace *fes_, BlockVector &u_block,
|
||||
Configuration &config_);
|
||||
~Euler() { };
|
||||
|
||||
virtual double EvaluatePressure(const Vector &u) const;
|
||||
|
||||
virtual void EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
|
||||
int e, int k, int i = -1) const;
|
||||
virtual double GetGMS(const Vector &uL, const Vector &uR,
|
||||
const Vector &normal) const override;
|
||||
virtual double GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
|
||||
int i) const;
|
||||
virtual void CheckAdmissibility(const Vector &u) const override;
|
||||
virtual void SetBdrCond(const Vector &y1, Vector &y2, const Vector &normal,
|
||||
int attr) const override;
|
||||
virtual void ComputeDerivedQuantities(const GridFunction &u, GridFunction &d1,
|
||||
GridFunction &d2) const override;
|
||||
virtual void ComputeErrors(Array<double> &errors, const GridFunction &u,
|
||||
double DomainSize, double t) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,140 @@
|
||||
#ifndef HYPSYS_HYPERBOLIC_SYSTEM
|
||||
#define HYPSYS_HYPERBOLIC_SYSTEM
|
||||
|
||||
#include "../lib/tools.hpp"
|
||||
|
||||
struct Configuration
|
||||
{
|
||||
int ConfigNum;
|
||||
double tFinal;
|
||||
Vector bbMin, bbMax;
|
||||
};
|
||||
|
||||
class HyperbolicSystem
|
||||
{
|
||||
public:
|
||||
explicit HyperbolicSystem(FiniteElementSpace *fes_, BlockVector &u_block,
|
||||
int NumEq_, Configuration &config_,
|
||||
VectorFunctionCoefficient BdrCond_) : fes(fes_), u0(fes_, u_block),
|
||||
NumEq(NumEq_), BdrCond(BdrCond_)
|
||||
{
|
||||
ne = fes->GetNE();
|
||||
nd = fes->GetFE(0)->GetDof();
|
||||
dim = fes->GetMesh()->Dimension();
|
||||
|
||||
l2_fec = new L2_FECollection(fes->GetFE(0)->GetOrder(),
|
||||
fes->GetMesh()->Dimension());
|
||||
l2_fes = new FiniteElementSpace(fes->GetMesh(), l2_fec, NumEq,
|
||||
Ordering::byNODES);
|
||||
l2_proj = new GridFunction(l2_fes);
|
||||
}
|
||||
|
||||
virtual ~HyperbolicSystem()
|
||||
{
|
||||
delete l2_proj;
|
||||
delete l2_fes;
|
||||
delete l2_fec;
|
||||
}
|
||||
|
||||
virtual void EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
|
||||
int e, int k, int i = -1) const = 0;
|
||||
virtual double GetGMS(const Vector &uL, const Vector &uR,
|
||||
const Vector &normal) const { } // TODO: if used "= 0"
|
||||
virtual double GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
|
||||
int i = -1) const = 0;
|
||||
virtual void CheckAdmissibility(const Vector &u) const { };
|
||||
virtual void SetBdrCond(const Vector &y1, Vector &y2, const Vector &normal,
|
||||
int attr) const { };
|
||||
virtual void ComputeDerivedQuantities(const GridFunction &u, GridFunction &d1,
|
||||
GridFunction &d2) const { };
|
||||
virtual void ComputeErrors(Array<double> &errors, const GridFunction &u,
|
||||
double DomainSize, double t) const { };
|
||||
|
||||
virtual void WriteErrors(const Array<double> &errors) const
|
||||
{
|
||||
ofstream file("errors.txt", ios_base::app);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
MFEM_ABORT("Error opening file.");
|
||||
}
|
||||
else
|
||||
{
|
||||
ostringstream strs;
|
||||
for (int i = 0; i < errors.Size(); i++)
|
||||
{
|
||||
strs << errors[i] << " ";
|
||||
}
|
||||
strs << "\n";
|
||||
string str = strs.str();
|
||||
file << str;
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
// L2 projection for scalar problems.
|
||||
void L2_Projection(FunctionCoefficient fun, GridFunction &proj) const
|
||||
{
|
||||
l2_proj->ProjectCoefficient(fun);
|
||||
proj.ProjectGridFunction(*l2_proj);
|
||||
}
|
||||
|
||||
// L2 projection for systems.
|
||||
void L2_Projection(VectorFunctionCoefficient fun, GridFunction &proj) const
|
||||
{
|
||||
l2_proj->ProjectCoefficient(fun);
|
||||
proj.ProjectGridFunction(*l2_proj);
|
||||
}
|
||||
|
||||
// Lumped L2 projection for general problems.
|
||||
void LumpedL2_Projection(VectorFunctionCoefficient fun, GridFunction &proj) const
|
||||
{
|
||||
Vector LumpedMassMat;
|
||||
|
||||
Vector aux_vec(NumEq);
|
||||
aux_vec = 1.0;
|
||||
VectorConstantCoefficient ones(aux_vec);
|
||||
BilinearForm ml(fes);
|
||||
ml.AddDomainIntegrator(new LumpedIntegrator(new VectorMassIntegrator(ones)));
|
||||
ml.Assemble();
|
||||
ml.Finalize();
|
||||
ml.SpMat().GetDiag(LumpedMassMat);
|
||||
|
||||
LinearForm rhs(fes);
|
||||
rhs.AddDomainIntegrator(new VectorDomainLFIntegrator(fun));
|
||||
rhs.Assemble();
|
||||
|
||||
for (int i = 0; i < LumpedMassMat.Size(); i++)
|
||||
{
|
||||
proj(i) = rhs.Elem(i) / LumpedMassMat(i);
|
||||
}
|
||||
}
|
||||
|
||||
int ne, nd, dim;
|
||||
|
||||
// 0: L2 projection,
|
||||
// 1: Nodal values as GridFunction coefficients (only second order accurate).
|
||||
int ProjType;
|
||||
const int NumEq;
|
||||
|
||||
FiniteElementSpace *fes;
|
||||
GridFunction u0;
|
||||
|
||||
// Auxiliary data needed for L2 projections
|
||||
L2_FECollection *l2_fec;
|
||||
FiniteElementSpace *l2_fes;
|
||||
GridFunction *l2_proj;
|
||||
|
||||
mutable VectorFunctionCoefficient BdrCond;
|
||||
|
||||
string ProblemName, glvis_scale;
|
||||
bool SolutionKnown;
|
||||
bool SteadyState;
|
||||
bool TimeDepBC;
|
||||
|
||||
// Currently only true for advection, due to spatially dependent flux.
|
||||
bool DiscreteUpwinding = false;
|
||||
DenseTensor VelNode;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,121 @@
|
||||
#include "kpp.hpp"
|
||||
|
||||
Configuration ConfigKPP;
|
||||
|
||||
void InitialConditionKPP(const Vector &x, Vector &u);
|
||||
void InflowFunctionKPP(const Vector &x, double t, Vector &u);
|
||||
|
||||
KPP::KPP(FiniteElementSpace *fes_, BlockVector &u_block,
|
||||
Configuration &config_)
|
||||
: HyperbolicSystem(fes_, u_block, 1, config_,
|
||||
VectorFunctionCoefficient(1, InflowFunctionKPP))
|
||||
{
|
||||
ConfigKPP = config_;
|
||||
VectorFunctionCoefficient ic(NumEq, InitialConditionKPP);
|
||||
|
||||
switch (ConfigKPP.ConfigNum)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
ProblemName = "KPP Equation - 2D Spiral";
|
||||
glvis_scale = "on";
|
||||
SolutionKnown = false;
|
||||
SteadyState = false;
|
||||
TimeDepBC = false;
|
||||
ProjType = 1;
|
||||
u0.ProjectCoefficient(ic);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
ProblemName = "KPP Equation - 1D";
|
||||
glvis_scale = "on";
|
||||
SolutionKnown =
|
||||
false; // There is a solution, but I don't have an analytical expression.
|
||||
SteadyState = false;
|
||||
TimeDepBC = false;
|
||||
ProjType = 1;
|
||||
u0.ProjectCoefficient(ic);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MFEM_ABORT("No such test case implemented.");
|
||||
}
|
||||
}
|
||||
|
||||
void KPP::EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
|
||||
int e, int k, int i) const
|
||||
{
|
||||
if (dim==1)
|
||||
{
|
||||
double coef = u(0)*(1.0-u(0));
|
||||
FluxEval(0,0) = u(0) < 0.5 ? (0.25*coef) : (0.1875 - 0.5*coef);
|
||||
}
|
||||
else if (dim==2)
|
||||
{
|
||||
FluxEval(0,0) = sin(u(0));
|
||||
FluxEval(0,1) = cos(u(0));
|
||||
}
|
||||
else { MFEM_ABORT("Not implemented."); }
|
||||
}
|
||||
|
||||
double KPP::GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
|
||||
int i) const
|
||||
{
|
||||
return 1.0; // Tighter bound exists.
|
||||
}
|
||||
|
||||
void InitialConditionKPP(const Vector &x, Vector &u)
|
||||
{
|
||||
const int dim = x.Size();
|
||||
Vector X(dim);
|
||||
|
||||
for (int i = 0; i < dim; i++)
|
||||
{
|
||||
switch (ConfigKPP.ConfigNum)
|
||||
{
|
||||
case 1: // Map to the reference domain [-1,1]^d.
|
||||
{
|
||||
double center = 0.5 * (ConfigKPP.bbMin(i) + ConfigKPP.bbMax(i));
|
||||
X(i) = 2.0 * (x(i) - center) / (ConfigKPP.bbMax(i) - ConfigKPP.bbMin(i));
|
||||
break;
|
||||
}
|
||||
case 2: // Map to the reference domain [0,1]^d.
|
||||
{
|
||||
X(i) = (x(i) - ConfigKPP.bbMin(i)) / (ConfigKPP.bbMax(i) - ConfigKPP.bbMin(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (ConfigKPP.ConfigNum)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
// Map to test case specific domain [-2,2] x [-2.5,1.5].
|
||||
X *= 2.0;
|
||||
X(1) -= 0.5;
|
||||
|
||||
u(0) = X.Norml2() <= 1. ? 3.5 * M_PI : 0.25 * M_PI;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
u(0) = X.Norml2() <= 0.25 ? 0.0 :
|
||||
1.0; // According to the original KPP paper, not Ern and Guermond.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InflowFunctionKPP(const Vector &x, double t, Vector &u)
|
||||
{
|
||||
switch (ConfigKPP.ConfigNum)
|
||||
{
|
||||
case 1: { u(0) = 0.25 * M_PI; break; }
|
||||
|
||||
// This definition is consistent with the problem and assures correct
|
||||
// handling of inflow (left) and outflow (right) boundaries.
|
||||
case 2: { u(0) = x(0); break; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef HYPSYS_KPP
|
||||
#define HYPSYS_KPP
|
||||
|
||||
#include "hyperbolic_system.hpp"
|
||||
|
||||
class KPP : public HyperbolicSystem
|
||||
{
|
||||
public:
|
||||
explicit KPP(FiniteElementSpace *fes_, BlockVector &u_block,
|
||||
Configuration &config_);
|
||||
~KPP() { };
|
||||
|
||||
virtual void EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
|
||||
int e, int k, int i = -1) const;
|
||||
virtual double GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
|
||||
int i) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef HYPSYS_APPS_LIB
|
||||
#define HYPSYS_APPS_LIB
|
||||
|
||||
#include "advection.hpp"
|
||||
#include "burgers.hpp"
|
||||
#include "kpp.hpp"
|
||||
#include "buckley_leverett.hpp"
|
||||
#include "shallowwater.hpp"
|
||||
#include "euler.hpp"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,463 @@
|
||||
#include "shallowwater.hpp"
|
||||
|
||||
Configuration ConfigSWE;
|
||||
|
||||
double GravConst;
|
||||
double Depth;
|
||||
|
||||
void AnalyticalSolutionSWE(const Vector &x, double t, Vector &u);
|
||||
void InitialConditionSWE(const Vector &x, Vector &u);
|
||||
void InflowFunctionSWE(const Vector &x, double t, Vector &u);
|
||||
|
||||
ShallowWater::ShallowWater(FiniteElementSpace *fes_, BlockVector &u_block,
|
||||
Configuration &config_)
|
||||
: HyperbolicSystem(fes_, u_block, fes_->GetMesh()->Dimension() + 1, config_,
|
||||
VectorFunctionCoefficient(fes_->GetMesh()->Dimension() + 1,
|
||||
InflowFunctionSWE))
|
||||
{
|
||||
ConfigSWE = config_;
|
||||
VectorFunctionCoefficient ic(NumEq, InitialConditionSWE);
|
||||
|
||||
switch (ConfigSWE.ConfigNum)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// Periodic meshes must be used for this problem.
|
||||
ProblemName = "Shallow Water Equations - Vorticity Advection";
|
||||
glvis_scale = "on";
|
||||
GravConst = 1.0;
|
||||
Depth = 1.0;
|
||||
SolutionKnown = true;
|
||||
SteadyState = false;
|
||||
TimeDepBC = false;
|
||||
ProjType = 0;
|
||||
L2_Projection(ic, u0);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
ProblemName = "Shallow Water Equations - Dam Break";
|
||||
glvis_scale = "on";
|
||||
GravConst = 9.81;
|
||||
Depth = 1.0;
|
||||
SolutionKnown = true;
|
||||
SteadyState = false;
|
||||
TimeDepBC = false;
|
||||
ProjType = 1;
|
||||
L2_Projection(ic, u0);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
ProblemName = "Shallow Water Equations - Radial Dam Break";
|
||||
glvis_scale = "off valuerange 0.1 1";
|
||||
GravConst = 9.81;
|
||||
Depth = 0.1;
|
||||
SolutionKnown = false;
|
||||
SteadyState = false;
|
||||
TimeDepBC = false;
|
||||
ProjType = 1;
|
||||
u0.ProjectCoefficient(ic);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
ProblemName = "Shallow Water Equations - Constricted Channel";
|
||||
glvis_scale = "on";
|
||||
GravConst = 0.16;
|
||||
Depth = 1.0;
|
||||
SolutionKnown = false;
|
||||
SteadyState = true;
|
||||
TimeDepBC = false;
|
||||
ProjType = 0;
|
||||
u0.ProjectCoefficient(ic);
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
ProblemName = "Shallow Water Equations - MoST Gimmick";
|
||||
glvis_scale = "on";
|
||||
GravConst = 1.0;
|
||||
SolutionKnown = false;
|
||||
SteadyState = false;
|
||||
TimeDepBC = false;
|
||||
ProjType = 1;
|
||||
|
||||
Mesh *mesh = fes->GetMesh();
|
||||
const int nd = fes->GetFE(0)->GetDof();
|
||||
const int ne = fes->GetNE();
|
||||
if (mesh->Dimension() != 2) { MFEM_ABORT("Test case works only in 2D."); }
|
||||
u0 = 0.;
|
||||
|
||||
for (int e = 0; e < ne; e++)
|
||||
{
|
||||
int id = mesh->GetElement(e)->GetAttribute();
|
||||
for (int j = 0; j < nd; j++)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
u0(e*nd+j) = 1.;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
{
|
||||
u0(e*nd+j) = 0.125;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MFEM_ABORT("Too many element IDs.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MFEM_ABORT("No such test case implemented.");
|
||||
}
|
||||
}
|
||||
|
||||
void ShallowWater::EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
|
||||
int e, int k, int i) const
|
||||
{
|
||||
CheckAdmissibility(u);
|
||||
switch (dim)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
FluxEval(0,0) = u(1);
|
||||
FluxEval(1,0) = u(1) * u(1) / u(0) + 0.5 * GravConst * u(0) * u(0);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
double vx = u(1) / u(0);
|
||||
double vy = u(2) / u(0);
|
||||
double gravitation = 0.5 * GravConst * u(0) * u(0);
|
||||
|
||||
FluxEval(0,0) = u(1);
|
||||
FluxEval(0,1) = u(2);
|
||||
|
||||
FluxEval(1,0) = u(1) * vx + gravitation;
|
||||
FluxEval(1,1) = u(1) * vy;
|
||||
|
||||
FluxEval(2,0) = u(2) * vx;
|
||||
FluxEval(2,1) = u(2) * vy + gravitation;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MFEM_ABORT("Invalid space dimension.");
|
||||
}
|
||||
}
|
||||
|
||||
double ShallowWater::GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
|
||||
int i) const
|
||||
{
|
||||
CheckAdmissibility(u);
|
||||
switch (u.Size())
|
||||
{
|
||||
case 2:
|
||||
return abs( u(1)*n(0) / u(0) ) + sqrt(GravConst * u(0));
|
||||
case 3:
|
||||
return abs( (u(1)*n(0) + u(2)*n(1)) / u(0) ) + sqrt(GravConst * u(0));
|
||||
}
|
||||
}
|
||||
|
||||
void ShallowWater::CheckAdmissibility(const Vector &u) const
|
||||
{
|
||||
double HMin = 1.e-12;
|
||||
|
||||
if (u.Size() != NumEq) { MFEM_ABORT("Invalid solution vector."); }
|
||||
|
||||
if (u(0) < HMin)
|
||||
{
|
||||
ostringstream height_str;
|
||||
height_str << u(0);
|
||||
string err_msg = "Water height too small H = ";
|
||||
MFEM_ABORT(err_msg << height_str.str() << ".");
|
||||
}
|
||||
}
|
||||
|
||||
void ShallowWater::SetBdrCond(const Vector &y1, Vector &y2,
|
||||
const Vector &normal, int attr) const
|
||||
{
|
||||
switch (attr)
|
||||
{
|
||||
case -1: // Land boundary
|
||||
{
|
||||
if (normal.Size() == 1)
|
||||
{
|
||||
y2(0) = y1(0);
|
||||
y2(1) = -y1(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
double MomTimesNor = y1(1) * normal(0) + y1(2) * normal(1);
|
||||
y2(0) = y1(0);
|
||||
y2(1) = y1(1) - 2. * MomTimesNor * normal(0);
|
||||
y2(2) = y1(2) - 2. * MomTimesNor * normal(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case -2: // Radiation boundary
|
||||
{
|
||||
y2 = y1;
|
||||
break;
|
||||
}
|
||||
case -3: // River boundary
|
||||
{
|
||||
break;
|
||||
}
|
||||
case -4: // Open sea boundary
|
||||
{
|
||||
double tmp = y2(0);
|
||||
y2 = y1;
|
||||
y2(0) = tmp;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MFEM_ABORT("Invalid boundary attribute.");
|
||||
}
|
||||
}
|
||||
|
||||
void ShallowWater::ComputeDerivedQuantities(const GridFunction &u,
|
||||
GridFunction &d1, GridFunction &d2) const
|
||||
{
|
||||
double height, momentum;
|
||||
const IntegrationRule ir = u.FESpace()->GetFE(0)->GetNodes();
|
||||
|
||||
for (int e = 0; e < ne; e++)
|
||||
{
|
||||
for (int i = 0; i < nd; i++)
|
||||
{
|
||||
const IntegrationPoint &ip = ir.IntPoint(i);
|
||||
height = u.GetValue(e, ip, 1);
|
||||
momentum = u.GetValue(e, ip, 2);
|
||||
d1(e*nd + i) = pow(momentum / height, 2.0);
|
||||
|
||||
if (dim==2)
|
||||
{
|
||||
momentum = u.GetValue(e, ip, 3);
|
||||
d1(e*nd + i) += pow(momentum / height, 2.0);
|
||||
}
|
||||
d1(e*nd + i) = sqrt(d1(e*nd + i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ShallowWater::ComputeErrors(Array<double> &errors, const GridFunction &u,
|
||||
double DomainSize, double t) const
|
||||
{
|
||||
errors.SetSize(NumEq*3);
|
||||
Vector component(dim+1);
|
||||
VectorFunctionCoefficient uAnalytic(NumEq, AnalyticalSolutionSWE);
|
||||
|
||||
if (ConfigSWE.ConfigNum == 0) { uAnalytic.SetTime(0); }
|
||||
else { uAnalytic.SetTime(t); }
|
||||
|
||||
component = 0.0;
|
||||
component(0) = 1.0;
|
||||
VectorConstantCoefficient weight1(component);
|
||||
errors[0] = u.ComputeLpError(1.0, uAnalytic, NULL, &weight1) / DomainSize;
|
||||
errors[1] = u.ComputeLpError(2.0, uAnalytic, NULL, &weight1) / DomainSize;
|
||||
errors[2] = u.ComputeLpError(numeric_limits<double>::infinity(), uAnalytic,
|
||||
NULL, &weight1);
|
||||
|
||||
component = 0.0;
|
||||
component(1) = 1.0;
|
||||
VectorConstantCoefficient weight2(component);
|
||||
errors[3] = u.ComputeLpError(1.0, uAnalytic, NULL, &weight2) / DomainSize;
|
||||
errors[4] = u.ComputeLpError(2.0, uAnalytic, NULL, &weight2) / DomainSize;
|
||||
errors[5] = u.ComputeLpError(numeric_limits<double>::infinity(), uAnalytic,
|
||||
NULL, &weight2);
|
||||
|
||||
if (dim == 2)
|
||||
{
|
||||
component = 0.0;
|
||||
component(2) = 1.0;
|
||||
VectorConstantCoefficient weight3(component);
|
||||
errors[6] = u.ComputeLpError(1.0, uAnalytic, NULL, &weight3) / DomainSize;
|
||||
errors[7] = u.ComputeLpError(2.0, uAnalytic, NULL, &weight3) / DomainSize;
|
||||
errors[8] = u.ComputeLpError(numeric_limits<double>::infinity(), uAnalytic,
|
||||
NULL, &weight3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AnalyticalSolutionSWE(const Vector &x, double t, Vector &u)
|
||||
{
|
||||
const int dim = x.Size();
|
||||
Vector X(dim);
|
||||
|
||||
for (int i = 0; i < dim; i++)
|
||||
{
|
||||
switch (ConfigSWE.ConfigNum)
|
||||
{
|
||||
case 0: // Map to the reference domain [-1,1]^d.
|
||||
{
|
||||
double center = 0.5 * (ConfigSWE.bbMin(i) + ConfigSWE.bbMax(i));
|
||||
double factor = 2.0 / (ConfigSWE.bbMax(i) - ConfigSWE.bbMin(i));
|
||||
X(i) = factor * (x(i) - center);
|
||||
t *= pow(factor, 1.0 / (double(dim)));
|
||||
break;
|
||||
}
|
||||
case 1: // Map to the reference domain [0,1]^d.
|
||||
{
|
||||
double factor = 1.0 / (ConfigSWE.bbMax(i) - ConfigSWE.bbMin(i));
|
||||
X(i) = factor * (x(i) - ConfigSWE.bbMin(i));
|
||||
t *= pow(factor, 1.0 / (double(dim)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (ConfigSWE.ConfigNum)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if (dim != 2) { MFEM_ABORT("Test case works only in 2D."); }
|
||||
|
||||
// Map to test case specific domain [-50,50].
|
||||
X *= 50.;
|
||||
t *= 50.;
|
||||
|
||||
double M = sqrt(2);
|
||||
double c1 = -0.1;
|
||||
double c2 = 0.005;
|
||||
double a = M_PI / 4.0;
|
||||
double x0 = 0.0;
|
||||
double y0 = 0.0;
|
||||
|
||||
double f = -c2 * ( pow(X(0) - x0 - M*t*cos(a), 2.0)
|
||||
+ pow(X(1) - y0 - M*t*sin(a), 2.0) );
|
||||
|
||||
u(0) = 1.0;
|
||||
u(1) = M*cos(a) + c1 * (X(1) - y0 - M*t*sin(a)) * exp(f);
|
||||
u(2) = M*sin(a) - c1 * (X(0) - x0 - M*t*cos(a)) * exp(f);
|
||||
u *= Depth - c1*c1 / (4.0*c2*GravConst) * exp(2.0*f);
|
||||
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
// Map to test case specific domain [0,1000]^d.
|
||||
X *= 1000;
|
||||
t *= 1000;
|
||||
|
||||
double r = X(0);
|
||||
u = 0.;
|
||||
|
||||
if (t==0)
|
||||
{
|
||||
u(0) = r < 500.0 ? Depth + 9.0 : Depth;
|
||||
return;
|
||||
}
|
||||
|
||||
double cm = 6.23416;
|
||||
double aux = sqrt(10.0 * GravConst);
|
||||
double xA = 500.0 - t*aux;
|
||||
double xB = 500.0 + t*(2.0*aux - 3.0*cm);
|
||||
double xC = 500.0 + t*(2.0*cm*cm*(aux - cm))/(cm*cm - GravConst);
|
||||
|
||||
u(0) = 9.0 * (r<xA) + (4.0/(9.0*GravConst) * pow( aux - (r-500.0)/(2.0*t),
|
||||
2.0 ) - 1.0) * (r>=xA) * (r<xB)
|
||||
+ (cm*cm/GravConst - 1.) * (r>=xB) * (r<xC);
|
||||
u(1) = 2.0/3.0 * ((r-500.0)/t + aux) * (r >= xA) * (r < xB) + 2.0 *
|
||||
(aux - cm) * (r >= xB) * (r < xC);
|
||||
u(0) += Depth;
|
||||
u(1) *= u(0);
|
||||
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
if (dim != 2) { MFEM_ABORT("Test case works only in 2D."); }
|
||||
|
||||
const double x1[2]= {-10., 0.}, x2[2]= {-10., 40.},
|
||||
x3[2]= {53.8622, 5.5872}, x4[2]= {53.8622, 34.4128},
|
||||
slope0=0.53886, slope1=0.79893;
|
||||
int sign_top, sign_bot;
|
||||
|
||||
if (x(0)>x3[0])
|
||||
{
|
||||
sign_top = -(x(0)-x4[0])*slope1-(x(1)-x4[1])>0 ? 1 : -1;
|
||||
sign_bot = (x(0)-x3[0])*slope1-(x(1)-x3[1])>0 ? 1 : -1;
|
||||
u(0) = sign_top*sign_bot>0. ? 0.8350436: 0.5273361;
|
||||
}
|
||||
else
|
||||
{
|
||||
sign_top = -(x(0)-x2[0])*slope0-(x(1)-x2[1])>0 ? 1 : -1;
|
||||
sign_bot = (x(0)-x1[0])*slope0-(x(1)-x1[1])>0 ? 1 : -1;
|
||||
u(0) = sign_top*sign_bot>0. ? 0.250133 : (sign_top>0 ? 1. : 0.5273361);
|
||||
}
|
||||
|
||||
u(0) += Depth;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InitialConditionSWE(const Vector &x, Vector &u)
|
||||
{
|
||||
const int dim = x.Size();
|
||||
Vector X(dim);
|
||||
|
||||
// Map to the reference domain [-1,1]^d.
|
||||
for (int i = 0; i < dim; i++)
|
||||
{
|
||||
double center = 0.5 * (ConfigSWE.bbMin(i) + ConfigSWE.bbMax(i));
|
||||
double factor = 2.0 / (ConfigSWE.bbMax(i) - ConfigSWE.bbMin(i));
|
||||
X(i) = factor * (x(i) - center);
|
||||
}
|
||||
|
||||
switch (ConfigSWE.ConfigNum)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
{
|
||||
AnalyticalSolutionSWE(x, 0., u);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
u = 0.0;
|
||||
u(0) = X.Norml2() < 0.5 ? 0.9 : 0.0;
|
||||
u(0) += Depth;
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
u(0) = Depth;
|
||||
u(1) = Depth;
|
||||
u(2) = 0.;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InflowFunctionSWE(const Vector &x, double t, Vector &u)
|
||||
{
|
||||
switch (ConfigSWE.ConfigNum)
|
||||
{
|
||||
case 0:
|
||||
case 2:
|
||||
{
|
||||
// Do not impose inflow values in this setup.
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
AnalyticalSolutionSWE(x, 0., u);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
InitialConditionSWE(x, u);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef HYPSYS_SHALLOWWATER
|
||||
#define HYPSYS_SHALLOWWATER
|
||||
|
||||
#include "hyperbolic_system.hpp"
|
||||
|
||||
class ShallowWater : public HyperbolicSystem
|
||||
{
|
||||
public:
|
||||
explicit ShallowWater(FiniteElementSpace *fes_, BlockVector &u_block,
|
||||
Configuration &config_);
|
||||
~ShallowWater() { };
|
||||
|
||||
virtual void EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
|
||||
int e, int k, int i = -1) const;
|
||||
virtual double GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
|
||||
int i) const;
|
||||
virtual void CheckAdmissibility(const Vector &u) const override;
|
||||
virtual void SetBdrCond(const Vector &y1, Vector &y2, const Vector &normal,
|
||||
int attr) const override;
|
||||
virtual void ComputeDerivedQuantities(const GridFunction &u, GridFunction &d1,
|
||||
GridFunction &d2) const override;
|
||||
virtual void ComputeErrors(Array<double> &errors, const GridFunction &u,
|
||||
double DomainSize, double t) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,115 @@
|
||||
#include "template.hpp"
|
||||
|
||||
Configuration ConfigTEMPLATE;
|
||||
|
||||
void AnalyticalSolutionTEMPLATE(const Vector &x, double t, Vector &u);
|
||||
void InitialConditionTEMPLATE(const Vector &x, Vector &u);
|
||||
void InflowFunctionTEMPLATE(const Vector &x, double t, Vector &u);
|
||||
|
||||
TEMPLATE::TEMPLATE(FiniteElementSpace *fes_, BlockVector &u_block,
|
||||
Configuration &config_)
|
||||
: HyperbolicSystem(fes_, u_block, NUMEQ, config_,
|
||||
VectorFunctionCoefficient(NUMEQ, InflowFunctionTEMPLATE))
|
||||
{
|
||||
ConfigTEMPLATE = config_;
|
||||
VectorFunctionCoefficient ic(NumEq, InitialConditionTEMPLATE);
|
||||
|
||||
switch (ConfigTEMPLATE.ConfigNum)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
ProblemName = "TEMPLATE - ";
|
||||
glvis_scale = "on";
|
||||
SolutionKnown = ;
|
||||
SteadyState = ;
|
||||
TimeDepBC = ;
|
||||
ProjType = 0;
|
||||
L2_Projection(ic, u0);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
ProblemName = "TEMPLATE - ";
|
||||
glvis_scale = "off valuerange 0 1";
|
||||
SolutionKnown = ;
|
||||
SteadyState = ;
|
||||
TimeDepBC = ;
|
||||
ProjType = 1;
|
||||
u0.ProjectCoefficient(ic);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MFEM_ABORT("No such test case implemented.");
|
||||
}
|
||||
}
|
||||
|
||||
void TEMPLATE::EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
|
||||
int e, int k, int i) const
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
double TEMPLATE::GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
|
||||
int i) const
|
||||
{
|
||||
//TODO
|
||||
return 0.;
|
||||
}
|
||||
|
||||
void TEMPLATE::SetBdrCond(const Vector &y1, Vector &y2, const Vector &normal,
|
||||
int attr) const
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
void TEMPLATE::ComputeErrors(Array<double> &errors, const GridFunction &u,
|
||||
double DomainSize, double t) const
|
||||
{
|
||||
errors.SetSize(3);
|
||||
VectorFunctionCoefficient uAnalytic(NumEq, AnalyticalSolutionTEMPLATE);
|
||||
uAnalytic.SetTime(t);
|
||||
errors[0] = u.ComputeLpError(1., uAnalytic) / DomainSize;
|
||||
errors[1] = u.ComputeLpError(2., uAnalytic) / DomainSize;
|
||||
errors[2] = u.ComputeLpError(numeric_limits<double>::infinity(), uAnalytic);
|
||||
}
|
||||
|
||||
|
||||
void AnalyticalSolutionTEMPLATE(const Vector &x, double t, Vector &u)
|
||||
{
|
||||
const int dim = x.Size();
|
||||
Vector X(dim);
|
||||
|
||||
for (int i = 0; i < dim; i++)
|
||||
{
|
||||
switch (ConfigTEMPLATE.ConfigNum)
|
||||
{
|
||||
case /* TODO */: // Map to the reference domain [-1,1]^d.
|
||||
{
|
||||
double center = 0.5 * (ConfigTEMPLATE.bbMin(i) + ConfigTEMPLATE.bbMax(i));
|
||||
double factor = 2.0 / (ConfigTEMPLATE.bbMax(i) - ConfigTEMPLATE.bbMin(i));
|
||||
X(i) = factor * (x(i) - center);
|
||||
t *= pow(factor, 1.0 / (double(dim)));
|
||||
break;
|
||||
}
|
||||
case /* TODO */: // Map to the reference domain [0,1]^d.
|
||||
{
|
||||
double factor = 1.0 / (ConfigTEMPLATE.bbMax(i) - ConfigTEMPLATE.bbMin(i));
|
||||
X(i) = factor * (x(i) - ConfigTEMPLATE.bbMin(i));
|
||||
t *= pow(factor, 1.0 / (double(dim)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
void InitialConditionTEMPLATE(const Vector &x, Vector &u)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void InflowFunctionTEMPLATE(const Vector &x, double t, Vector &u)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef HYPSYS_TEMPLATE
|
||||
#define HYPSYS_TEMPLATE
|
||||
|
||||
#include "hyperbolic_system.hpp"
|
||||
|
||||
class TEMPLATE : public HyperbolicSystem
|
||||
{
|
||||
public:
|
||||
explicit TEMPLATE(FiniteElementSpace *fes_, BlockVector &u_block,
|
||||
Configuration &config_);
|
||||
~TEMPLATE() { };
|
||||
|
||||
virtual void EvaluateFlux(const Vector &u, DenseMatrix &FluxEval,
|
||||
int e, int k, int i = -1) const;
|
||||
virtual double GetWaveSpeed(const Vector &u, const Vector n, int e, int k,
|
||||
int i) const;
|
||||
virtual void SetBdrCond(const Vector &y1, Vector &y2, const Vector &normal,
|
||||
int attr) const;
|
||||
virtual void ComputeDerivedQuantities(const Vector &u) const { };
|
||||
virtual void ComputeErrors(Array<double> &errors, const GridFunction &u,
|
||||
double DomainSize, double t) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
EXEC="mpirun -np 7 phypsys"
|
||||
|
||||
SCHEME=1
|
||||
MESH="data/periodic-4segment.mesh"
|
||||
MESH0="data/periodic-3segment.mesh"
|
||||
CONFIG="-p 0 -c 4 -vf 100 -tf 1 -s 3 -dt 0.001 -m $MESH"
|
||||
|
||||
$EXEC $CONFIG -es $SCHEME -o 1 -r 5
|
||||
$EXEC $CONFIG -es $SCHEME -o 3 -r 4
|
||||
$EXEC $CONFIG -es $SCHEME -o 7 -r 3
|
||||
|
||||
|
||||
# GRID CONVERGENCE TEST
|
||||
ORDER=1
|
||||
DT=0.0004
|
||||
# ORDER=2
|
||||
# DT=0.00025
|
||||
# ORDER=3
|
||||
# DT=0.0001
|
||||
# ORDER=4
|
||||
# DT=0.000025
|
||||
CONFIG0="-p 0 -c 3 -vf 1000 -tf 1 -s 3 -dt $DT -m $MESH0 -o $ORDER"
|
||||
CONFIG1="-p 0 -c 3 -vf 1000 -tf 1 -s 3 -dt $DT -m $MESH -o $ORDER"
|
||||
|
||||
# rm errors.txt
|
||||
# $EXEC $CONFIG0 -r 4 -es $SCHEME
|
||||
# $EXEC $CONFIG1 -r 4 -es $SCHEME
|
||||
# $EXEC $CONFIG0 -r 5 -es $SCHEME
|
||||
# $EXEC $CONFIG1 -r 5 -es $SCHEME
|
||||
# $EXEC $CONFIG0 -r 6 -es $SCHEME
|
||||
# $EXEC $CONFIG1 -r 6 -es $SCHEME
|
||||
# $EXEC $CONFIG0 -r 7 -es $SCHEME
|
||||
@@ -0,0 +1,43 @@
|
||||
EXEC="mpirun -np 7 phypsys"
|
||||
|
||||
SCHEME=0
|
||||
MESH=data/inline-4quad.mesh
|
||||
CONFIG="-p 1 -c 1 -vf 100 -tf 0.5 -s 3 -dt 0.0005 -m $MESH"
|
||||
|
||||
$EXEC $CONFIG -es $SCHEME -o 0 -r 5
|
||||
$EXEC $CONFIG -es $SCHEME -o 1 -r 4
|
||||
|
||||
SCHEME=1
|
||||
|
||||
$EXEC $CONFIG -es $SCHEME -o 1 -r 4
|
||||
$EXEC $CONFIG -es $SCHEME -o 3 -r 3
|
||||
$EXEC $CONFIG -es $SCHEME -o 7 -r 2
|
||||
$EXEC $CONFIG -es $SCHEME -o 15 -r 1
|
||||
|
||||
|
||||
# # GRID CONVERGENCE TEST
|
||||
# SCHEME=1
|
||||
ORDER=0
|
||||
DT=0.002
|
||||
# ORDER=1
|
||||
# DT=0.0004
|
||||
# # ORDER=2
|
||||
# # DT=0.00016
|
||||
# # ORDER=3
|
||||
# # DT=-dt 0.0001
|
||||
# # ORDER=4
|
||||
# # DT=0.00005
|
||||
# MESH="data/periodic-4segment.mesh"
|
||||
# MESH0="data/periodic-3segment.mesh"
|
||||
# CONFIG0="-p 1 -c 0 -vf 1000 -tf 0.1 -s 3 -dt $DT -m $MESH0 -o $ORDER"
|
||||
# CONFIG1="-p 1 -c 0 -vf 1000 -tf 0.1 -s 3 -dt $DT -m $MESH -o $ORDER"
|
||||
|
||||
# rm errors.txt
|
||||
# $EXEC $CONFIG0 -r 4 -es $SCHEME
|
||||
# $EXEC $CONFIG1 -r 4 -es $SCHEME
|
||||
# $EXEC $CONFIG0 -r 5 -es $SCHEME
|
||||
# $EXEC $CONFIG1 -r 5 -es $SCHEME
|
||||
# $EXEC $CONFIG0 -r 6 -es $SCHEME
|
||||
# $EXEC $CONFIG1 -r 6 -es $SCHEME
|
||||
# $EXEC $CONFIG0 -r 7 -es $SCHEME
|
||||
# $EXEC $CONFIG1 -r 7 -es $SCHEME
|
||||
@@ -0,0 +1,7 @@
|
||||
MESH=data/wall-bdr-100segment.mesh
|
||||
CONFIG="-p 3 -c 1 -vf 1000 -tf 0.02 -s 1 -m $MESH -r 0 -es 1"
|
||||
|
||||
./hypsys $CONFIG -o 3 -dt 0.00005
|
||||
mv ultimate.gf cmp.gf
|
||||
mpirun -np 3 phypsys $CONFIG -o 3 -dt 0.00005
|
||||
meld ultimate.gf cmp.gf
|
||||
@@ -0,0 +1,55 @@
|
||||
EXEC="mpirun -np 7 phypsys"
|
||||
|
||||
SCHEME=1
|
||||
MESH=data/wall-bdr-4segment.mesh
|
||||
|
||||
## SOD Shock tube
|
||||
CONFIG="-p 5 -c 1 -vf 1000 -tf 0.231 -s 3 -m $MESH -es $SCHEME"
|
||||
|
||||
# # h-refinement
|
||||
# $EXEC $CONFIG -o 1 -r 5 -dt 0.00064
|
||||
# $EXEC $CONFIG -o 1 -r 6 -dt 0.00032
|
||||
# $EXEC $CONFIG -o 1 -r 7 -dt 0.00016
|
||||
|
||||
# # p-refinement & h-coarsening
|
||||
# $EXEC $CONFIG -r 5 -o 1 -dt 0.0004
|
||||
# $EXEC $CONFIG -r 4 -o 3 -dt 0.0004
|
||||
# $EXEC $CONFIG -r 3 -o 7 -dt 0.0004
|
||||
# $EXEC $CONFIG -r 2 -o 15 -dt 0.0004
|
||||
# $EXEC $CONFIG -r 1 -o 31 -dt 0.0004
|
||||
|
||||
|
||||
## Woodward Colella
|
||||
MESH=data/wall-bdr-100segment.mesh
|
||||
CONFIG="-p 5 -c 2 -vf 1000 -tf 0.038 -s 3 -m $MESH -es $SCHEME"
|
||||
$EXEC $CONFIG -o 1 -r 2 -dt 1e-6
|
||||
|
||||
|
||||
# ## Double Mach reflection
|
||||
# MESH=data/double-mach-quad.mesh
|
||||
# CONFIG="-p 5 -c 3 -vf 1000 -tf 0.2 -s 3 -m $MESH -es $SCHEME"
|
||||
# $EXEC $CONFIG -o 1 -r 3 -dt 5e-5
|
||||
|
||||
|
||||
# ## Vortex advection
|
||||
# SCHEME=0
|
||||
# MESH3=data/periodic-3quad.mesh
|
||||
# MESH4=data/periodic-4quad.mesh
|
||||
|
||||
# ORDER=1
|
||||
# ODESOLVER=2
|
||||
# DT=0.000625
|
||||
# # ORDER=2
|
||||
# # ODESOLVER=3
|
||||
# # DT=0.0002
|
||||
# # ORDER=3
|
||||
# # ODESOLVER=3
|
||||
# # DT=0.00032
|
||||
# CONFIG="-p 5 -c 0 -vf 100 -tf 1 -s $ODESOLVER -dt $DT -o $ORDER -es $SCHEME"
|
||||
|
||||
# rm errors.txt
|
||||
# $EXEC $CONFIG -m $MESH3 -r 3
|
||||
# $EXEC $CONFIG -m $MESH4 -r 3
|
||||
# $EXEC $CONFIG -m $MESH3 -r 4
|
||||
# $EXEC $CONFIG -m $MESH4 -r 4
|
||||
# $EXEC $CONFIG -m $MESH3 -r 5
|
||||
@@ -0,0 +1,47 @@
|
||||
SCHEME=0
|
||||
|
||||
## Advection
|
||||
|
||||
# Solid Body Roatation
|
||||
# ./hypsys -r 0 -es $SCHEME
|
||||
# ./phypsys -r 0 -es $SCHEME
|
||||
# mpirun -np 4 ./phypsys -r 0 -es $SCHEME
|
||||
|
||||
# Steady Circular Convection
|
||||
# ./hypsys -vf 1000 -m data/inline-4quad.mesh -dt 0.0001 -o 2 -s 1 -r 3 -c 0 -es $SCHEME
|
||||
# ./phypsys -vf 1000 -m data/inline-4quad.mesh -dt 0.0001 -o 2 -s 1 -r 3 -c 0 -es $SCHEME
|
||||
# mpirun -np 4 ./phypsys -vf 1000 -m data/inline-4quad.mesh -dt 0.0001 -o 2 -s 1 -r 3 -c 0 -es $SCHEME
|
||||
|
||||
# Translation
|
||||
CONFIG="-p 0 -c 2 -vf 100 -tf 0.4 -s 3 -dt 0.002 -m data/periodic-3tri.mesh -o 2 -r 3 -es $SCHEME"
|
||||
./hypsys $CONFIG
|
||||
./phypsys $CONFIG
|
||||
mpirun -np 4 phypsys $CONFIG
|
||||
|
||||
## Burgers
|
||||
CONFIG="-p 1 -c 1 -vf 100 -tf 0.5 -s 3 -dt 0.004 -m data/inline-3quad.mesh -o 1 -r 3 -es $SCHEME"
|
||||
./hypsys $CONFIG
|
||||
./phypsys $CONFIG
|
||||
mpirun -np 7 phypsys $CONFIG
|
||||
|
||||
## KPP
|
||||
CONFIG="-p 2 -c 1 -vf 50 -tf 0.25 -s 3 -dt 0.005 -m data/inline-4tri.mesh -o 0 -r 4 -es 0"
|
||||
./hypsys $CONFIG
|
||||
./phypsys $CONFIG
|
||||
mpirun -np 1 phypsys $CONFIG
|
||||
|
||||
## Shallow-Water
|
||||
|
||||
# Dam break
|
||||
CONFIG="-p 4 -c 2 -vf 20 -tf 0.1 -s 3 -dt 0.0005 -m data/wall-bdr-4tri.mesh -o 1 -r 3 -es $SCHEME"
|
||||
./hypsys $CONFIG
|
||||
./phypsys $CONFIG
|
||||
mpirun -np 2 phypsys $CONFIG
|
||||
|
||||
## Euler
|
||||
|
||||
# Smooth vortex
|
||||
CONFIG="-p 5 -c 0 -vf 100 -tf 1 -s 3 -dt 0.00125 -m data/periodic-3quad.mesh -r 2 -es $SCHEME"
|
||||
./hypsys $CONFIG
|
||||
./phypsys $CONFIG
|
||||
mpirun -np 4 phypsys $CONFIG
|
||||
@@ -0,0 +1,12 @@
|
||||
EXEC="mpirun -np 7 phypsys"
|
||||
MESH=data/inline-4quad.mesh
|
||||
|
||||
# KPP
|
||||
# $EXEC -p 2 -c 1 -vf 100 -tf 0.25 -s 3 -dt 0.00025 -r 9 -o 0 -m $MESH -es 0
|
||||
$EXEC -p 2 -c 1 -vf 100 -tf 0.25 -s 3 -dt 0.002 -r 6 -o 0 -m $MESH -es 0
|
||||
$EXEC -p 2 -c 1 -vf 100 -tf 0.25 -s 3 -dt 0.0008 -r 5 -o 1 -m $MESH -es 0
|
||||
$EXEC -p 2 -c 1 -vf 100 -tf 0.25 -s 3 -dt 0.0008 -r 5 -o 1 -m $MESH -es 1
|
||||
|
||||
# Buckley-Leverett
|
||||
$EXEC -p 3 -c 2 -vf 100 -tf 0.1666667 -s 3 -dt 0.0005 -r 5 -o 0 -m $MESH -es 0
|
||||
$EXEC -p 3 -c 2 -vf 100 -tf 0.1666667 -s 3 -dt 0.0005 -r 4 -o 1 -m $MESH -es 1
|
||||
@@ -0,0 +1,54 @@
|
||||
EXEC="mpirun -np 7 phypsys"
|
||||
|
||||
## 1D Dam break
|
||||
SCHEME=0
|
||||
MESH=data/wall-bdr-4segment.mesh
|
||||
CONFIG="-p 4 -c 1 -vf 1000 -tf 0.02 -s 3 -m $MESH -es $SCHEME"
|
||||
|
||||
# # h-refinement
|
||||
# $EXEC $CONFIG -o 1 -r 5 -dt 0.0001
|
||||
# $EXEC $CONFIG -o 1 -r 6 -dt 0.00005
|
||||
# $EXEC $CONFIG -o 1 -r 7 -dt 0.000025
|
||||
# $EXEC $CONFIG -o 1 -r 8 -dt 0.0000125
|
||||
|
||||
# # p-refinement & h-coarsening
|
||||
# $EXEC $CONFIG -o 1 -r 5 -dt 0.000025
|
||||
# $EXEC $CONFIG -o 3 -r 4 -dt 0.000025
|
||||
# $EXEC $CONFIG -o 7 -r 3 -dt 0.000025
|
||||
|
||||
# ## Radial dambreak
|
||||
# MESH=data/outflow-bdr-4quad.mesh
|
||||
# CONFIG="-p 4 -c 2 -vf 50 -tf 0.06 -s 3 -m $MESH -es 1"
|
||||
|
||||
# # p-refinement & h-coarsening
|
||||
# $EXEC $CONFIG -o 1 -r 5 -dt 0.0001
|
||||
# $EXEC $CONFIG -o 3 -r 4 -dt 0.0001
|
||||
# $EXEC $CONFIG -o 7 -r 3 -dt 0.0001
|
||||
|
||||
## Constricted channel
|
||||
MESH=data/constricted-channel.mesh
|
||||
CONFIG="-p 4 -c 3 -vf 100 -tf 1000 -s 1 -m $MESH -es $SCHEME"
|
||||
$EXEC $CONFIG -r 1 -o 1 -dt 0.025
|
||||
|
||||
# ## Vortex advection
|
||||
# SCHEME=0
|
||||
# MESH3=data/periodic-3quad.mesh
|
||||
# MESH4=data/periodic-4quad.mesh
|
||||
|
||||
# ORDER=1
|
||||
# ODESOLVER=2
|
||||
# DT=0.00064
|
||||
# # ORDER=2
|
||||
# # ODESOLVER=3
|
||||
# # DT=0.0004
|
||||
# # ORDER=3
|
||||
# # ODESOLVER=3
|
||||
# # DT=0.00025
|
||||
# CONFIG="-p 4 -c 0 -vf 100 -tf 1 -s $ODESOLVER -dt $DT -o $ORDER -es $SCHEME"
|
||||
|
||||
# rm errors.txt
|
||||
# $EXEC $CONFIG -m $MESH3 -r 3
|
||||
# $EXEC $CONFIG -m $MESH4 -r 3
|
||||
# $EXEC $CONFIG -m $MESH3 -r 4
|
||||
# $EXEC $CONFIG -m $MESH4 -r 4
|
||||
# $EXEC $CONFIG -m $MESH3 -r 5
|
||||
@@ -0,0 +1,6 @@
|
||||
EXEC="mpirun -np 7 phypsys"
|
||||
|
||||
MESH=data/periodic-4quad.mesh
|
||||
SCHEME=1
|
||||
|
||||
$EXEC -p 0 -c 1 -vf 200 -tf 1 -s 3 -dt 0.00032 -m $MESH -r 4 -o 2 -es $SCHEME
|
||||
@@ -0,0 +1,103 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
#
|
||||
|
||||
dimension
|
||||
3
|
||||
|
||||
elements
|
||||
8
|
||||
1 5 0 1 10 9 18 19 28 27
|
||||
1 5 1 2 11 10 19 20 29 28
|
||||
1 5 2 3 12 11 20 21 30 29
|
||||
1 5 3 4 13 12 21 22 31 30
|
||||
2 5 4 5 14 13 22 23 32 31
|
||||
2 5 5 6 15 14 23 24 33 32
|
||||
2 5 6 7 16 15 24 25 34 33
|
||||
2 5 7 8 17 16 25 26 35 34
|
||||
|
||||
boundary
|
||||
34
|
||||
3 3 9 10 1 0
|
||||
3 3 0 1 19 18
|
||||
3 3 10 9 27 28
|
||||
1 3 9 0 18 27
|
||||
3 3 18 19 28 27
|
||||
3 3 10 11 2 1
|
||||
3 3 1 2 20 19
|
||||
3 3 11 10 28 29
|
||||
3 3 19 20 29 28
|
||||
3 3 11 12 3 2
|
||||
3 3 2 3 21 20
|
||||
3 3 12 11 29 30
|
||||
3 3 20 21 30 29
|
||||
3 3 12 13 4 3
|
||||
3 3 3 4 22 21
|
||||
3 3 13 12 30 31
|
||||
3 3 21 22 31 30
|
||||
3 3 13 14 5 4
|
||||
3 3 4 5 23 22
|
||||
3 3 14 13 31 32
|
||||
3 3 22 23 32 31
|
||||
3 3 14 15 6 5
|
||||
3 3 5 6 24 23
|
||||
3 3 15 14 32 33
|
||||
3 3 23 24 33 32
|
||||
3 3 15 16 7 6
|
||||
3 3 6 7 25 24
|
||||
3 3 16 15 33 34
|
||||
3 3 24 25 34 33
|
||||
3 3 16 17 8 7
|
||||
3 3 7 8 26 25
|
||||
2 3 8 17 35 26
|
||||
3 3 17 16 34 35
|
||||
3 3 25 26 35 34
|
||||
|
||||
vertices
|
||||
36
|
||||
3
|
||||
0 0 0
|
||||
1 0 0
|
||||
2 0 0
|
||||
3 0 0
|
||||
4 0 0
|
||||
5 0 0
|
||||
6 0 0
|
||||
7 0 0
|
||||
8 0 0
|
||||
0 1 0
|
||||
1 1 0
|
||||
2 1 0
|
||||
3 1 0
|
||||
4 1 0
|
||||
5 1 0
|
||||
6 1 0
|
||||
7 1 0
|
||||
8 1 0
|
||||
0 0 1
|
||||
1 0 1
|
||||
2 0 1
|
||||
3 0 1
|
||||
4 0 1
|
||||
5 0 1
|
||||
6 0 1
|
||||
7 0 1
|
||||
8 0 1
|
||||
0 1 1
|
||||
1 1 1
|
||||
2 1 1
|
||||
3 1 1
|
||||
4 1 1
|
||||
5 1 1
|
||||
6 1 1
|
||||
7 1 1
|
||||
8 1 1
|
||||
@@ -0,0 +1,69 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
#
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
elements
|
||||
8
|
||||
1 3 0 1 10 9
|
||||
1 3 1 2 11 10
|
||||
1 3 2 3 12 11
|
||||
1 3 3 4 13 12
|
||||
2 3 4 5 14 13
|
||||
2 3 5 6 15 14
|
||||
2 3 6 7 16 15
|
||||
2 3 7 8 17 16
|
||||
|
||||
boundary
|
||||
18
|
||||
3 1 0 1
|
||||
3 1 1 2
|
||||
3 1 2 3
|
||||
3 1 3 4
|
||||
3 1 4 5
|
||||
3 1 5 6
|
||||
3 1 6 7
|
||||
3 1 7 8
|
||||
3 1 10 9
|
||||
3 1 11 10
|
||||
3 1 12 11
|
||||
3 1 13 12
|
||||
3 1 14 13
|
||||
3 1 15 14
|
||||
3 1 16 15
|
||||
3 1 17 16
|
||||
1 1 9 0
|
||||
2 1 8 17
|
||||
|
||||
vertices
|
||||
18
|
||||
2
|
||||
0 0
|
||||
1 0
|
||||
2 0
|
||||
3 0
|
||||
4 0
|
||||
5 0
|
||||
6 0
|
||||
7 0
|
||||
8 0
|
||||
0 1
|
||||
1 1
|
||||
2 1
|
||||
3 1
|
||||
4 1
|
||||
5 1
|
||||
6 1
|
||||
7 1
|
||||
8 1
|
||||
@@ -0,0 +1,77 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
#
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
elements
|
||||
16
|
||||
1 2 10 0 1
|
||||
1 2 0 10 9
|
||||
1 2 11 1 2
|
||||
1 2 1 11 10
|
||||
1 2 12 2 3
|
||||
1 2 2 12 11
|
||||
1 2 13 3 4
|
||||
1 2 3 13 12
|
||||
2 2 14 4 5
|
||||
2 2 4 14 13
|
||||
2 2 15 5 6
|
||||
2 2 5 15 14
|
||||
2 2 16 6 7
|
||||
2 2 6 16 15
|
||||
2 2 17 7 8
|
||||
2 2 7 17 16
|
||||
|
||||
boundary
|
||||
18
|
||||
3 1 0 1
|
||||
3 1 1 2
|
||||
3 1 2 3
|
||||
3 1 3 4
|
||||
3 1 4 5
|
||||
3 1 5 6
|
||||
3 1 6 7
|
||||
3 1 7 8
|
||||
3 1 10 9
|
||||
3 1 11 10
|
||||
3 1 12 11
|
||||
3 1 13 12
|
||||
3 1 14 13
|
||||
3 1 15 14
|
||||
3 1 16 15
|
||||
3 1 17 16
|
||||
1 1 9 0
|
||||
2 1 8 17
|
||||
|
||||
vertices
|
||||
18
|
||||
2
|
||||
0 0
|
||||
1 0
|
||||
2 0
|
||||
3 0
|
||||
4 0
|
||||
5 0
|
||||
6 0
|
||||
7 0
|
||||
8 0
|
||||
0 1
|
||||
1 1
|
||||
2 1
|
||||
3 1
|
||||
4 1
|
||||
5 1
|
||||
6 1
|
||||
7 1
|
||||
8 1
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,405 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
# PRISM = 6
|
||||
#
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
elements
|
||||
144
|
||||
1 3 0 1 26 25
|
||||
1 3 25 26 51 50
|
||||
1 3 26 27 52 51
|
||||
1 3 1 2 27 26
|
||||
1 3 2 3 28 27
|
||||
1 3 27 28 53 52
|
||||
1 3 52 53 78 77
|
||||
1 3 77 78 103 102
|
||||
1 3 76 77 102 101
|
||||
1 3 51 52 77 76
|
||||
1 3 50 51 76 75
|
||||
1 3 75 76 101 100
|
||||
1 3 100 101 126 125
|
||||
1 3 125 126 151 150
|
||||
1 3 126 127 152 151
|
||||
1 3 101 102 127 126
|
||||
1 3 102 103 128 127
|
||||
1 3 127 128 153 152
|
||||
1 3 128 129 154 153
|
||||
1 3 103 104 129 128
|
||||
1 3 104 105 130 129
|
||||
1 3 129 130 155 154
|
||||
1 3 130 131 156 155
|
||||
1 3 105 106 131 130
|
||||
1 3 80 81 106 105
|
||||
1 3 55 56 81 80
|
||||
1 3 54 55 80 79
|
||||
1 3 79 80 105 104
|
||||
1 3 78 79 104 103
|
||||
1 3 53 54 79 78
|
||||
1 3 28 29 54 53
|
||||
1 3 3 4 29 28
|
||||
1 3 4 5 30 29
|
||||
1 3 29 30 55 54
|
||||
1 3 30 31 56 55
|
||||
1 3 5 6 31 30
|
||||
1 3 6 7 32 31
|
||||
1 3 31 32 57 56
|
||||
1 3 32 33 58 57
|
||||
1 3 7 8 33 32
|
||||
1 3 8 9 34 33
|
||||
1 3 33 34 59 58
|
||||
1 3 58 59 84 83
|
||||
1 3 83 84 109 108
|
||||
1 3 82 83 108 107
|
||||
1 3 57 58 83 82
|
||||
1 3 56 57 82 81
|
||||
1 3 81 82 107 106
|
||||
1 3 106 107 132 131
|
||||
1 3 131 132 157 156
|
||||
1 3 132 133 158 157
|
||||
1 3 107 108 133 132
|
||||
1 3 108 109 134 133
|
||||
1 3 133 134 159 158
|
||||
1 3 134 135 160 159
|
||||
1 3 109 110 135 134
|
||||
1 3 110 111 136 135
|
||||
1 3 135 136 161 160
|
||||
1 3 136 137 162 161
|
||||
1 3 111 112 137 136
|
||||
1 3 86 87 112 111
|
||||
1 3 61 62 87 86
|
||||
1 3 60 61 86 85
|
||||
1 3 85 86 111 110
|
||||
1 3 84 85 110 109
|
||||
1 3 59 60 85 84
|
||||
1 3 34 35 60 59
|
||||
1 3 9 10 35 34
|
||||
1 3 10 11 36 35
|
||||
1 3 35 36 61 60
|
||||
1 3 36 37 62 61
|
||||
1 3 11 12 37 36
|
||||
1 3 12 13 38 37
|
||||
1 3 37 38 63 62
|
||||
1 3 38 39 64 63
|
||||
1 3 13 14 39 38
|
||||
1 3 14 15 40 39
|
||||
1 3 39 40 65 64
|
||||
1 3 64 65 90 89
|
||||
1 3 89 90 115 114
|
||||
1 3 88 89 114 113
|
||||
1 3 63 64 89 88
|
||||
1 3 62 63 88 87
|
||||
1 3 87 88 113 112
|
||||
1 3 112 113 138 137
|
||||
1 3 137 138 163 162
|
||||
1 3 138 139 164 163
|
||||
1 3 113 114 139 138
|
||||
1 3 114 115 140 139
|
||||
1 3 139 140 165 164
|
||||
1 3 140 141 166 165
|
||||
1 3 115 116 141 140
|
||||
1 3 116 117 142 141
|
||||
1 3 141 142 167 166
|
||||
1 3 142 143 168 167
|
||||
1 3 117 118 143 142
|
||||
1 3 92 93 118 117
|
||||
1 3 67 68 93 92
|
||||
1 3 66 67 92 91
|
||||
1 3 91 92 117 116
|
||||
1 3 90 91 116 115
|
||||
1 3 65 66 91 90
|
||||
1 3 40 41 66 65
|
||||
1 3 15 16 41 40
|
||||
1 3 16 17 42 41
|
||||
1 3 41 42 67 66
|
||||
1 3 42 43 68 67
|
||||
1 3 17 18 43 42
|
||||
1 3 18 19 44 43
|
||||
1 3 43 44 69 68
|
||||
1 3 44 45 70 69
|
||||
1 3 19 20 45 44
|
||||
1 3 20 21 46 45
|
||||
1 3 45 46 71 70
|
||||
1 3 70 71 96 95
|
||||
1 3 95 96 121 120
|
||||
1 3 94 95 120 119
|
||||
1 3 69 70 95 94
|
||||
1 3 68 69 94 93
|
||||
1 3 93 94 119 118
|
||||
1 3 118 119 144 143
|
||||
1 3 143 144 169 168
|
||||
1 3 144 145 170 169
|
||||
1 3 119 120 145 144
|
||||
1 3 120 121 146 145
|
||||
1 3 145 146 171 170
|
||||
1 3 146 147 172 171
|
||||
1 3 121 122 147 146
|
||||
1 3 122 123 148 147
|
||||
1 3 147 148 173 172
|
||||
1 3 148 149 174 173
|
||||
1 3 123 124 149 148
|
||||
1 3 98 99 124 123
|
||||
1 3 73 74 99 98
|
||||
1 3 72 73 98 97
|
||||
1 3 97 98 123 122
|
||||
1 3 96 97 122 121
|
||||
1 3 71 72 97 96
|
||||
1 3 46 47 72 71
|
||||
1 3 21 22 47 46
|
||||
1 3 22 23 48 47
|
||||
1 3 47 48 73 72
|
||||
1 3 48 49 74 73
|
||||
1 3 23 24 49 48
|
||||
|
||||
boundary
|
||||
60
|
||||
3 1 0 1
|
||||
1 1 1 2
|
||||
1 1 2 3
|
||||
1 1 3 4
|
||||
1 1 4 5
|
||||
1 1 5 6
|
||||
1 1 6 7
|
||||
1 1 7 8
|
||||
1 1 8 9
|
||||
1 1 9 10
|
||||
1 1 10 11
|
||||
1 1 11 12
|
||||
1 1 12 13
|
||||
1 1 13 14
|
||||
1 1 14 15
|
||||
1 1 15 16
|
||||
1 1 16 17
|
||||
1 1 17 18
|
||||
1 1 18 19
|
||||
1 1 19 20
|
||||
1 1 20 21
|
||||
1 1 21 22
|
||||
1 1 22 23
|
||||
1 1 23 24
|
||||
3 1 151 150
|
||||
3 1 152 151
|
||||
3 1 153 152
|
||||
3 1 154 153
|
||||
3 1 155 154
|
||||
3 1 156 155
|
||||
3 1 157 156
|
||||
3 1 158 157
|
||||
3 1 159 158
|
||||
3 1 160 159
|
||||
3 1 161 160
|
||||
3 1 162 161
|
||||
3 1 163 162
|
||||
3 1 164 163
|
||||
3 1 165 164
|
||||
3 1 166 165
|
||||
3 1 167 166
|
||||
3 1 168 167
|
||||
3 1 169 168
|
||||
3 1 170 169
|
||||
3 1 171 170
|
||||
3 1 172 171
|
||||
3 1 173 172
|
||||
3 1 174 173
|
||||
3 1 25 0
|
||||
3 1 50 25
|
||||
3 1 75 50
|
||||
3 1 100 75
|
||||
3 1 125 100
|
||||
3 1 150 125
|
||||
2 1 24 49
|
||||
2 1 49 74
|
||||
2 1 74 99
|
||||
2 1 99 124
|
||||
2 1 124 149
|
||||
2 1 149 174
|
||||
|
||||
vertices
|
||||
175
|
||||
2
|
||||
0 0
|
||||
0.16666666666666666 0
|
||||
0.33333333333333333 0
|
||||
0.5 0
|
||||
0.66666666666666666 0
|
||||
0.83333333333333333 0
|
||||
1 0
|
||||
1.1666666666666666 0
|
||||
1.3333333333333333 0
|
||||
1.5 0
|
||||
1.6666666666666666 0
|
||||
1.8333333333333333 0
|
||||
2 0
|
||||
2.1666666666666666 0
|
||||
2.3333333333333333 0
|
||||
2.5 0
|
||||
2.6666666666666666 0
|
||||
2.8333333333333333 0
|
||||
3 0
|
||||
3.1666666666666666 0
|
||||
3.3333333333333333 0
|
||||
3.5 0
|
||||
3.6666666666666666 0
|
||||
3.8333333333333333 0
|
||||
4 0
|
||||
0 0.16666666666666666
|
||||
0.16666666666666666 0.16666666666666666
|
||||
0.33333333333333333 0.16666666666666666
|
||||
0.5 0.16666666666666666
|
||||
0.66666666666666666 0.16666666666666666
|
||||
0.83333333333333333 0.16666666666666666
|
||||
1 0.16666666666666666
|
||||
1.1666666666666666 0.16666666666666666
|
||||
1.3333333333333333 0.16666666666666666
|
||||
1.5 0.16666666666666666
|
||||
1.6666666666666666 0.16666666666666666
|
||||
1.8333333333333333 0.16666666666666666
|
||||
2 0.16666666666666666
|
||||
2.1666666666666666 0.16666666666666666
|
||||
2.3333333333333333 0.16666666666666666
|
||||
2.5 0.16666666666666666
|
||||
2.6666666666666666 0.16666666666666666
|
||||
2.8333333333333333 0.16666666666666666
|
||||
3 0.16666666666666666
|
||||
3.1666666666666666 0.16666666666666666
|
||||
3.3333333333333333 0.16666666666666666
|
||||
3.5 0.16666666666666666
|
||||
3.6666666666666666 0.16666666666666666
|
||||
3.8333333333333333 0.16666666666666666
|
||||
4 0.16666666666666666
|
||||
0 0.33333333333333333
|
||||
0.16666666666666666 0.33333333333333333
|
||||
0.33333333333333333 0.33333333333333333
|
||||
0.5 0.33333333333333333
|
||||
0.66666666666666666 0.33333333333333333
|
||||
0.83333333333333333 0.33333333333333333
|
||||
1 0.33333333333333333
|
||||
1.1666666666666666 0.33333333333333333
|
||||
1.3333333333333333 0.33333333333333333
|
||||
1.5 0.33333333333333333
|
||||
1.6666666666666666 0.33333333333333333
|
||||
1.8333333333333333 0.33333333333333333
|
||||
2 0.33333333333333333
|
||||
2.1666666666666666 0.33333333333333333
|
||||
2.3333333333333333 0.33333333333333333
|
||||
2.5 0.33333333333333333
|
||||
2.6666666666666666 0.33333333333333333
|
||||
2.8333333333333333 0.33333333333333333
|
||||
3 0.33333333333333333
|
||||
3.1666666666666666 0.33333333333333333
|
||||
3.3333333333333333 0.33333333333333333
|
||||
3.5 0.33333333333333333
|
||||
3.6666666666666666 0.33333333333333333
|
||||
3.8333333333333333 0.33333333333333333
|
||||
4 0.33333333333333333
|
||||
0 0.5
|
||||
0.16666666666666666 0.5
|
||||
0.33333333333333333 0.5
|
||||
0.5 0.5
|
||||
0.66666666666666666 0.5
|
||||
0.83333333333333333 0.5
|
||||
1 0.5
|
||||
1.1666666666666666 0.5
|
||||
1.3333333333333333 0.5
|
||||
1.5 0.5
|
||||
1.6666666666666666 0.5
|
||||
1.8333333333333333 0.5
|
||||
2 0.5
|
||||
2.1666666666666666 0.5
|
||||
2.3333333333333333 0.5
|
||||
2.5 0.5
|
||||
2.6666666666666666 0.5
|
||||
2.8333333333333333 0.5
|
||||
3 0.5
|
||||
3.1666666666666666 0.5
|
||||
3.3333333333333333 0.5
|
||||
3.5 0.5
|
||||
3.6666666666666666 0.5
|
||||
3.8333333333333333 0.5
|
||||
4 0.5
|
||||
0 0.66666666666666666
|
||||
0.16666666666666666 0.66666666666666666
|
||||
0.33333333333333333 0.66666666666666666
|
||||
0.5 0.66666666666666666
|
||||
0.66666666666666666 0.66666666666666666
|
||||
0.83333333333333333 0.66666666666666666
|
||||
1 0.66666666666666666
|
||||
1.1666666666666666 0.66666666666666666
|
||||
1.3333333333333333 0.66666666666666666
|
||||
1.5 0.66666666666666666
|
||||
1.6666666666666666 0.66666666666666666
|
||||
1.8333333333333333 0.66666666666666666
|
||||
2 0.66666666666666666
|
||||
2.1666666666666666 0.66666666666666666
|
||||
2.3333333333333333 0.66666666666666666
|
||||
2.5 0.66666666666666666
|
||||
2.6666666666666666 0.66666666666666666
|
||||
2.8333333333333333 0.66666666666666666
|
||||
3 0.66666666666666666
|
||||
3.1666666666666666 0.66666666666666666
|
||||
3.3333333333333333 0.66666666666666666
|
||||
3.5 0.66666666666666666
|
||||
3.6666666666666666 0.66666666666666666
|
||||
3.8333333333333333 0.66666666666666666
|
||||
4 0.66666666666666666
|
||||
0 0.83333333333333333
|
||||
0.16666666666666666 0.83333333333333333
|
||||
0.33333333333333333 0.83333333333333333
|
||||
0.5 0.83333333333333333
|
||||
0.66666666666666666 0.83333333333333333
|
||||
0.83333333333333333 0.83333333333333333
|
||||
1 0.83333333333333333
|
||||
1.1666666666666666 0.83333333333333333
|
||||
1.3333333333333333 0.83333333333333333
|
||||
1.5 0.83333333333333333
|
||||
1.6666666666666666 0.83333333333333333
|
||||
1.8333333333333333 0.83333333333333333
|
||||
2 0.83333333333333333
|
||||
2.1666666666666666 0.83333333333333333
|
||||
2.3333333333333333 0.83333333333333333
|
||||
2.5 0.83333333333333333
|
||||
2.6666666666666666 0.83333333333333333
|
||||
2.8333333333333333 0.83333333333333333
|
||||
3 0.83333333333333333
|
||||
3.1666666666666666 0.83333333333333333
|
||||
3.3333333333333333 0.83333333333333333
|
||||
3.5 0.83333333333333333
|
||||
3.6666666666666666 0.83333333333333333
|
||||
3.8333333333333333 0.83333333333333333
|
||||
4 0.83333333333333333
|
||||
0 1
|
||||
0.16666666666666666 1
|
||||
0.33333333333333333 1
|
||||
0.5 1
|
||||
0.66666666666666666 1
|
||||
0.83333333333333333 1
|
||||
1 1
|
||||
1.1666666666666666 1
|
||||
1.3333333333333333 1
|
||||
1.5 1
|
||||
1.6666666666666666 1
|
||||
1.8333333333333333 1
|
||||
2 1
|
||||
2.1666666666666666 1
|
||||
2.3333333333333333 1
|
||||
2.5 1
|
||||
2.6666666666666666 1
|
||||
2.8333333333333333 1
|
||||
3 1
|
||||
3.1666666666666666 1
|
||||
3.3333333333333333 1
|
||||
3.5 1
|
||||
3.6666666666666666 1
|
||||
3.8333333333333333 1
|
||||
4 1
|
||||
@@ -0,0 +1,549 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
# PRISM = 6
|
||||
#
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
elements
|
||||
288
|
||||
1 2 0 26 25
|
||||
1 2 26 0 1
|
||||
1 2 1 27 26
|
||||
1 2 27 1 2
|
||||
1 2 2 28 27
|
||||
1 2 28 2 3
|
||||
1 2 3 29 28
|
||||
1 2 29 3 4
|
||||
1 2 4 30 29
|
||||
1 2 30 4 5
|
||||
1 2 5 31 30
|
||||
1 2 31 5 6
|
||||
1 2 6 32 31
|
||||
1 2 32 6 7
|
||||
1 2 7 33 32
|
||||
1 2 33 7 8
|
||||
1 2 8 34 33
|
||||
1 2 34 8 9
|
||||
1 2 9 35 34
|
||||
1 2 35 9 10
|
||||
1 2 10 36 35
|
||||
1 2 36 10 11
|
||||
1 2 11 37 36
|
||||
1 2 37 11 12
|
||||
1 2 12 38 37
|
||||
1 2 38 12 13
|
||||
1 2 13 39 38
|
||||
1 2 39 13 14
|
||||
1 2 14 40 39
|
||||
1 2 40 14 15
|
||||
1 2 15 41 40
|
||||
1 2 41 15 16
|
||||
1 2 16 42 41
|
||||
1 2 42 16 17
|
||||
1 2 17 43 42
|
||||
1 2 43 17 18
|
||||
1 2 18 44 43
|
||||
1 2 44 18 19
|
||||
1 2 19 45 44
|
||||
1 2 45 19 20
|
||||
1 2 20 46 45
|
||||
1 2 46 20 21
|
||||
1 2 21 47 46
|
||||
1 2 47 21 22
|
||||
1 2 22 48 47
|
||||
1 2 48 22 23
|
||||
1 2 23 49 48
|
||||
1 2 49 23 24
|
||||
1 2 25 51 50
|
||||
1 2 51 25 26
|
||||
1 2 26 52 51
|
||||
1 2 52 26 27
|
||||
1 2 27 53 52
|
||||
1 2 53 27 28
|
||||
1 2 28 54 53
|
||||
1 2 54 28 29
|
||||
1 2 29 55 54
|
||||
1 2 55 29 30
|
||||
1 2 30 56 55
|
||||
1 2 56 30 31
|
||||
1 2 31 57 56
|
||||
1 2 57 31 32
|
||||
1 2 32 58 57
|
||||
1 2 58 32 33
|
||||
1 2 33 59 58
|
||||
1 2 59 33 34
|
||||
1 2 34 60 59
|
||||
1 2 60 34 35
|
||||
1 2 35 61 60
|
||||
1 2 61 35 36
|
||||
1 2 36 62 61
|
||||
1 2 62 36 37
|
||||
1 2 37 63 62
|
||||
1 2 63 37 38
|
||||
1 2 38 64 63
|
||||
1 2 64 38 39
|
||||
1 2 39 65 64
|
||||
1 2 65 39 40
|
||||
1 2 40 66 65
|
||||
1 2 66 40 41
|
||||
1 2 41 67 66
|
||||
1 2 67 41 42
|
||||
1 2 42 68 67
|
||||
1 2 68 42 43
|
||||
1 2 43 69 68
|
||||
1 2 69 43 44
|
||||
1 2 44 70 69
|
||||
1 2 70 44 45
|
||||
1 2 45 71 70
|
||||
1 2 71 45 46
|
||||
1 2 46 72 71
|
||||
1 2 72 46 47
|
||||
1 2 47 73 72
|
||||
1 2 73 47 48
|
||||
1 2 48 74 73
|
||||
1 2 74 48 49
|
||||
1 2 50 76 75
|
||||
1 2 76 50 51
|
||||
1 2 51 77 76
|
||||
1 2 77 51 52
|
||||
1 2 52 78 77
|
||||
1 2 78 52 53
|
||||
1 2 53 79 78
|
||||
1 2 79 53 54
|
||||
1 2 54 80 79
|
||||
1 2 80 54 55
|
||||
1 2 55 81 80
|
||||
1 2 81 55 56
|
||||
1 2 56 82 81
|
||||
1 2 82 56 57
|
||||
1 2 57 83 82
|
||||
1 2 83 57 58
|
||||
1 2 58 84 83
|
||||
1 2 84 58 59
|
||||
1 2 59 85 84
|
||||
1 2 85 59 60
|
||||
1 2 60 86 85
|
||||
1 2 86 60 61
|
||||
1 2 61 87 86
|
||||
1 2 87 61 62
|
||||
1 2 62 88 87
|
||||
1 2 88 62 63
|
||||
1 2 63 89 88
|
||||
1 2 89 63 64
|
||||
1 2 64 90 89
|
||||
1 2 90 64 65
|
||||
1 2 65 91 90
|
||||
1 2 91 65 66
|
||||
1 2 66 92 91
|
||||
1 2 92 66 67
|
||||
1 2 67 93 92
|
||||
1 2 93 67 68
|
||||
1 2 68 94 93
|
||||
1 2 94 68 69
|
||||
1 2 69 95 94
|
||||
1 2 95 69 70
|
||||
1 2 70 96 95
|
||||
1 2 96 70 71
|
||||
1 2 71 97 96
|
||||
1 2 97 71 72
|
||||
1 2 72 98 97
|
||||
1 2 98 72 73
|
||||
1 2 73 99 98
|
||||
1 2 99 73 74
|
||||
1 2 75 101 100
|
||||
1 2 101 75 76
|
||||
1 2 76 102 101
|
||||
1 2 102 76 77
|
||||
1 2 77 103 102
|
||||
1 2 103 77 78
|
||||
1 2 78 104 103
|
||||
1 2 104 78 79
|
||||
1 2 79 105 104
|
||||
1 2 105 79 80
|
||||
1 2 80 106 105
|
||||
1 2 106 80 81
|
||||
1 2 81 107 106
|
||||
1 2 107 81 82
|
||||
1 2 82 108 107
|
||||
1 2 108 82 83
|
||||
1 2 83 109 108
|
||||
1 2 109 83 84
|
||||
1 2 84 110 109
|
||||
1 2 110 84 85
|
||||
1 2 85 111 110
|
||||
1 2 111 85 86
|
||||
1 2 86 112 111
|
||||
1 2 112 86 87
|
||||
1 2 87 113 112
|
||||
1 2 113 87 88
|
||||
1 2 88 114 113
|
||||
1 2 114 88 89
|
||||
1 2 89 115 114
|
||||
1 2 115 89 90
|
||||
1 2 90 116 115
|
||||
1 2 116 90 91
|
||||
1 2 91 117 116
|
||||
1 2 117 91 92
|
||||
1 2 92 118 117
|
||||
1 2 118 92 93
|
||||
1 2 93 119 118
|
||||
1 2 119 93 94
|
||||
1 2 94 120 119
|
||||
1 2 120 94 95
|
||||
1 2 95 121 120
|
||||
1 2 121 95 96
|
||||
1 2 96 122 121
|
||||
1 2 122 96 97
|
||||
1 2 97 123 122
|
||||
1 2 123 97 98
|
||||
1 2 98 124 123
|
||||
1 2 124 98 99
|
||||
1 2 100 126 125
|
||||
1 2 126 100 101
|
||||
1 2 101 127 126
|
||||
1 2 127 101 102
|
||||
1 2 102 128 127
|
||||
1 2 128 102 103
|
||||
1 2 103 129 128
|
||||
1 2 129 103 104
|
||||
1 2 104 130 129
|
||||
1 2 130 104 105
|
||||
1 2 105 131 130
|
||||
1 2 131 105 106
|
||||
1 2 106 132 131
|
||||
1 2 132 106 107
|
||||
1 2 107 133 132
|
||||
1 2 133 107 108
|
||||
1 2 108 134 133
|
||||
1 2 134 108 109
|
||||
1 2 109 135 134
|
||||
1 2 135 109 110
|
||||
1 2 110 136 135
|
||||
1 2 136 110 111
|
||||
1 2 111 137 136
|
||||
1 2 137 111 112
|
||||
1 2 112 138 137
|
||||
1 2 138 112 113
|
||||
1 2 113 139 138
|
||||
1 2 139 113 114
|
||||
1 2 114 140 139
|
||||
1 2 140 114 115
|
||||
1 2 115 141 140
|
||||
1 2 141 115 116
|
||||
1 2 116 142 141
|
||||
1 2 142 116 117
|
||||
1 2 117 143 142
|
||||
1 2 143 117 118
|
||||
1 2 118 144 143
|
||||
1 2 144 118 119
|
||||
1 2 119 145 144
|
||||
1 2 145 119 120
|
||||
1 2 120 146 145
|
||||
1 2 146 120 121
|
||||
1 2 121 147 146
|
||||
1 2 147 121 122
|
||||
1 2 122 148 147
|
||||
1 2 148 122 123
|
||||
1 2 123 149 148
|
||||
1 2 149 123 124
|
||||
1 2 125 151 150
|
||||
1 2 151 125 126
|
||||
1 2 126 152 151
|
||||
1 2 152 126 127
|
||||
1 2 127 153 152
|
||||
1 2 153 127 128
|
||||
1 2 128 154 153
|
||||
1 2 154 128 129
|
||||
1 2 129 155 154
|
||||
1 2 155 129 130
|
||||
1 2 130 156 155
|
||||
1 2 156 130 131
|
||||
1 2 131 157 156
|
||||
1 2 157 131 132
|
||||
1 2 132 158 157
|
||||
1 2 158 132 133
|
||||
1 2 133 159 158
|
||||
1 2 159 133 134
|
||||
1 2 134 160 159
|
||||
1 2 160 134 135
|
||||
1 2 135 161 160
|
||||
1 2 161 135 136
|
||||
1 2 136 162 161
|
||||
1 2 162 136 137
|
||||
1 2 137 163 162
|
||||
1 2 163 137 138
|
||||
1 2 138 164 163
|
||||
1 2 164 138 139
|
||||
1 2 139 165 164
|
||||
1 2 165 139 140
|
||||
1 2 140 166 165
|
||||
1 2 166 140 141
|
||||
1 2 141 167 166
|
||||
1 2 167 141 142
|
||||
1 2 142 168 167
|
||||
1 2 168 142 143
|
||||
1 2 143 169 168
|
||||
1 2 169 143 144
|
||||
1 2 144 170 169
|
||||
1 2 170 144 145
|
||||
1 2 145 171 170
|
||||
1 2 171 145 146
|
||||
1 2 146 172 171
|
||||
1 2 172 146 147
|
||||
1 2 147 173 172
|
||||
1 2 173 147 148
|
||||
1 2 148 174 173
|
||||
1 2 174 148 149
|
||||
|
||||
boundary
|
||||
60
|
||||
3 1 0 1
|
||||
1 1 1 2
|
||||
1 1 2 3
|
||||
1 1 3 4
|
||||
1 1 4 5
|
||||
1 1 5 6
|
||||
1 1 6 7
|
||||
1 1 7 8
|
||||
1 1 8 9
|
||||
1 1 9 10
|
||||
1 1 10 11
|
||||
1 1 11 12
|
||||
1 1 12 13
|
||||
1 1 13 14
|
||||
1 1 14 15
|
||||
1 1 15 16
|
||||
1 1 16 17
|
||||
1 1 17 18
|
||||
1 1 18 19
|
||||
1 1 19 20
|
||||
1 1 20 21
|
||||
1 1 21 22
|
||||
1 1 22 23
|
||||
1 1 23 24
|
||||
3 1 151 150
|
||||
3 1 152 151
|
||||
3 1 153 152
|
||||
3 1 154 153
|
||||
3 1 155 154
|
||||
3 1 156 155
|
||||
3 1 157 156
|
||||
3 1 158 157
|
||||
3 1 159 158
|
||||
3 1 160 159
|
||||
3 1 161 160
|
||||
3 1 162 161
|
||||
3 1 163 162
|
||||
3 1 164 163
|
||||
3 1 165 164
|
||||
3 1 166 165
|
||||
3 1 167 166
|
||||
3 1 168 167
|
||||
3 1 169 168
|
||||
3 1 170 169
|
||||
3 1 171 170
|
||||
3 1 172 171
|
||||
3 1 173 172
|
||||
3 1 174 173
|
||||
3 1 25 0
|
||||
3 1 50 25
|
||||
3 1 75 50
|
||||
3 1 100 75
|
||||
3 1 125 100
|
||||
3 1 150 125
|
||||
2 1 24 49
|
||||
2 1 49 74
|
||||
2 1 74 99
|
||||
2 1 99 124
|
||||
2 1 124 149
|
||||
2 1 149 174
|
||||
|
||||
vertices
|
||||
175
|
||||
2
|
||||
0 0
|
||||
0.1666666666666666 0
|
||||
0.3333333333333333 0
|
||||
0.5 0
|
||||
0.6666666666666666 0
|
||||
0.8333333333333333 0
|
||||
1 0
|
||||
1.1666667 0
|
||||
1.333333333333333 0
|
||||
1.5 0
|
||||
1.666666666666666 0
|
||||
1.8333333 0
|
||||
2 0
|
||||
2.1666667 0
|
||||
2.333333333333333 0
|
||||
2.5 0
|
||||
2.666666666666666 0
|
||||
2.8333333 0
|
||||
3 0
|
||||
3.1666667 0
|
||||
3.333333333333333 0
|
||||
3.5 0
|
||||
3.666666666666666 0
|
||||
3.8333333 0
|
||||
4 0
|
||||
0 0.1666666666666666
|
||||
0.1666666666666666 0.1666666666666666
|
||||
0.3333333333333333 0.1666666666666666
|
||||
0.5 0.1666666666666666
|
||||
0.6666666666666666 0.1666666666666666
|
||||
0.8333333333333333 0.1666666666666666
|
||||
1 0.1666666666666666
|
||||
1.1666667 0.1666666666666666
|
||||
1.333333333333333 0.1666666666666666
|
||||
1.5 0.1666666666666666
|
||||
1.666666666666666 0.1666666666666666
|
||||
1.8333333 0.1666666666666666
|
||||
2 0.1666666666666666
|
||||
2.1666667 0.1666666666666666
|
||||
2.333333333333333 0.1666666666666666
|
||||
2.5 0.1666666666666666
|
||||
2.666666666666666 0.1666666666666666
|
||||
2.8333333 0.1666666666666666
|
||||
3 0.1666666666666666
|
||||
3.1666667 0.1666666666666666
|
||||
3.333333333333333 0.1666666666666666
|
||||
3.5 0.1666666666666666
|
||||
3.666666666666666 0.1666666666666666
|
||||
3.8333333 0.1666666666666666
|
||||
4 0.1666666666666666
|
||||
0 0.3333333333333333
|
||||
0.1666666666666666 0.3333333333333333
|
||||
0.3333333333333333 0.3333333333333333
|
||||
0.5 0.3333333333333333
|
||||
0.6666666666666666 0.3333333333333333
|
||||
0.8333333333333333 0.3333333333333333
|
||||
1 0.3333333333333333
|
||||
1.1666667 0.3333333333333333
|
||||
1.333333333333333 0.3333333333333333
|
||||
1.5 0.3333333333333333
|
||||
1.666666666666666 0.3333333333333333
|
||||
1.8333333 0.3333333333333333
|
||||
2 0.3333333333333333
|
||||
2.1666667 0.3333333333333333
|
||||
2.333333333333333 0.3333333333333333
|
||||
2.5 0.3333333333333333
|
||||
2.666666666666666 0.3333333333333333
|
||||
2.8333333 0.3333333333333333
|
||||
3 0.3333333333333333
|
||||
3.1666667 0.3333333333333333
|
||||
3.333333333333333 0.3333333333333333
|
||||
3.5 0.3333333333333333
|
||||
3.666666666666666 0.3333333333333333
|
||||
3.8333333 0.3333333333333333
|
||||
4 0.3333333333333333
|
||||
0 0.5
|
||||
0.1666666666666666 0.5
|
||||
0.3333333333333333 0.5
|
||||
0.5 0.5
|
||||
0.6666666666666666 0.5
|
||||
0.8333333333333333 0.5
|
||||
1 0.5
|
||||
1.1666667 0.5
|
||||
1.333333333333333 0.5
|
||||
1.5 0.5
|
||||
1.666666666666666 0.5
|
||||
1.8333333 0.5
|
||||
2 0.5
|
||||
2.1666667 0.5
|
||||
2.333333333333333 0.5
|
||||
2.5 0.5
|
||||
2.666666666666666 0.5
|
||||
2.8333333 0.5
|
||||
3 0.5
|
||||
3.1666667 0.5
|
||||
3.333333333333333 0.5
|
||||
3.5 0.5
|
||||
3.666666666666666 0.5
|
||||
3.8333333 0.5
|
||||
4 0.5
|
||||
0 0.6666666666666666
|
||||
0.1666666666666666 0.6666666666666666
|
||||
0.3333333333333333 0.6666666666666666
|
||||
0.5 0.6666666666666666
|
||||
0.6666666666666666 0.6666666666666666
|
||||
0.8333333333333333 0.6666666666666666
|
||||
1 0.6666666666666666
|
||||
1.1666667 0.6666666666666666
|
||||
1.333333333333333 0.6666666666666666
|
||||
1.5 0.6666666666666666
|
||||
1.666666666666666 0.6666666666666666
|
||||
1.8333333 0.6666666666666666
|
||||
2 0.6666666666666666
|
||||
2.1666667 0.6666666666666666
|
||||
2.333333333333333 0.6666666666666666
|
||||
2.5 0.6666666666666666
|
||||
2.666666666666666 0.6666666666666666
|
||||
2.8333333 0.6666666666666666
|
||||
3 0.6666666666666666
|
||||
3.1666667 0.6666666666666666
|
||||
3.333333333333333 0.6666666666666666
|
||||
3.5 0.6666666666666666
|
||||
3.666666666666666 0.6666666666666666
|
||||
3.8333333 0.6666666666666666
|
||||
4 0.6666666666666666
|
||||
0 0.8333333333333333
|
||||
0.1666666666666666 0.8333333333333333
|
||||
0.3333333333333333 0.8333333333333333
|
||||
0.5 0.8333333333333333
|
||||
0.6666666666666666 0.8333333333333333
|
||||
0.8333333333333333 0.8333333333333333
|
||||
1 0.8333333333333333
|
||||
1.1666667 0.8333333333333333
|
||||
1.333333333333333 0.8333333333333333
|
||||
1.5 0.8333333333333333
|
||||
1.666666666666666 0.8333333333333333
|
||||
1.8333333 0.8333333333333333
|
||||
2 0.8333333333333333
|
||||
2.1666667 0.8333333333333333
|
||||
2.333333333333333 0.8333333333333333
|
||||
2.5 0.8333333333333333
|
||||
2.666666666666666 0.8333333333333333
|
||||
2.8333333 0.8333333333333333
|
||||
3 0.8333333333333333
|
||||
3.1666667 0.8333333333333333
|
||||
3.333333333333333 0.8333333333333333
|
||||
3.5 0.8333333333333333
|
||||
3.666666666666666 0.8333333333333333
|
||||
3.8333333 0.8333333333333333
|
||||
4 0.8333333333333333
|
||||
0 1
|
||||
0.1666666666666666 1
|
||||
0.3333333333333333 1
|
||||
0.5 1
|
||||
0.6666666666666666 1
|
||||
0.8333333333333333 1
|
||||
1 1
|
||||
1.1666667 1
|
||||
1.333333333333333 1
|
||||
1.5 1
|
||||
1.666666666666666 1
|
||||
1.8333333 1
|
||||
2 1
|
||||
2.1666667 1
|
||||
2.333333333333333 1
|
||||
2.5 1
|
||||
2.666666666666666 1
|
||||
2.8333333 1
|
||||
3 1
|
||||
3.1666667 1
|
||||
3.333333333333333 1
|
||||
3.5 1
|
||||
3.666666666666666 1
|
||||
3.8333333 1
|
||||
4 1
|
||||
@@ -0,0 +1,7 @@
|
||||
MFEM INLINE mesh v1.0
|
||||
|
||||
type = quad
|
||||
nx = 3
|
||||
ny = 3
|
||||
sx = 1.0
|
||||
sy = 1.0
|
||||
@@ -0,0 +1,5 @@
|
||||
MFEM INLINE mesh v1.0
|
||||
|
||||
type = segment
|
||||
nx = 3
|
||||
sx = 1.0
|
||||
@@ -0,0 +1,7 @@
|
||||
MFEM INLINE mesh v1.0
|
||||
|
||||
type = tri
|
||||
nx = 3
|
||||
ny = 3
|
||||
sx = 1.0
|
||||
sy = 1.0
|
||||
@@ -0,0 +1,7 @@
|
||||
MFEM INLINE mesh v1.0
|
||||
|
||||
type = quad
|
||||
nx = 4
|
||||
ny = 4
|
||||
sx = 1.0
|
||||
sy = 1.0
|
||||
@@ -0,0 +1,5 @@
|
||||
MFEM INLINE mesh v1.0
|
||||
|
||||
type = segment
|
||||
nx = 4
|
||||
sx = 1.0
|
||||
@@ -0,0 +1,7 @@
|
||||
MFEM INLINE mesh v1.0
|
||||
|
||||
type = tri
|
||||
nx = 4
|
||||
ny = 4
|
||||
sx = 1.0
|
||||
sy = 1.0
|
||||
@@ -0,0 +1,9 @@
|
||||
MFEM INLINE mesh v1.0
|
||||
|
||||
type = hex
|
||||
nx = 4
|
||||
ny = 4
|
||||
nz = 4
|
||||
sx = 1.0
|
||||
sy = 1.0
|
||||
sz = 1.0
|
||||
@@ -0,0 +1,83 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
# PRISM = 6
|
||||
#
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
elements
|
||||
16
|
||||
1 3 0 1 6 5
|
||||
1 3 1 2 7 6
|
||||
1 3 6 7 12 11
|
||||
1 3 5 6 11 10
|
||||
1 3 10 11 16 15
|
||||
1 3 15 16 21 20
|
||||
1 3 16 17 22 21
|
||||
1 3 11 12 17 16
|
||||
1 3 12 13 18 17
|
||||
1 3 17 18 23 22
|
||||
1 3 18 19 24 23
|
||||
1 3 13 14 19 18
|
||||
1 3 8 9 14 13
|
||||
1 3 7 8 13 12
|
||||
1 3 2 3 8 7
|
||||
1 3 3 4 9 8
|
||||
|
||||
boundary
|
||||
16
|
||||
1 1 0 1
|
||||
1 1 1 2
|
||||
1 1 2 3
|
||||
1 1 3 4
|
||||
2 1 21 20
|
||||
2 1 22 21
|
||||
2 1 23 22
|
||||
2 1 24 23
|
||||
1 1 5 0
|
||||
1 1 10 5
|
||||
1 1 15 10
|
||||
1 1 20 15
|
||||
2 1 4 9
|
||||
2 1 9 14
|
||||
2 1 14 19
|
||||
2 1 19 24
|
||||
|
||||
vertices
|
||||
25
|
||||
2
|
||||
0 0
|
||||
0.25 0
|
||||
0.5 0
|
||||
0.75 0
|
||||
1 0
|
||||
0 0.25
|
||||
0.25 0.25
|
||||
0.5 0.25
|
||||
0.75 0.25
|
||||
1 0.25
|
||||
0 0.5
|
||||
0.25 0.5
|
||||
0.5 0.5
|
||||
0.75 0.5
|
||||
1 0.5
|
||||
0 0.75
|
||||
0.25 0.75
|
||||
0.5 0.75
|
||||
0.75 0.75
|
||||
1 0.75
|
||||
0 1
|
||||
0.25 1
|
||||
0.5 1
|
||||
0.75 1
|
||||
1 1
|
||||
@@ -0,0 +1,83 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
# PRISM = 6
|
||||
#
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
elements
|
||||
16
|
||||
1 3 0 1 6 5
|
||||
1 3 1 2 7 6
|
||||
1 3 6 7 12 11
|
||||
1 3 5 6 11 10
|
||||
1 3 10 11 16 15
|
||||
1 3 15 16 21 20
|
||||
1 3 16 17 22 21
|
||||
1 3 11 12 17 16
|
||||
1 3 12 13 18 17
|
||||
1 3 17 18 23 22
|
||||
1 3 18 19 24 23
|
||||
1 3 13 14 19 18
|
||||
1 3 8 9 14 13
|
||||
1 3 7 8 13 12
|
||||
1 3 2 3 8 7
|
||||
1 3 3 4 9 8
|
||||
|
||||
boundary
|
||||
16
|
||||
2 1 0 1
|
||||
2 1 1 2
|
||||
2 1 2 3
|
||||
2 1 3 4
|
||||
2 1 21 20
|
||||
2 1 22 21
|
||||
2 1 23 22
|
||||
2 1 24 23
|
||||
2 1 5 0
|
||||
2 1 10 5
|
||||
2 1 15 10
|
||||
2 1 20 15
|
||||
2 1 4 9
|
||||
2 1 9 14
|
||||
2 1 14 19
|
||||
2 1 19 24
|
||||
|
||||
vertices
|
||||
25
|
||||
2
|
||||
0 0
|
||||
0.25 0
|
||||
0.5 0
|
||||
0.75 0
|
||||
1 0
|
||||
0 0.25
|
||||
0.25 0.25
|
||||
0.5 0.25
|
||||
0.75 0.25
|
||||
1 0.25
|
||||
0 0.5
|
||||
0.25 0.5
|
||||
0.5 0.5
|
||||
0.75 0.5
|
||||
1 0.5
|
||||
0 0.75
|
||||
0.25 0.75
|
||||
0.5 0.75
|
||||
0.75 0.75
|
||||
1 0.75
|
||||
0 1
|
||||
0.25 1
|
||||
0.5 1
|
||||
0.75 1
|
||||
1 1
|
||||
@@ -0,0 +1,88 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
#
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
# format: <attribute> <geometry type> <vertex 0> <vertex 1> ...
|
||||
elements
|
||||
9
|
||||
1 3 0 1 4 3
|
||||
2 3 1 2 5 4
|
||||
3 3 2 0 3 5
|
||||
4 3 3 4 7 6
|
||||
5 3 4 5 8 7
|
||||
6 3 5 3 6 8
|
||||
7 3 6 7 1 0
|
||||
8 3 7 8 2 1
|
||||
9 3 8 6 0 2
|
||||
|
||||
boundary
|
||||
0
|
||||
|
||||
vertices
|
||||
9
|
||||
|
||||
nodes
|
||||
FiniteElementSpace
|
||||
FiniteElementCollection: L2_T1_2D_P1
|
||||
VDim: 2
|
||||
Ordering: 1
|
||||
|
||||
0 0
|
||||
0.3333333333333333 0
|
||||
0 0.3333333333333333
|
||||
0.3333333333333333 0.3333333333333333
|
||||
|
||||
0.3333333333333333 0
|
||||
0.6666666666666666 0
|
||||
0.3333333333333333 0.3333333333333333
|
||||
0.6666666666666666 0.3333333333333333
|
||||
|
||||
0.6666666666666666 0
|
||||
1 0
|
||||
0.6666666666666666 0.3333333333333333
|
||||
1 0.3333333333333333
|
||||
|
||||
0 0.3333333333333333
|
||||
0.3333333333333333 0.3333333333333333
|
||||
0 0.6666666666666666
|
||||
0.3333333333333333 0.6666666666666666
|
||||
|
||||
0.3333333333333333 0.3333333333333333
|
||||
0.6666666666666666 0.3333333333333333
|
||||
0.3333333333333333 0.6666666666666666
|
||||
0.6666666666666666 0.6666666666666666
|
||||
|
||||
0.6666666666666666 0.3333333333333333
|
||||
1 0.3333333333333333
|
||||
0.6666666666666666 0.6666666666666666
|
||||
1 0.6666666666666666
|
||||
|
||||
0 0.6666666666666666
|
||||
0.3333333333333333 0.6666666666666666
|
||||
0 1
|
||||
0.3333333333333333 1
|
||||
|
||||
0.3333333333333333 0.6666666666666666
|
||||
0.6666666666666666 0.6666666666666666
|
||||
0.3333333333333333 1
|
||||
0.6666666666666666 1
|
||||
|
||||
0.6666666666666666 0.6666666666666666
|
||||
1 0.6666666666666666
|
||||
0.6666666666666666 1
|
||||
1 1
|
||||
|
||||
0.3333333333333333
|
||||
0.6666666666666666
|
||||
@@ -0,0 +1,38 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
#
|
||||
|
||||
dimension
|
||||
1
|
||||
|
||||
# format: <attribute> <geometry type> <vertex 0> <vertex 1> ...
|
||||
elements
|
||||
3
|
||||
1 1 0 1
|
||||
1 1 1 2
|
||||
1 1 2 0
|
||||
|
||||
boundary
|
||||
0
|
||||
|
||||
vertices
|
||||
3
|
||||
|
||||
nodes
|
||||
FiniteElementSpace
|
||||
FiniteElementCollection: L2_T1_1D_P1
|
||||
VDim: 1
|
||||
Ordering: 1
|
||||
|
||||
0.0000000000000000 0.3333333333333333
|
||||
0.3333333333333333 0.6666666666666666
|
||||
0.6666666666666666 1.0000000000000000
|
||||
@@ -0,0 +1,121 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
#
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
# format: <attribute> <geometry type> <vertex 0> <vertex 1> ...
|
||||
elements
|
||||
18
|
||||
1 2 0 1 4
|
||||
1 2 0 4 3
|
||||
1 2 1 2 5
|
||||
1 2 1 5 4
|
||||
1 2 2 0 3
|
||||
1 2 2 3 5
|
||||
1 2 3 4 7
|
||||
1 2 3 7 6
|
||||
1 2 4 5 8
|
||||
1 2 4 8 7
|
||||
1 2 5 3 6
|
||||
1 2 5 6 8
|
||||
1 2 6 7 1
|
||||
1 2 6 1 0
|
||||
1 2 7 8 2
|
||||
1 2 7 2 1
|
||||
1 2 8 6 0
|
||||
1 2 8 0 2
|
||||
|
||||
boundary
|
||||
0
|
||||
|
||||
vertices
|
||||
9
|
||||
|
||||
nodes
|
||||
FiniteElementSpace
|
||||
FiniteElementCollection: L2_T1_2D_P1
|
||||
VDim: 2
|
||||
Ordering: 1
|
||||
|
||||
0.0000000000000000 0.0000000000000000
|
||||
0.3333333333333333 0.0000000000000000
|
||||
0.3333333333333333 0.3333333333333333
|
||||
|
||||
0.0000000000000000 0.0000000000000000
|
||||
0.3333333333333333 0.3333333333333333
|
||||
0.0000000000000000 0.3333333333333333
|
||||
|
||||
0.3333333333333333 0.0000000000000000
|
||||
0.6666666666666666 0.0000000000000000
|
||||
0.6666666666666666 0.3333333333333333
|
||||
|
||||
0.3333333333333333 0.0000000000000000
|
||||
0.6666666666666666 0.3333333333333333
|
||||
0.3333333333333333 0.3333333333333333
|
||||
|
||||
0.6666666666666666 0.0000000000000000
|
||||
1.0000000000000000 0.0000000000000000
|
||||
1.0000000000000000 0.3333333333333333
|
||||
|
||||
0.6666666666666666 0.0000000000000000
|
||||
1.0000000000000000 0.3333333333333333
|
||||
0.6666666666666666 0.3333333333333333
|
||||
|
||||
0.0000000000000000 0.3333333333333333
|
||||
0.3333333333333333 0.3333333333333333
|
||||
0.3333333333333333 0.6666666666666666
|
||||
|
||||
0.0000000000000000 0.3333333333333333
|
||||
0.3333333333333333 0.6666666666666666
|
||||
0.0000000000000000 0.6666666666666666
|
||||
|
||||
0.3333333333333333 0.3333333333333333
|
||||
0.6666666666666666 0.3333333333333333
|
||||
0.6666666666666666 0.6666666666666666
|
||||
|
||||
0.3333333333333333 0.3333333333333333
|
||||
0.6666666666666666 0.6666666666666666
|
||||
0.3333333333333333 0.6666666666666666
|
||||
|
||||
0.6666666666666666 0.3333333333333333
|
||||
1.0000000000000000 0.3333333333333333
|
||||
1.0000000000000000 0.6666666666666666
|
||||
|
||||
0.6666666666666666 0.3333333333333333
|
||||
1.0000000000000000 0.6666666666666666
|
||||
0.6666666666666666 0.6666666666666666
|
||||
|
||||
0.0000000000000000 0.6666666666666666
|
||||
0.3333333333333333 0.6666666666666666
|
||||
0.3333333333333333 1.0000000000000000
|
||||
|
||||
0.0000000000000000 0.6666666666666666
|
||||
0.3333333333333333 1.0000000000000000
|
||||
0.0000000000000000 1.0000000000000000
|
||||
|
||||
0.3333333333333333 0.6666666666666666
|
||||
0.6666666666666666 0.6666666666666666
|
||||
0.6666666666666666 1.0000000000000000
|
||||
|
||||
0.3333333333333333 0.6666666666666666
|
||||
0.6666666666666666 1.0000000000000000
|
||||
0.3333333333333333 1.0000000000000000
|
||||
|
||||
0.6666666666666666 0.6666666666666666
|
||||
1.0000000000000000 0.6666666666666666
|
||||
1.0000000000000000 1.0000000000000000
|
||||
|
||||
0.6666666666666666 0.6666666666666666
|
||||
1.0000000000000000 1.0000000000000000
|
||||
0.6666666666666666 1.0000000000000000
|
||||
@@ -0,0 +1,127 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
#
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
# format: <attribute> <geometry type> <vertex 0> <vertex 1> ...
|
||||
elements
|
||||
16
|
||||
1 3 0 1 5 4
|
||||
2 3 1 2 6 5
|
||||
3 3 2 3 7 6
|
||||
4 3 3 0 4 7
|
||||
5 3 4 5 9 8
|
||||
6 3 5 6 10 9
|
||||
7 3 6 7 11 10
|
||||
8 3 7 4 8 11
|
||||
9 3 8 9 13 12
|
||||
10 3 9 10 14 13
|
||||
11 3 10 11 15 14
|
||||
12 3 11 8 12 15
|
||||
13 3 12 13 1 0
|
||||
14 3 13 14 2 1
|
||||
15 3 14 15 3 2
|
||||
16 3 15 12 0 3
|
||||
|
||||
boundary
|
||||
0
|
||||
|
||||
vertices
|
||||
16
|
||||
|
||||
nodes
|
||||
FiniteElementSpace
|
||||
FiniteElementCollection: L2_T1_2D_P1
|
||||
VDim: 2
|
||||
Ordering: 1
|
||||
|
||||
0 0
|
||||
0.25 0
|
||||
0 0.25
|
||||
0.25 0.25
|
||||
|
||||
0.25 0
|
||||
0.5 0
|
||||
0.25 0.25
|
||||
0.5 0.25
|
||||
|
||||
0.5 0
|
||||
0.75 0
|
||||
0.5 0.25
|
||||
0.75 0.25
|
||||
|
||||
0.75 0
|
||||
1 0
|
||||
0.75 0.25
|
||||
1 0.25
|
||||
|
||||
0 0.25
|
||||
0.25 0.25
|
||||
0 0.5
|
||||
0.25 0.5
|
||||
|
||||
0.25 0.25
|
||||
0.5 0.25
|
||||
0.25 0.5
|
||||
0.5 0.5
|
||||
|
||||
0.5 0.25
|
||||
0.75 0.25
|
||||
0.5 0.5
|
||||
0.75 0.5
|
||||
|
||||
0.75 0.25
|
||||
1 0.25
|
||||
0.75 0.5
|
||||
1 0.5
|
||||
|
||||
0 0.5
|
||||
0.25 0.5
|
||||
0 0.75
|
||||
0.25 0.75
|
||||
|
||||
0.25 0.5
|
||||
0.5 0.5
|
||||
0.25 0.75
|
||||
0.5 0.75
|
||||
|
||||
0.5 0.5
|
||||
0.75 0.5
|
||||
0.5 0.75
|
||||
0.75 0.75
|
||||
|
||||
0.75 0.5
|
||||
1 0.5
|
||||
0.75 0.75
|
||||
1 0.75
|
||||
|
||||
0 0.75
|
||||
0.25 0.75
|
||||
0 1
|
||||
0.25 1
|
||||
|
||||
0.25 0.75
|
||||
0.5 0.75
|
||||
0.25 1
|
||||
0.5 1
|
||||
|
||||
0.5 0.75
|
||||
0.75 0.75
|
||||
0.5 1
|
||||
0.75 1
|
||||
|
||||
0.75 0.75
|
||||
1 0.75
|
||||
0.75 1
|
||||
1 1
|
||||
@@ -0,0 +1,40 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
#
|
||||
|
||||
dimension
|
||||
1
|
||||
|
||||
# format: <attribute> <geometry type> <vertex 0> <vertex 1> ...
|
||||
elements
|
||||
4
|
||||
1 1 0 1
|
||||
1 1 1 2
|
||||
1 1 2 3
|
||||
1 1 3 0
|
||||
|
||||
boundary
|
||||
0
|
||||
|
||||
vertices
|
||||
4
|
||||
|
||||
nodes
|
||||
FiniteElementSpace
|
||||
FiniteElementCollection: L2_T1_1D_P1
|
||||
VDim: 1
|
||||
Ordering: 1
|
||||
|
||||
0 0.25
|
||||
0.25 0.5
|
||||
0.5 0.75
|
||||
0.75 1
|
||||
@@ -0,0 +1,191 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
#
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
# format: <attribute> <geometry type> <vertex 0> <vertex 1> ...
|
||||
elements
|
||||
32
|
||||
1 2 0 1 5
|
||||
1 2 0 5 4
|
||||
1 2 1 2 6
|
||||
1 2 1 6 5
|
||||
1 2 2 3 7
|
||||
1 2 2 7 6
|
||||
1 2 3 0 4
|
||||
1 2 3 4 7
|
||||
1 2 4 5 9
|
||||
1 2 4 9 8
|
||||
1 2 5 6 10
|
||||
1 2 5 10 9
|
||||
1 2 6 7 11
|
||||
1 2 6 11 10
|
||||
1 2 7 4 8
|
||||
1 2 7 8 11
|
||||
1 2 8 9 13
|
||||
1 2 8 13 12
|
||||
1 2 9 10 14
|
||||
1 2 9 14 13
|
||||
1 2 10 11 15
|
||||
1 2 10 15 14
|
||||
1 2 11 8 12
|
||||
1 2 11 12 15
|
||||
1 2 12 13 1
|
||||
1 2 12 1 0
|
||||
1 2 13 14 2
|
||||
1 2 13 2 1
|
||||
1 2 14 15 3
|
||||
1 2 14 3 2
|
||||
1 2 15 12 0
|
||||
1 2 15 0 3
|
||||
|
||||
boundary
|
||||
0
|
||||
|
||||
vertices
|
||||
16
|
||||
|
||||
nodes
|
||||
FiniteElementSpace
|
||||
FiniteElementCollection: L2_T1_2D_P1
|
||||
VDim: 2
|
||||
Ordering: 1
|
||||
|
||||
0 0
|
||||
0.25 0
|
||||
0.25 0.25
|
||||
|
||||
0 0
|
||||
0.25 0.25
|
||||
0 0.25
|
||||
|
||||
0.25 0
|
||||
0.5 0
|
||||
0.5 0.25
|
||||
|
||||
0.25 0
|
||||
0.5 0.25
|
||||
0.25 0.25
|
||||
|
||||
0.5 0
|
||||
0.75 0
|
||||
0.75 0.25
|
||||
|
||||
0.5 0
|
||||
0.75 0.25
|
||||
0.5 0.25
|
||||
|
||||
0.75 0
|
||||
1 0
|
||||
1 0.25
|
||||
|
||||
0.75 0
|
||||
1 0.25
|
||||
0.75 0.25
|
||||
|
||||
0 0.25
|
||||
0.25 0.25
|
||||
0.25 0.5
|
||||
|
||||
0 0.25
|
||||
0.25 0.5
|
||||
0 0.5
|
||||
|
||||
0.25 0.25
|
||||
0.5 0.25
|
||||
0.5 0.5
|
||||
|
||||
0.25 0.25
|
||||
0.5 0.5
|
||||
0.25 0.5
|
||||
|
||||
0.5 0.25
|
||||
0.75 0.25
|
||||
0.75 0.5
|
||||
|
||||
0.5 0.25
|
||||
0.75 0.5
|
||||
0.5 0.5
|
||||
|
||||
0.75 0.25
|
||||
1 0.25
|
||||
1 0.5
|
||||
|
||||
0.75 0.25
|
||||
1 0.5
|
||||
0.75 0.5
|
||||
|
||||
0 0.5
|
||||
0.25 0.5
|
||||
0.25 0.75
|
||||
|
||||
0 0.5
|
||||
0.25 0.75
|
||||
0 0.75
|
||||
|
||||
0.25 0.5
|
||||
0.5 0.5
|
||||
0.5 0.75
|
||||
|
||||
0.25 0.5
|
||||
0.5 0.75
|
||||
0.25 0.75
|
||||
|
||||
0.5 0.5
|
||||
0.75 0.5
|
||||
0.75 0.75
|
||||
|
||||
0.5 0.5
|
||||
0.75 0.75
|
||||
0.5 0.75
|
||||
|
||||
0.75 0.5
|
||||
1 0.5
|
||||
1 0.75
|
||||
|
||||
0.75 0.5
|
||||
1 0.75
|
||||
0.75 0.75
|
||||
|
||||
0 0.75
|
||||
0.25 0.75
|
||||
0.25 1
|
||||
|
||||
0 0.75
|
||||
0.25 1
|
||||
0 1
|
||||
|
||||
0.25 0.75
|
||||
0.5 0.75
|
||||
0.5 1
|
||||
|
||||
0.25 0.75
|
||||
0.5 1
|
||||
0.25 1
|
||||
|
||||
0.5 0.75
|
||||
0.75 0.75
|
||||
0.75 1
|
||||
|
||||
0.5 0.75
|
||||
0.75 1
|
||||
0.5 1
|
||||
|
||||
0.75 0.75
|
||||
1 0.75
|
||||
1 1
|
||||
|
||||
0.75 0.75
|
||||
1 1
|
||||
0.75 1
|
||||
@@ -0,0 +1,37 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
# PRISM = 6
|
||||
#
|
||||
|
||||
dimension
|
||||
1
|
||||
|
||||
elements
|
||||
4
|
||||
1 1 0 1
|
||||
1 1 1 2
|
||||
1 1 2 3
|
||||
1 1 3 4
|
||||
|
||||
boundary
|
||||
2
|
||||
3 0 0
|
||||
3 0 4
|
||||
|
||||
vertices
|
||||
5
|
||||
1
|
||||
0
|
||||
0.25
|
||||
0.5
|
||||
0.75
|
||||
1
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,229 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
# PRISM = 6
|
||||
#
|
||||
|
||||
dimension
|
||||
1
|
||||
|
||||
elements
|
||||
100
|
||||
1 1 0 1
|
||||
1 1 1 2
|
||||
1 1 2 3
|
||||
1 1 3 4
|
||||
1 1 4 5
|
||||
1 1 5 6
|
||||
1 1 6 7
|
||||
1 1 7 8
|
||||
1 1 8 9
|
||||
1 1 9 10
|
||||
1 1 10 11
|
||||
1 1 11 12
|
||||
1 1 12 13
|
||||
1 1 13 14
|
||||
1 1 14 15
|
||||
1 1 15 16
|
||||
1 1 16 17
|
||||
1 1 17 18
|
||||
1 1 18 19
|
||||
1 1 19 20
|
||||
1 1 20 21
|
||||
1 1 21 22
|
||||
1 1 22 23
|
||||
1 1 23 24
|
||||
1 1 24 25
|
||||
1 1 25 26
|
||||
1 1 26 27
|
||||
1 1 27 28
|
||||
1 1 28 29
|
||||
1 1 29 30
|
||||
1 1 30 31
|
||||
1 1 31 32
|
||||
1 1 32 33
|
||||
1 1 33 34
|
||||
1 1 34 35
|
||||
1 1 35 36
|
||||
1 1 36 37
|
||||
1 1 37 38
|
||||
1 1 38 39
|
||||
1 1 39 40
|
||||
1 1 40 41
|
||||
1 1 41 42
|
||||
1 1 42 43
|
||||
1 1 43 44
|
||||
1 1 44 45
|
||||
1 1 45 46
|
||||
1 1 46 47
|
||||
1 1 47 48
|
||||
1 1 48 49
|
||||
1 1 49 50
|
||||
1 1 50 51
|
||||
1 1 51 52
|
||||
1 1 52 53
|
||||
1 1 53 54
|
||||
1 1 54 55
|
||||
1 1 55 56
|
||||
1 1 56 57
|
||||
1 1 57 58
|
||||
1 1 58 59
|
||||
1 1 59 60
|
||||
1 1 60 61
|
||||
1 1 61 62
|
||||
1 1 62 63
|
||||
1 1 63 64
|
||||
1 1 64 65
|
||||
1 1 65 66
|
||||
1 1 66 67
|
||||
1 1 67 68
|
||||
1 1 68 69
|
||||
1 1 69 70
|
||||
1 1 70 71
|
||||
1 1 71 72
|
||||
1 1 72 73
|
||||
1 1 73 74
|
||||
1 1 74 75
|
||||
1 1 75 76
|
||||
1 1 76 77
|
||||
1 1 77 78
|
||||
1 1 78 79
|
||||
1 1 79 80
|
||||
1 1 80 81
|
||||
1 1 81 82
|
||||
1 1 82 83
|
||||
1 1 83 84
|
||||
1 1 84 85
|
||||
1 1 85 86
|
||||
1 1 86 87
|
||||
1 1 87 88
|
||||
1 1 88 89
|
||||
1 1 89 90
|
||||
1 1 90 91
|
||||
1 1 91 92
|
||||
1 1 92 93
|
||||
1 1 93 94
|
||||
1 1 94 95
|
||||
1 1 95 96
|
||||
1 1 96 97
|
||||
1 1 97 98
|
||||
1 1 98 99
|
||||
1 1 99 100
|
||||
|
||||
boundary
|
||||
2
|
||||
1 0 0
|
||||
1 0 100
|
||||
|
||||
vertices
|
||||
101
|
||||
1
|
||||
0
|
||||
0.01
|
||||
0.02
|
||||
0.03
|
||||
0.04
|
||||
0.05
|
||||
0.06
|
||||
0.07
|
||||
0.08
|
||||
0.09
|
||||
0.10
|
||||
0.11
|
||||
0.12
|
||||
0.13
|
||||
0.14
|
||||
0.15
|
||||
0.16
|
||||
0.17
|
||||
0.18
|
||||
0.19
|
||||
0.20
|
||||
0.21
|
||||
0.22
|
||||
0.23
|
||||
0.24
|
||||
0.25
|
||||
0.26
|
||||
0.27
|
||||
0.28
|
||||
0.29
|
||||
0.30
|
||||
0.31
|
||||
0.32
|
||||
0.33
|
||||
0.34
|
||||
0.35
|
||||
0.36
|
||||
0.37
|
||||
0.38
|
||||
0.39
|
||||
0.40
|
||||
0.41
|
||||
0.42
|
||||
0.43
|
||||
0.44
|
||||
0.45
|
||||
0.46
|
||||
0.47
|
||||
0.48
|
||||
0.49
|
||||
0.50
|
||||
0.51
|
||||
0.52
|
||||
0.53
|
||||
0.54
|
||||
0.55
|
||||
0.56
|
||||
0.57
|
||||
0.58
|
||||
0.59
|
||||
0.60
|
||||
0.61
|
||||
0.62
|
||||
0.63
|
||||
0.64
|
||||
0.65
|
||||
0.66
|
||||
0.67
|
||||
0.68
|
||||
0.69
|
||||
0.70
|
||||
0.71
|
||||
0.72
|
||||
0.73
|
||||
0.74
|
||||
0.75
|
||||
0.76
|
||||
0.77
|
||||
0.78
|
||||
0.79
|
||||
0.80
|
||||
0.81
|
||||
0.82
|
||||
0.83
|
||||
0.84
|
||||
0.85
|
||||
0.86
|
||||
0.87
|
||||
0.88
|
||||
0.89
|
||||
0.90
|
||||
0.91
|
||||
0.92
|
||||
0.93
|
||||
0.94
|
||||
0.95
|
||||
0.96
|
||||
0.97
|
||||
0.98
|
||||
0.99
|
||||
1
|
||||
@@ -0,0 +1,311 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
# PRISM = 6
|
||||
#
|
||||
|
||||
dimension
|
||||
3
|
||||
|
||||
elements
|
||||
64
|
||||
1 5 0 1 6 5 25 26 31 30
|
||||
1 5 25 26 31 30 50 51 56 55
|
||||
1 5 26 27 32 31 51 52 57 56
|
||||
1 5 1 2 7 6 26 27 32 31
|
||||
1 5 6 7 12 11 31 32 37 36
|
||||
1 5 31 32 37 36 56 57 62 61
|
||||
1 5 30 31 36 35 55 56 61 60
|
||||
1 5 5 6 11 10 30 31 36 35
|
||||
1 5 10 11 16 15 35 36 41 40
|
||||
1 5 11 12 17 16 36 37 42 41
|
||||
1 5 16 17 22 21 41 42 47 46
|
||||
1 5 15 16 21 20 40 41 46 45
|
||||
1 5 40 41 46 45 65 66 71 70
|
||||
1 5 41 42 47 46 66 67 72 71
|
||||
1 5 36 37 42 41 61 62 67 66
|
||||
1 5 35 36 41 40 60 61 66 65
|
||||
1 5 60 61 66 65 85 86 91 90
|
||||
1 5 61 62 67 66 86 87 92 91
|
||||
1 5 66 67 72 71 91 92 97 96
|
||||
1 5 65 66 71 70 90 91 96 95
|
||||
1 5 90 91 96 95 115 116 121 120
|
||||
1 5 91 92 97 96 116 117 122 121
|
||||
1 5 86 87 92 91 111 112 117 116
|
||||
1 5 85 86 91 90 110 111 116 115
|
||||
1 5 80 81 86 85 105 106 111 110
|
||||
1 5 75 76 81 80 100 101 106 105
|
||||
1 5 50 51 56 55 75 76 81 80
|
||||
1 5 55 56 61 60 80 81 86 85
|
||||
1 5 56 57 62 61 81 82 87 86
|
||||
1 5 51 52 57 56 76 77 82 81
|
||||
1 5 76 77 82 81 101 102 107 106
|
||||
1 5 81 82 87 86 106 107 112 111
|
||||
1 5 82 83 88 87 107 108 113 112
|
||||
1 5 77 78 83 82 102 103 108 107
|
||||
1 5 52 53 58 57 77 78 83 82
|
||||
1 5 57 58 63 62 82 83 88 87
|
||||
1 5 58 59 64 63 83 84 89 88
|
||||
1 5 53 54 59 58 78 79 84 83
|
||||
1 5 78 79 84 83 103 104 109 108
|
||||
1 5 83 84 89 88 108 109 114 113
|
||||
1 5 88 89 94 93 113 114 119 118
|
||||
1 5 87 88 93 92 112 113 118 117
|
||||
1 5 92 93 98 97 117 118 123 122
|
||||
1 5 93 94 99 98 118 119 124 123
|
||||
1 5 68 69 74 73 93 94 99 98
|
||||
1 5 67 68 73 72 92 93 98 97
|
||||
1 5 62 63 68 67 87 88 93 92
|
||||
1 5 63 64 69 68 88 89 94 93
|
||||
1 5 38 39 44 43 63 64 69 68
|
||||
1 5 37 38 43 42 62 63 68 67
|
||||
1 5 42 43 48 47 67 68 73 72
|
||||
1 5 43 44 49 48 68 69 74 73
|
||||
1 5 18 19 24 23 43 44 49 48
|
||||
1 5 17 18 23 22 42 43 48 47
|
||||
1 5 12 13 18 17 37 38 43 42
|
||||
1 5 13 14 19 18 38 39 44 43
|
||||
1 5 8 9 14 13 33 34 39 38
|
||||
1 5 33 34 39 38 58 59 64 63
|
||||
1 5 32 33 38 37 57 58 63 62
|
||||
1 5 7 8 13 12 32 33 38 37
|
||||
1 5 2 3 8 7 27 28 33 32
|
||||
1 5 27 28 33 32 52 53 58 57
|
||||
1 5 28 29 34 33 53 54 59 58
|
||||
1 5 3 4 9 8 28 29 34 33
|
||||
|
||||
boundary
|
||||
96
|
||||
1 3 0 5 6 1
|
||||
1 3 1 6 7 2
|
||||
1 3 2 7 8 3
|
||||
1 3 3 8 9 4
|
||||
1 3 5 10 11 6
|
||||
1 3 6 11 12 7
|
||||
1 3 7 12 13 8
|
||||
1 3 8 13 14 9
|
||||
1 3 10 15 16 11
|
||||
1 3 11 16 17 12
|
||||
1 3 12 17 18 13
|
||||
1 3 13 18 19 14
|
||||
1 3 15 20 21 16
|
||||
1 3 16 21 22 17
|
||||
1 3 17 22 23 18
|
||||
1 3 18 23 24 19
|
||||
1 3 100 101 106 105
|
||||
1 3 101 102 107 106
|
||||
1 3 102 103 108 107
|
||||
1 3 103 104 109 108
|
||||
1 3 105 106 111 110
|
||||
1 3 106 107 112 111
|
||||
1 3 107 108 113 112
|
||||
1 3 108 109 114 113
|
||||
1 3 110 111 116 115
|
||||
1 3 111 112 117 116
|
||||
1 3 112 113 118 117
|
||||
1 3 113 114 119 118
|
||||
1 3 115 116 121 120
|
||||
1 3 116 117 122 121
|
||||
1 3 117 118 123 122
|
||||
1 3 118 119 124 123
|
||||
1 3 0 25 30 5
|
||||
1 3 5 30 35 10
|
||||
1 3 10 35 40 15
|
||||
1 3 15 40 45 20
|
||||
1 3 25 50 55 30
|
||||
1 3 30 55 60 35
|
||||
1 3 35 60 65 40
|
||||
1 3 40 65 70 45
|
||||
1 3 50 75 80 55
|
||||
1 3 55 80 85 60
|
||||
1 3 60 85 90 65
|
||||
1 3 65 90 95 70
|
||||
1 3 75 100 105 80
|
||||
1 3 80 105 110 85
|
||||
1 3 85 110 115 90
|
||||
1 3 90 115 120 95
|
||||
1 3 4 9 34 29
|
||||
1 3 9 14 39 34
|
||||
1 3 14 19 44 39
|
||||
1 3 19 24 49 44
|
||||
1 3 29 34 59 54
|
||||
1 3 34 39 64 59
|
||||
1 3 39 44 69 64
|
||||
1 3 44 49 74 69
|
||||
1 3 54 59 84 79
|
||||
1 3 59 64 89 84
|
||||
1 3 64 69 94 89
|
||||
1 3 69 74 99 94
|
||||
1 3 79 84 109 104
|
||||
1 3 84 89 114 109
|
||||
1 3 89 94 119 114
|
||||
1 3 94 99 124 119
|
||||
1 3 0 1 26 25
|
||||
1 3 25 26 51 50
|
||||
1 3 50 51 76 75
|
||||
1 3 75 76 101 100
|
||||
1 3 1 2 27 26
|
||||
1 3 26 27 52 51
|
||||
1 3 51 52 77 76
|
||||
1 3 76 77 102 101
|
||||
1 3 2 3 28 27
|
||||
1 3 27 28 53 52
|
||||
1 3 52 53 78 77
|
||||
1 3 77 78 103 102
|
||||
1 3 3 4 29 28
|
||||
1 3 28 29 54 53
|
||||
1 3 53 54 79 78
|
||||
1 3 78 79 104 103
|
||||
1 3 20 45 46 21
|
||||
1 3 45 70 71 46
|
||||
1 3 70 95 96 71
|
||||
1 3 95 120 121 96
|
||||
1 3 21 46 47 22
|
||||
1 3 46 71 72 47
|
||||
1 3 71 96 97 72
|
||||
1 3 96 121 122 97
|
||||
1 3 22 47 48 23
|
||||
1 3 47 72 73 48
|
||||
1 3 72 97 98 73
|
||||
1 3 97 122 123 98
|
||||
1 3 23 48 49 24
|
||||
1 3 48 73 74 49
|
||||
1 3 73 98 99 74
|
||||
1 3 98 123 124 99
|
||||
|
||||
vertices
|
||||
125
|
||||
3
|
||||
0 0 0
|
||||
0.25 0 0
|
||||
0.5 0 0
|
||||
0.75 0 0
|
||||
1 0 0
|
||||
0 0.25 0
|
||||
0.25 0.25 0
|
||||
0.5 0.25 0
|
||||
0.75 0.25 0
|
||||
1 0.25 0
|
||||
0 0.5 0
|
||||
0.25 0.5 0
|
||||
0.5 0.5 0
|
||||
0.75 0.5 0
|
||||
1 0.5 0
|
||||
0 0.75 0
|
||||
0.25 0.75 0
|
||||
0.5 0.75 0
|
||||
0.75 0.75 0
|
||||
1 0.75 0
|
||||
0 1 0
|
||||
0.25 1 0
|
||||
0.5 1 0
|
||||
0.75 1 0
|
||||
1 1 0
|
||||
0 0 0.25
|
||||
0.25 0 0.25
|
||||
0.5 0 0.25
|
||||
0.75 0 0.25
|
||||
1 0 0.25
|
||||
0 0.25 0.25
|
||||
0.25 0.25 0.25
|
||||
0.5 0.25 0.25
|
||||
0.75 0.25 0.25
|
||||
1 0.25 0.25
|
||||
0 0.5 0.25
|
||||
0.25 0.5 0.25
|
||||
0.5 0.5 0.25
|
||||
0.75 0.5 0.25
|
||||
1 0.5 0.25
|
||||
0 0.75 0.25
|
||||
0.25 0.75 0.25
|
||||
0.5 0.75 0.25
|
||||
0.75 0.75 0.25
|
||||
1 0.75 0.25
|
||||
0 1 0.25
|
||||
0.25 1 0.25
|
||||
0.5 1 0.25
|
||||
0.75 1 0.25
|
||||
1 1 0.25
|
||||
0 0 0.5
|
||||
0.25 0 0.5
|
||||
0.5 0 0.5
|
||||
0.75 0 0.5
|
||||
1 0 0.5
|
||||
0 0.25 0.5
|
||||
0.25 0.25 0.5
|
||||
0.5 0.25 0.5
|
||||
0.75 0.25 0.5
|
||||
1 0.25 0.5
|
||||
0 0.5 0.5
|
||||
0.25 0.5 0.5
|
||||
0.5 0.5 0.5
|
||||
0.75 0.5 0.5
|
||||
1 0.5 0.5
|
||||
0 0.75 0.5
|
||||
0.25 0.75 0.5
|
||||
0.5 0.75 0.5
|
||||
0.75 0.75 0.5
|
||||
1 0.75 0.5
|
||||
0 1 0.5
|
||||
0.25 1 0.5
|
||||
0.5 1 0.5
|
||||
0.75 1 0.5
|
||||
1 1 0.5
|
||||
0 0 0.75
|
||||
0.25 0 0.75
|
||||
0.5 0 0.75
|
||||
0.75 0 0.75
|
||||
1 0 0.75
|
||||
0 0.25 0.75
|
||||
0.25 0.25 0.75
|
||||
0.5 0.25 0.75
|
||||
0.75 0.25 0.75
|
||||
1 0.25 0.75
|
||||
0 0.5 0.75
|
||||
0.25 0.5 0.75
|
||||
0.5 0.5 0.75
|
||||
0.75 0.5 0.75
|
||||
1 0.5 0.75
|
||||
0 0.75 0.75
|
||||
0.25 0.75 0.75
|
||||
0.5 0.75 0.75
|
||||
0.75 0.75 0.75
|
||||
1 0.75 0.75
|
||||
0 1 0.75
|
||||
0.25 1 0.75
|
||||
0.5 1 0.75
|
||||
0.75 1 0.75
|
||||
1 1 0.75
|
||||
0 0 1
|
||||
0.25 0 1
|
||||
0.5 0 1
|
||||
0.75 0 1
|
||||
1 0 1
|
||||
0 0.25 1
|
||||
0.25 0.25 1
|
||||
0.5 0.25 1
|
||||
0.75 0.25 1
|
||||
1 0.25 1
|
||||
0 0.5 1
|
||||
0.25 0.5 1
|
||||
0.5 0.5 1
|
||||
0.75 0.5 1
|
||||
1 0.5 1
|
||||
0 0.75 1
|
||||
0.25 0.75 1
|
||||
0.5 0.75 1
|
||||
0.75 0.75 1
|
||||
1 0.75 1
|
||||
0 1 1
|
||||
0.25 1 1
|
||||
0.5 1 1
|
||||
0.75 1 1
|
||||
1 1 1
|
||||
@@ -0,0 +1,83 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
# PRISM = 6
|
||||
#
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
elements
|
||||
16
|
||||
1 3 0 1 6 5
|
||||
1 3 1 2 7 6
|
||||
1 3 6 7 12 11
|
||||
1 3 5 6 11 10
|
||||
1 3 10 11 16 15
|
||||
1 3 15 16 21 20
|
||||
1 3 16 17 22 21
|
||||
1 3 11 12 17 16
|
||||
1 3 12 13 18 17
|
||||
1 3 17 18 23 22
|
||||
1 3 18 19 24 23
|
||||
1 3 13 14 19 18
|
||||
1 3 8 9 14 13
|
||||
1 3 7 8 13 12
|
||||
1 3 2 3 8 7
|
||||
1 3 3 4 9 8
|
||||
|
||||
boundary
|
||||
16
|
||||
1 1 0 1
|
||||
1 1 1 2
|
||||
1 1 2 3
|
||||
1 1 3 4
|
||||
1 1 21 20
|
||||
1 1 22 21
|
||||
1 1 23 22
|
||||
1 1 24 23
|
||||
1 1 5 0
|
||||
1 1 10 5
|
||||
1 1 15 10
|
||||
1 1 20 15
|
||||
1 1 4 9
|
||||
1 1 9 14
|
||||
1 1 14 19
|
||||
1 1 19 24
|
||||
|
||||
vertices
|
||||
25
|
||||
2
|
||||
0 0
|
||||
0.25 0
|
||||
0.5 0
|
||||
0.75 0
|
||||
1 0
|
||||
0 0.25
|
||||
0.25 0.25
|
||||
0.5 0.25
|
||||
0.75 0.25
|
||||
1 0.25
|
||||
0 0.5
|
||||
0.25 0.5
|
||||
0.5 0.5
|
||||
0.75 0.5
|
||||
1 0.5
|
||||
0 0.75
|
||||
0.25 0.75
|
||||
0.5 0.75
|
||||
0.75 0.75
|
||||
1 0.75
|
||||
0 1
|
||||
0.25 1
|
||||
0.5 1
|
||||
0.75 1
|
||||
1 1
|
||||
@@ -0,0 +1,37 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
# PRISM = 6
|
||||
#
|
||||
|
||||
dimension
|
||||
1
|
||||
|
||||
elements
|
||||
4
|
||||
1 1 0 1
|
||||
1 1 1 2
|
||||
1 1 2 3
|
||||
1 1 3 4
|
||||
|
||||
boundary
|
||||
2
|
||||
1 0 0
|
||||
1 0 4
|
||||
|
||||
vertices
|
||||
5
|
||||
1
|
||||
0
|
||||
0.25
|
||||
0.5
|
||||
0.75
|
||||
1
|
||||
@@ -0,0 +1,99 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
# PRISM = 6
|
||||
#
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
elements
|
||||
32
|
||||
1 2 0 6 5
|
||||
1 2 6 0 1
|
||||
1 2 1 7 6
|
||||
1 2 7 1 2
|
||||
1 2 2 8 7
|
||||
1 2 8 2 3
|
||||
1 2 3 9 8
|
||||
1 2 9 3 4
|
||||
1 2 5 11 10
|
||||
1 2 11 5 6
|
||||
1 2 6 12 11
|
||||
1 2 12 6 7
|
||||
1 2 7 13 12
|
||||
1 2 13 7 8
|
||||
1 2 8 14 13
|
||||
1 2 14 8 9
|
||||
1 2 10 16 15
|
||||
1 2 16 10 11
|
||||
1 2 11 17 16
|
||||
1 2 17 11 12
|
||||
1 2 12 18 17
|
||||
1 2 18 12 13
|
||||
1 2 13 19 18
|
||||
1 2 19 13 14
|
||||
1 2 15 21 20
|
||||
1 2 21 15 16
|
||||
1 2 16 22 21
|
||||
1 2 22 16 17
|
||||
1 2 17 23 22
|
||||
1 2 23 17 18
|
||||
1 2 18 24 23
|
||||
1 2 24 18 19
|
||||
|
||||
boundary
|
||||
16
|
||||
1 1 0 1
|
||||
1 1 1 2
|
||||
1 1 2 3
|
||||
1 1 3 4
|
||||
1 1 21 20
|
||||
1 1 22 21
|
||||
1 1 23 22
|
||||
1 1 24 23
|
||||
1 1 5 0
|
||||
1 1 10 5
|
||||
1 1 15 10
|
||||
1 1 20 15
|
||||
1 1 4 9
|
||||
1 1 9 14
|
||||
1 1 14 19
|
||||
1 1 19 24
|
||||
|
||||
vertices
|
||||
25
|
||||
2
|
||||
0 0
|
||||
0.25 0
|
||||
0.5 0
|
||||
0.75 0
|
||||
1 0
|
||||
0 0.25
|
||||
0.25 0.25
|
||||
0.5 0.25
|
||||
0.75 0.25
|
||||
1 0.25
|
||||
0 0.5
|
||||
0.25 0.5
|
||||
0.5 0.5
|
||||
0.75 0.5
|
||||
1 0.5
|
||||
0 0.75
|
||||
0.25 0.75
|
||||
0.5 0.75
|
||||
0.75 0.75
|
||||
1 0.75
|
||||
0 1
|
||||
0.25 1
|
||||
0.5 1
|
||||
0.75 1
|
||||
1 1
|
||||
@@ -0,0 +1,316 @@
|
||||
#include "fe_evol.hpp"
|
||||
|
||||
FE_Evolution::FE_Evolution(FiniteElementSpace *fes_, HyperbolicSystem *hyp_,
|
||||
DofInfo &dofs_)
|
||||
: TimeDependentOperator(fes_->GetVSize()), fes(fes_), hyp(hyp_),
|
||||
dofs(dofs_), z(fes_->GetVSize()), inflow(fes_),
|
||||
xSizeMPI(dofs_.fes->GetVSize())
|
||||
{
|
||||
const char* fecol = fes->FEColl()->Name();
|
||||
if (strncmp(fecol, "L2", 2))
|
||||
{
|
||||
MFEM_ABORT("FiniteElementSpace must be L2 conforming (DG).");
|
||||
}
|
||||
if (strncmp(fecol, "L2_T2", 5))
|
||||
{
|
||||
MFEM_ABORT("Shape functions must be represented in Bernstein basis.");
|
||||
}
|
||||
|
||||
// Initialize member variables.
|
||||
IntRuleElem = GetElementIntegrationRule(fes);
|
||||
IntRuleFace = GetFaceIntegrationRule(fes);
|
||||
IntRuleFaceWeights.SetSize(IntRuleFace->GetNPoints());
|
||||
|
||||
Mesh *mesh = fes->GetMesh();
|
||||
const FiniteElement *el = fes->GetFE(0);
|
||||
|
||||
dim = mesh->Dimension();
|
||||
nd = el->GetDof();
|
||||
ne = mesh->GetNE();
|
||||
nqe = IntRuleElem->GetNPoints();
|
||||
nqf = IntRuleFace->GetNPoints();
|
||||
|
||||
ShapeEval.SetSize(nd,nqe);
|
||||
DShapeEval.SetSize(nd,dim,nqe);
|
||||
ShapeEvalFace.SetSize(dofs.NumBdrs, dofs.NumFaceDofs, nqf);
|
||||
|
||||
ElemInt.SetSize(dim, dim, ne*nqe);
|
||||
BdrInt.SetSize(dofs.NumBdrs, nqf, ne);
|
||||
OuterUnitNormals.SetSize(dim, nqf, ne*dofs.NumBdrs);
|
||||
|
||||
MassMat = new MassMatrixDG(fes);
|
||||
InvMassMat = new InverseMassMatrixDG(MassMat);
|
||||
|
||||
Vector aux_vec(hyp->NumEq);
|
||||
aux_vec = 1.0;
|
||||
VectorConstantCoefficient ones(aux_vec);
|
||||
BilinearForm ml(fes);
|
||||
ml.AddDomainIntegrator(new LumpedIntegrator(new VectorMassIntegrator(ones)));
|
||||
ml.Assemble();
|
||||
ml.Finalize();
|
||||
ml.SpMat().GetDiag(LumpedMassMat);
|
||||
|
||||
uElem.SetSize(nd);
|
||||
uEval.SetSize(hyp->NumEq);
|
||||
uNbrEval.SetSize(hyp->NumEq);
|
||||
normal.SetSize(dim);
|
||||
NumFlux.SetSize(hyp->NumEq);
|
||||
|
||||
Flux.SetSize(hyp->NumEq, dim);
|
||||
FluxNbr.SetSize(hyp->NumEq, dim);
|
||||
mat1.SetSize(dim, hyp->NumEq);
|
||||
mat2.SetSize(nd, hyp->NumEq);
|
||||
|
||||
// Precompute data that is constant for the whole run.
|
||||
Array <int> bdrs, orientation;
|
||||
Vector shape(nd);
|
||||
DenseMatrix dshape(nd,dim);
|
||||
DenseMatrix adjJ(dim);
|
||||
Array<IntegrationPoint> eip(nqf*dofs.NumBdrs);
|
||||
|
||||
// Fill eip, to be used for evaluation of shape functions on element faces.
|
||||
if (dim==1) { mesh->GetElementVertices(0, bdrs); }
|
||||
else if (dim==2) { mesh->GetElementEdges(0, bdrs, orientation); }
|
||||
else if (dim==3) { mesh->GetElementFaces(0, bdrs, orientation); }
|
||||
|
||||
for (int i = 0; i < dofs.NumBdrs; i++)
|
||||
{
|
||||
FaceElementTransformations *help
|
||||
= mesh->GetFaceElementTransformations(bdrs[i]);
|
||||
|
||||
if (help->Elem1No != 0)
|
||||
{
|
||||
// NOTE: If this error ever occurs, use neighbor element to
|
||||
// obtain the correct quadrature points and weight.
|
||||
MFEM_ABORT("First element has inward pointing normal.");
|
||||
}
|
||||
for (int k = 0; k < nqf; k++)
|
||||
{
|
||||
const IntegrationPoint &ip = IntRuleFace->IntPoint(k);
|
||||
help->Loc1.Transform(ip, eip[i*nqf + k]);
|
||||
}
|
||||
}
|
||||
|
||||
// Precompute evaluations of shape functions on elements.
|
||||
for (int k = 0; k < nqe; k++)
|
||||
{
|
||||
const IntegrationPoint &ip = IntRuleElem->IntPoint(k);
|
||||
el->CalcShape(ip, shape);
|
||||
el->CalcDShape(ip, dshape);
|
||||
ShapeEval.SetCol(k, shape);
|
||||
DShapeEval(k) = dshape;
|
||||
}
|
||||
|
||||
// Precompute evaluations of shape functions on element faces.
|
||||
for (int k = 0; k < nqf; k++)
|
||||
{
|
||||
const IntegrationPoint &ip = IntRuleFace->IntPoint(k);
|
||||
IntRuleFaceWeights(k) = ip.weight;
|
||||
|
||||
if (dim==1) { mesh->GetElementVertices(0, bdrs); }
|
||||
else if (dim==2) { mesh->GetElementEdges(0, bdrs, orientation); }
|
||||
else if (dim==3) { mesh->GetElementFaces(0, bdrs, orientation); }
|
||||
|
||||
for (int i = 0; i < dofs.NumBdrs; i++)
|
||||
{
|
||||
FaceElementTransformations *facetrans =
|
||||
mesh->GetFaceElementTransformations(bdrs[i]);
|
||||
|
||||
IntegrationPoint eip;
|
||||
facetrans->Face->SetIntPoint(&ip);
|
||||
facetrans->Loc1.Transform(ip, eip);
|
||||
el->CalcShape(eip, shape);
|
||||
|
||||
for (int j = 0; j < dofs.NumFaceDofs; j++)
|
||||
{
|
||||
ShapeEvalFace(i,j,k) = shape(dofs.BdrDofs(j,i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int e = 0; e < ne; e++)
|
||||
{
|
||||
ElementTransformation *eltrans = fes->GetElementTransformation(e);
|
||||
for (int k = 0; k < nqe; k++)
|
||||
{
|
||||
const IntegrationPoint &ip = IntRuleElem->IntPoint(k);
|
||||
eltrans->SetIntPoint(&ip);
|
||||
CalcAdjugate(eltrans->Jacobian(), adjJ);
|
||||
adjJ *= ip.weight;
|
||||
ElemInt(e*nqe+k) = adjJ;
|
||||
}
|
||||
|
||||
if (dim==1) { mesh->GetElementVertices(e, bdrs); }
|
||||
else if (dim==2) { mesh->GetElementEdges(e, bdrs, orientation); }
|
||||
else if (dim==3) { mesh->GetElementFaces(e, bdrs, orientation); }
|
||||
|
||||
for (int i = 0; i < dofs.NumBdrs; i++)
|
||||
{
|
||||
Vector nor(dim);
|
||||
FaceElementTransformations *facetrans
|
||||
= mesh->GetFaceElementTransformations(bdrs[i]);
|
||||
|
||||
for (int k = 0; k < nqf; k++)
|
||||
{
|
||||
const IntegrationPoint &ip = IntRuleFace->IntPoint(k);
|
||||
facetrans->Face->SetIntPoint(&ip);
|
||||
|
||||
if (dim == 1)
|
||||
{
|
||||
IntegrationPoint aux;
|
||||
facetrans->Loc1.Transform(ip, aux);
|
||||
nor(0) = 2.*aux.x - 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
CalcOrtho(facetrans->Face->Jacobian(), nor);
|
||||
}
|
||||
|
||||
if (facetrans->Elem1No != e)
|
||||
{
|
||||
nor *= -1.;
|
||||
}
|
||||
|
||||
nor /= nor.Norml2();
|
||||
BdrInt(i,k,e) = facetrans->Face->Weight();
|
||||
|
||||
for (int l = 0; l < dim; l++)
|
||||
{
|
||||
OuterUnitNormals(l,k,e*dofs.NumBdrs+i) = nor(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hyp->TimeDepBC)
|
||||
{
|
||||
if (!hyp->ProjType)
|
||||
{
|
||||
hyp->L2_Projection(hyp->BdrCond, inflow);
|
||||
}
|
||||
else
|
||||
{
|
||||
inflow.ProjectCoefficient(hyp->BdrCond);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FE_Evolution::ElemEval(const Vector &uElem, Vector &uEval, int k) const
|
||||
{
|
||||
uEval = 0.;
|
||||
for (int n = 0; n < hyp->NumEq; n++)
|
||||
{
|
||||
for (int j = 0; j < nd; j++)
|
||||
{
|
||||
uEval(n) += uElem(n * nd + j) * ShapeEval(j, k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FE_Evolution::FaceEval(const Vector &x, Vector &y1, Vector &y2,
|
||||
const Vector &xMPI, const Vector &normal,
|
||||
int e, int i, int k) const
|
||||
{
|
||||
y1 = y2 = 0.;
|
||||
for (int n = 0; n < hyp->NumEq; n++)
|
||||
{
|
||||
for (int j = 0; j < dofs.NumFaceDofs; j++)
|
||||
{
|
||||
nbr = dofs.NbrDofs(i, j, e);
|
||||
DofInd = n * ne * nd + e * nd + dofs.BdrDofs(j, i);
|
||||
|
||||
if (nbr < 0)
|
||||
{
|
||||
uNbr = inflow(DofInd);
|
||||
}
|
||||
else
|
||||
{
|
||||
// nbr in different MPI task?
|
||||
uNbr = (nbr < xSizeMPI) ? x(n * ne * nd + nbr) : xMPI(int((
|
||||
nbr - xSizeMPI) / nd) * nd * hyp->NumEq + n * nd + (nbr - xSizeMPI) % nd);
|
||||
}
|
||||
|
||||
y1(n) += x(DofInd) * ShapeEvalFace(i, j, k);
|
||||
y2(n) += uNbr * ShapeEvalFace(i, j, k);
|
||||
}
|
||||
}
|
||||
|
||||
if (nbr < 0) // TODO better distinction
|
||||
{
|
||||
hyp->SetBdrCond(y1, y2, normal, nbr);
|
||||
}
|
||||
}
|
||||
|
||||
void FE_Evolution::LaxFriedrichs(const Vector &x1, const Vector &x2,
|
||||
const Vector &normal, Vector &y,
|
||||
int e, int k, int i) const
|
||||
{
|
||||
hyp->EvaluateFlux(x1, Flux, e, k, i);
|
||||
hyp->EvaluateFlux(x2, FluxNbr, e, k, i);
|
||||
Flux += FluxNbr;
|
||||
double ws = max(hyp->GetWaveSpeed(x1, normal, e, k, i),
|
||||
hyp->GetWaveSpeed(x2, normal, e, k, i));
|
||||
|
||||
subtract(ws, x1, x2, y);
|
||||
Flux.AddMult(normal, y);
|
||||
y *= 0.5;
|
||||
}
|
||||
|
||||
void FE_Evolution::HLL(const Vector &x1, const Vector &x2, const Vector &normal,
|
||||
Vector &y, int e, int k, int i) const
|
||||
{
|
||||
MFEM_ABORT("TODO. Implement properly.");
|
||||
|
||||
hyp->EvaluateFlux(x1, Flux, e, k, i);
|
||||
hyp->EvaluateFlux(x2, FluxNbr, e, k, i);
|
||||
|
||||
double v1 = (x1(1) * normal(0) + x1(2) * normal(1)) / x1(0);
|
||||
double v2 = (x2(1) * normal(0) + x2(2) * normal(1)) / x2(0);
|
||||
|
||||
// Note: Hardcoded for 2D Euler
|
||||
// double p1 = 0.4 * ( x1(3) - 0.5 * (x1(1)*x1(1) + x1(2)*x1(2)) / x1(0) );
|
||||
// double p2 = 0.4 * ( x2(3) - 0.5 * (x2(1)*x2(1) + x2(2)*x2(2)) / x2(0) );
|
||||
// double c1 = sqrt(1.4 * p1 / x1(0));
|
||||
// double c2 = sqrt(1.4 * p2 / x2(0));
|
||||
|
||||
// Note: Hardcoded for 2D SWE
|
||||
double c1 = sqrt(1.0 * x1(0));
|
||||
double c2 = sqrt(1.0 * x2(0));
|
||||
|
||||
double s1 = min(v1, v2) - max(c1, c2);
|
||||
double s2 = max(v1, v2) + min(c1, c2);
|
||||
|
||||
if (s1 > 0.0) { Flux.Mult(normal, y); }
|
||||
else if (s2 < 0.0) { FluxNbr.Mult(normal, y); }
|
||||
else
|
||||
{
|
||||
subtract(s1*s2, x2, x1, y);
|
||||
Flux.AddMult_a(s2, normal, y);
|
||||
FluxNbr.AddMult_a(-s1, normal, y);
|
||||
y /= (s2 -s1);
|
||||
}
|
||||
}
|
||||
|
||||
double FE_Evolution::ConvergenceCheck(double dt, const Vector &u) const
|
||||
{
|
||||
z = u;
|
||||
z -= uOld;
|
||||
|
||||
double res = 0.;
|
||||
if (!hyp->SteadyState) // Use consistent mass matrix.
|
||||
{
|
||||
MassMat->Mult(z, uOld);
|
||||
res = uOld.Norml2() / dt;
|
||||
}
|
||||
else // Use lumped mass matrix.
|
||||
{
|
||||
for (int i = 0; i < u.Size(); i++)
|
||||
{
|
||||
res += pow(LumpedMassMat(i) * z(i), 2.);
|
||||
}
|
||||
res = sqrt(res) / dt;
|
||||
}
|
||||
|
||||
uOld = u;
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
#ifndef HYPSYS_FE_EVOL
|
||||
#define HYPSYS_FE_EVOL
|
||||
|
||||
#include "../lib/lib.hpp"
|
||||
#include "../apps/hyperbolic_system.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
// Auxiliary, only used to pass a non-used reference as parameter.
|
||||
static Vector serial;
|
||||
|
||||
class FE_Evolution : public TimeDependentOperator
|
||||
{
|
||||
public:
|
||||
// General member variables.
|
||||
FiniteElementSpace *fes;
|
||||
const HyperbolicSystem *hyp;
|
||||
const IntegrationRule *IntRuleElem; // TODO rm const, *
|
||||
const IntegrationRule *IntRuleFace;
|
||||
Vector IntRuleFaceWeights;
|
||||
|
||||
// Parameters that are needed repeatedly.
|
||||
int dim, nd, ne, nqe, nqf;
|
||||
const int xSizeMPI;
|
||||
|
||||
// Shape function evaluations.
|
||||
DenseMatrix ShapeEval;
|
||||
DenseTensor DShapeEval;
|
||||
DenseTensor ShapeEvalFace;
|
||||
|
||||
// Element and boundary integrals evaluated in quadrature points.
|
||||
DenseTensor ElemInt;
|
||||
DenseTensor BdrInt;
|
||||
DenseTensor OuterUnitNormals;
|
||||
|
||||
// DG mass matrices.
|
||||
const MassMatrixDG *MassMat;
|
||||
const InverseMassMatrixDG *InvMassMat;
|
||||
Vector LumpedMassMat;
|
||||
|
||||
// Tools to compute the discrete time derivative, needed repeatedly.
|
||||
mutable DofInfo dofs;
|
||||
mutable Array<int> vdofs;
|
||||
mutable Vector z, uOld, uElem, uEval, uNbrEval, NumFlux, normal;
|
||||
mutable DenseMatrix Flux, FluxNbr, mat1, mat2;
|
||||
mutable int DofInd, nbr;
|
||||
mutable double uNbr;
|
||||
|
||||
mutable GridFunction inflow;
|
||||
|
||||
FE_Evolution(FiniteElementSpace *fes_, HyperbolicSystem *hyp_,
|
||||
DofInfo &dofs_);
|
||||
|
||||
virtual ~FE_Evolution()
|
||||
{
|
||||
delete MassMat;
|
||||
delete InvMassMat;
|
||||
}
|
||||
|
||||
virtual void Mult(const Vector &x, Vector &y) const = 0;
|
||||
|
||||
virtual void ElemEval(const Vector &uElem, Vector &uEval, int k) const;
|
||||
virtual void FaceEval(const Vector &x, Vector &y1, Vector &y2,
|
||||
const Vector &xMPI, const Vector &normal,
|
||||
int e, int i, int k) const;
|
||||
virtual void LaxFriedrichs(const Vector &x1, const Vector &x2,
|
||||
const Vector &normal,
|
||||
Vector &y, int e, int k, int i) const;
|
||||
virtual void HLL(const Vector &x1, const Vector &x2, const Vector &normal,
|
||||
Vector &y, int e, int k, int i) const;
|
||||
virtual double ConvergenceCheck(double dt, const Vector &u) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,73 @@
|
||||
#include "galerkin.hpp"
|
||||
|
||||
GalerkinEvolution::GalerkinEvolution(FiniteElementSpace *fes_,
|
||||
HyperbolicSystem *hyp_, DofInfo &dofs_)
|
||||
: FE_Evolution(fes_, hyp_, dofs_)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void GalerkinEvolution::Mult(const Vector &x, Vector &y) const
|
||||
{
|
||||
if (hyp->TimeDepBC)
|
||||
{
|
||||
hyp->BdrCond.SetTime(t);
|
||||
if (!hyp->ProjType)
|
||||
{
|
||||
hyp->L2_Projection(hyp->BdrCond, inflow);
|
||||
}
|
||||
else
|
||||
{
|
||||
inflow.ProjectCoefficient(hyp->BdrCond);
|
||||
}
|
||||
}
|
||||
|
||||
z = 0.;
|
||||
ComputeTimeDerivative(x, y);
|
||||
}
|
||||
|
||||
void GalerkinEvolution::ComputeTimeDerivative(const Vector &x, Vector &y,
|
||||
const Vector &xMPI) const
|
||||
{
|
||||
for (int e = 0; e < ne; e++)
|
||||
{
|
||||
fes->GetElementVDofs(e, vdofs);
|
||||
x.GetSubVector(vdofs, uElem);
|
||||
mat2 = 0.;
|
||||
|
||||
for (int k = 0; k < nqe; k++)
|
||||
{
|
||||
ElemEval(uElem, uEval, k);
|
||||
hyp->EvaluateFlux(uEval, Flux, e, k);
|
||||
MultABt(ElemInt(e * nqe + k), Flux, mat1);
|
||||
AddMult(DShapeEval(k), mat1, mat2);
|
||||
}
|
||||
|
||||
z.AddElementVector(vdofs, mat2.GetData());
|
||||
|
||||
// Here, the use of nodal basis functions is essential, i.e. shape
|
||||
// functions must vanish on faces that their node is not associated with.
|
||||
for (int i = 0; i < dofs.NumBdrs; i++)
|
||||
{
|
||||
for (int k = 0; k < nqf; k++)
|
||||
{
|
||||
OuterUnitNormals(e * dofs.NumBdrs + i).GetColumn(k, normal);
|
||||
FaceEval(x, uEval, uNbrEval, xMPI, normal, e, i, k);
|
||||
|
||||
LaxFriedrichs(uEval, uNbrEval, normal, NumFlux, e, k, i);
|
||||
NumFlux *= BdrInt(i, k, e) * IntRuleFaceWeights(k);
|
||||
|
||||
for (int n = 0; n < hyp->NumEq; n++)
|
||||
{
|
||||
for (int j = 0; j < dofs.NumFaceDofs; j++)
|
||||
{
|
||||
z(vdofs[n * nd + dofs.BdrDofs(j,i)]) -= ShapeEvalFace(i,j,k)
|
||||
* NumFlux(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InvMassMat->Mult(z, y);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef HYPSYS_GALERKINEVOLUTION
|
||||
#define HYPSYS_GALERKINEVOLUTION
|
||||
|
||||
#include "fe_evol.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
class GalerkinEvolution : public FE_Evolution
|
||||
{
|
||||
public:
|
||||
explicit GalerkinEvolution(FiniteElementSpace *fes_,
|
||||
HyperbolicSystem *hyp_, DofInfo &dofs_);
|
||||
|
||||
virtual ~GalerkinEvolution() { }
|
||||
|
||||
void Mult(const Vector&x, Vector &y) const override;
|
||||
|
||||
void ComputeTimeDerivative(const Vector &x, Vector &y,
|
||||
const Vector &xMPI = serial) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef HYPSYS_FE_EVOL_LIB
|
||||
#define HYPSYS_FE_EVOL_LIB
|
||||
|
||||
#include "galerkin.hpp"
|
||||
#include "monolithic_convex_limiting.hpp"
|
||||
|
||||
enum EvolutionScheme { Galerkin, MonolithicConvexLimiting };
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,47 @@
|
||||
#ifndef HYPSYS_MCL_EVOLUTION
|
||||
#define HYPSYS_MCL_EVOLUTION
|
||||
|
||||
#include "fe_evol.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
class MCL_Evolution : public FE_Evolution
|
||||
{
|
||||
public:
|
||||
FiniteElementSpace *fesH1;
|
||||
|
||||
double MassMatLumpedRef;
|
||||
const double dt;
|
||||
int NumLocNbr;
|
||||
Vector DetJ;
|
||||
DenseTensor PrecGradOp, GradProd, Adjugates;
|
||||
DenseMatrix FaceMat, DistributionMatrix, MassMatLOR, Dof2LocNbr, MassMatRefInv;
|
||||
Bounds *bounds;
|
||||
|
||||
mutable DenseTensor CTilde, CFull, NodalFluxes, uij/* , ufiMin, ufiMax */;
|
||||
mutable DenseMatrix uFace, uNbrFace, mat3, DGFluxTerms, GalerkinRhs,
|
||||
ElFlux, uDot, DTilde, ufi, BdrFlux, AntiDiffBdr,
|
||||
uijMin, uijMax, LimitedBarState;
|
||||
mutable Vector sif, vec1, diffusion, LimitedFluxState;
|
||||
|
||||
explicit MCL_Evolution(FiniteElementSpace *fes_, HyperbolicSystem *hyp_,
|
||||
DofInfo &dofs_, double dt_);
|
||||
|
||||
virtual ~MCL_Evolution() { delete bounds; delete fesH1; }
|
||||
|
||||
void Mult(const Vector&x, Vector &y) const override;
|
||||
|
||||
virtual void GetNodeVal(const Vector &uElem, Vector &uEval, int ) const;
|
||||
virtual void GetFaceVal(const Vector &x, const Vector &xMPI, int e,
|
||||
int i) const;
|
||||
|
||||
void ComputeTimeDerivative(const Vector &x, Vector &y,
|
||||
const Vector &xMPI = serial) const;
|
||||
void ComputeDissipativeMatrix(int e, const Vector &uElem) const;
|
||||
void ComputePrecGradOp();
|
||||
void ComputeLORMassMatrix(DenseMatrix &RefMat, Geometry::Type gtype,
|
||||
bool UseDiagonalNbrs);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
#include "pgalerkin.hpp"
|
||||
|
||||
ParGalerkinEvolution::ParGalerkinEvolution(ParFiniteElementSpace *pfes_,
|
||||
HyperbolicSystem *hyp_,
|
||||
DofInfo &dofs_)
|
||||
: GalerkinEvolution(pfes_, hyp_, dofs_), x_gf_MPI(pfes_) { }
|
||||
|
||||
void ParGalerkinEvolution::Mult(const Vector &x, Vector &y) const
|
||||
{
|
||||
x_gf_MPI = x;
|
||||
x_gf_MPI.ExchangeFaceNbrData();
|
||||
Vector &xMPI = x_gf_MPI.FaceNbrData();
|
||||
|
||||
if (hyp->TimeDepBC)
|
||||
{
|
||||
hyp->BdrCond.SetTime(t);
|
||||
if (!hyp->ProjType)
|
||||
{
|
||||
hyp->L2_Projection(hyp->BdrCond, inflow);
|
||||
}
|
||||
else
|
||||
{
|
||||
inflow.ProjectCoefficient(hyp->BdrCond);
|
||||
}
|
||||
}
|
||||
|
||||
z = 0.;
|
||||
ComputeTimeDerivative(x, y, xMPI);
|
||||
}
|
||||
|
||||
double ParGalerkinEvolution::ConvergenceCheck(double dt, const Vector &u) const
|
||||
{
|
||||
z = u;
|
||||
z -= uOld;
|
||||
|
||||
double res, resMPI = 0.;
|
||||
if (!hyp->SteadyState) // Use consistent mass matrix.
|
||||
{
|
||||
MassMat->Mult(z, uOld);
|
||||
for (int i = 0; i < u.Size(); i++)
|
||||
{
|
||||
resMPI += uOld(i) * uOld(i);
|
||||
}
|
||||
MPI_Allreduce(&resMPI, &res, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
|
||||
res = sqrt(res) / dt;
|
||||
}
|
||||
else // Use lumped mass matrix.
|
||||
{
|
||||
for (int i = 0; i < u.Size(); i++)
|
||||
{
|
||||
resMPI += pow(LumpedMassMat(i) * z(i), 2.);
|
||||
}
|
||||
MPI_Allreduce(&resMPI, &res, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
|
||||
res = sqrt(res) / dt;
|
||||
}
|
||||
|
||||
uOld = u;
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef HYPSYS_PARGALERKINEVOLUTION
|
||||
#define HYPSYS_PARGALERKINEVOLUTION
|
||||
|
||||
#include "galerkin.hpp"
|
||||
#include "../lib/plib.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
class ParGalerkinEvolution : public GalerkinEvolution
|
||||
{
|
||||
public:
|
||||
mutable ParGridFunction x_gf_MPI;
|
||||
|
||||
explicit ParGalerkinEvolution(ParFiniteElementSpace *pfes_,
|
||||
HyperbolicSystem *hyp_, DofInfo &dofs_);
|
||||
|
||||
virtual ~ParGalerkinEvolution() { }
|
||||
|
||||
void Mult(const Vector&x, Vector &y) const override;
|
||||
double ConvergenceCheck(double dt, const Vector &u) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef HYPSYS_FE_EVOL_PLIB
|
||||
#define HYPSYS_FE_EVOL_PLIB
|
||||
|
||||
#include "lib.hpp"
|
||||
#include "../lib/ptools.hpp"
|
||||
#include "pgalerkin.hpp"
|
||||
#include "pmonolithic_convex_limiting.hpp"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,65 @@
|
||||
#include "pmonolithic_convex_limiting.hpp"
|
||||
|
||||
ParMCL_Evolution::ParMCL_Evolution(ParFiniteElementSpace *pfes_,
|
||||
HyperbolicSystem *hyp_,
|
||||
DofInfo &dofs_, double dt_)
|
||||
: MCL_Evolution(pfes_, hyp_, dofs_, dt_), x_gf_MPI(pfes_)
|
||||
{
|
||||
H1_FECollection fec(fes->GetFE(0)->GetOrder(), dim);
|
||||
pfesH1 = new ParFiniteElementSpace(pfes_->GetParMesh(), &fec);
|
||||
delete bounds; // Serial version is deleted.
|
||||
bounds = new ParTightBounds(pfes_, pfesH1);
|
||||
}
|
||||
|
||||
void ParMCL_Evolution::Mult(const Vector &x, Vector &y) const
|
||||
{
|
||||
x_gf_MPI = x;
|
||||
x_gf_MPI.ExchangeFaceNbrData();
|
||||
Vector &xMPI = x_gf_MPI.FaceNbrData();
|
||||
|
||||
if (hyp->TimeDepBC)
|
||||
{
|
||||
hyp->BdrCond.SetTime(t);
|
||||
if (!hyp->ProjType)
|
||||
{
|
||||
hyp->L2_Projection(hyp->BdrCond, inflow);
|
||||
}
|
||||
else
|
||||
{
|
||||
inflow.ProjectCoefficient(hyp->BdrCond);
|
||||
}
|
||||
}
|
||||
|
||||
z = 0.;
|
||||
ComputeTimeDerivative(x, y, xMPI);
|
||||
}
|
||||
|
||||
double ParMCL_Evolution::ConvergenceCheck(double dt, const Vector &u) const
|
||||
{
|
||||
z = u;
|
||||
z -= uOld;
|
||||
|
||||
double res, resMPI = 0.;
|
||||
if (!hyp->SteadyState) // Use consistent mass matrix.
|
||||
{
|
||||
MassMat->Mult(z, uOld);
|
||||
for (int i = 0; i < u.Size(); i++)
|
||||
{
|
||||
resMPI += uOld(i) * uOld(i);
|
||||
}
|
||||
MPI_Allreduce(&resMPI, &res, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
|
||||
res = sqrt(res) / dt;
|
||||
}
|
||||
else // Use lumped mass matrix.
|
||||
{
|
||||
for (int i = 0; i < u.Size(); i++)
|
||||
{
|
||||
resMPI += pow(LumpedMassMat(i) * z(i), 2.);
|
||||
}
|
||||
MPI_Allreduce(&resMPI, &res, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
|
||||
res = sqrt(res) / dt;
|
||||
}
|
||||
|
||||
uOld = u;
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef HYPSYS_PARMCL_EVOLUTION
|
||||
#define HYPSYS_PARMCL_EVOLUTION
|
||||
|
||||
#include "monolithic_convex_limiting.hpp"
|
||||
#include "../lib/plib.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
class ParMCL_Evolution : public MCL_Evolution
|
||||
{
|
||||
public:
|
||||
ParFiniteElementSpace *pfesH1;
|
||||
|
||||
mutable ParGridFunction x_gf_MPI;
|
||||
|
||||
explicit ParMCL_Evolution(ParFiniteElementSpace *pfes_,
|
||||
HyperbolicSystem *hyp_, DofInfo &dofs_, double dt_);
|
||||
|
||||
virtual ~ParMCL_Evolution() { delete pfesH1; }
|
||||
|
||||
void Mult(const Vector&x, Vector &y) const override;
|
||||
double ConvergenceCheck(double dt, const Vector &u) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,60 @@
|
||||
#include "ptemplate.hpp"
|
||||
|
||||
PARTEMPLATE::PARTEMPLATE(ParFiniteElementSpace *pfes_,
|
||||
HyperbolicSystem *hyp_,
|
||||
DofInfo &dofs_)
|
||||
: PARTEMPLATE(pfes_, hyp_, dofs_), x_gf_MPI(pfes_) { }
|
||||
|
||||
void PARTEMPLATE::Mult(const Vector &x, Vector &y) const
|
||||
{
|
||||
x_gf_MPI = x;
|
||||
x_gf_MPI.ExchangeFaceNbrData();
|
||||
Vector &xMPI = x_gf_MPI.FaceNbrData();
|
||||
|
||||
if (hyp->TimeDepBC)
|
||||
{
|
||||
hyp->BdrCond.SetTime(t);
|
||||
if (!hyp->ProjType)
|
||||
{
|
||||
hyp->L2_Projection(hyp->BdrCond, inflow);
|
||||
}
|
||||
else
|
||||
{
|
||||
inflow.ProjectCoefficient(hyp->BdrCond);
|
||||
}
|
||||
}
|
||||
|
||||
z = 0.;
|
||||
ComputeTimeDerivative(x, y, xMPI);
|
||||
}
|
||||
|
||||
double PARTEMPLATE::ConvergenceCheck(double dt, double tol,
|
||||
const Vector &u) const
|
||||
{
|
||||
z = u;
|
||||
z -= uOld;
|
||||
|
||||
double res, resMPI = 0.;
|
||||
if (!hyp->SteadyState) // Use consistent mass matrix.
|
||||
{
|
||||
MassMat->Mult(z, uOld);
|
||||
for (int i = 0; i < u.Size(); i++)
|
||||
{
|
||||
resMPI += uOld(i) * uOld(i);
|
||||
}
|
||||
MPI_Allreduce(&resMPI, &res, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
|
||||
res = sqrt(res) / dt;
|
||||
}
|
||||
else // Use lumped mass matrix.
|
||||
{
|
||||
for (int i = 0; i < u.Size(); i++)
|
||||
{
|
||||
resMPI += pow(LumpedMassMat(i) * z(i), 2.);
|
||||
}
|
||||
MPI_Allreduce(&resMPI, &res, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
|
||||
res = sqrt(res) / dt;
|
||||
}
|
||||
|
||||
uOld = u;
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef HYPSYS_PARTEMPLATE_EVOLUTION
|
||||
#define HYPSYS_PARTEMPLATE_EVOLUTION
|
||||
|
||||
#include "template.hpp"
|
||||
#include "../lib/plib.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
class PARTEMPLATE : public TEMPLATE
|
||||
{
|
||||
public:
|
||||
mutable ParGridFunction x_gf_MPI;
|
||||
|
||||
explicit PARTEMPLATE(ParFiniteElementSpace *pfes_,
|
||||
HyperbolicSystem *hyp_,
|
||||
DofInfo &dofs_);
|
||||
|
||||
virtual ~PARTEMPLATE() { }
|
||||
|
||||
void Mult(const Vector&x, Vector &y) const override;
|
||||
double ConvergenceCheck(double dt, double tol, const Vector &u) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "template.hpp"
|
||||
|
||||
TEMPLATE::TEMPLATE(FiniteElementSpace *fes_, HyperbolicSystem *hyp_,
|
||||
DofInfo &dofs_)
|
||||
: FE_Evolution(fes_, hyp_, dofs_)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void TEMPLATE::Mult(const Vector &x, Vector &y) const
|
||||
{
|
||||
if (hyp->TimeDepBC)
|
||||
{
|
||||
hyp->BdrCond.SetTime(t);
|
||||
if (!hyp->ProjType)
|
||||
{
|
||||
hyp->L2_Projection(hyp->BdrCond, inflow);
|
||||
}
|
||||
else
|
||||
{
|
||||
inflow.ProjectCoefficient(hyp->BdrCond);
|
||||
}
|
||||
}
|
||||
|
||||
z = 0.;
|
||||
ComputeTimeDerivative(x, y);
|
||||
}
|
||||
|
||||
void TEMPLATE::ComputeTimeDerivative(const Vector &x, Vector &y,
|
||||
const Vector &xMPI) const
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef HYPSYS_TEMPLATE_EVOLUTION
|
||||
#define HYPSYS_TEMPLATE_EVOLUTION
|
||||
|
||||
#include "fe_evol.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
class TEMPLATE : public FE_Evolution
|
||||
{
|
||||
public:
|
||||
explicit TEMPLATE(FiniteElementSpace *fes_, HyperbolicSystem *hyp_,
|
||||
DofInfo &dofs_);
|
||||
|
||||
virtual ~TEMPLATE() { }
|
||||
|
||||
void Mult(const Vector&x, Vector &y) const override;
|
||||
void ComputeTimeDerivative(const Vector &x, Vector &y,
|
||||
const Vector &xMPI = serial) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,295 @@
|
||||
#include "lib/lib.hpp"
|
||||
#include "fe_evol/lib.hpp"
|
||||
#include "apps/lib.hpp"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Configuration config;
|
||||
int ProblemNum = 0;
|
||||
config.ConfigNum = 1;
|
||||
int VisSteps = 100;
|
||||
config.tFinal = 1.;
|
||||
int odeSolverType = 3;
|
||||
double dt = 0.001;
|
||||
const char *MeshFile = "data/inline-4quad.mesh";
|
||||
int order = 3;
|
||||
int refinements = 1;
|
||||
EvolutionScheme scheme = MonolithicConvexLimiting;
|
||||
const char *OutputDir = "."; // Directory has to exist to produce output.
|
||||
bool TransOutput = false; // Use this to produce output for videos.
|
||||
bool VisualizeDerived = false;
|
||||
|
||||
int precision = 8;
|
||||
cout.precision(precision);
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&ProblemNum, "-p", "--problem",
|
||||
"Hyperbolic system of equations to solve.");
|
||||
args.AddOption(&config.ConfigNum, "-c", "--configuration",
|
||||
"Problem setup to use.");
|
||||
args.AddOption(&VisSteps, "-vf", "--visualization-frequency",
|
||||
"Visualize every n-th timestep.");
|
||||
args.AddOption(&config.tFinal, "-tf", "--final-time",
|
||||
"Final time; start time is 0.");
|
||||
args.AddOption(&odeSolverType, "-s", "--ode-solver",
|
||||
"ODE solver: 1 - Forward Euler,\n\t"
|
||||
" 2 - RK2 SSP, 3 - RK3 SSP, 4 - RK4, 6 - RK6.");
|
||||
args.AddOption(&dt, "-dt", "--time-step", "Time step.");
|
||||
args.AddOption(&MeshFile, "-m", "--mesh", "Mesh file to use.");
|
||||
args.AddOption(&order, "-o", "--order",
|
||||
"Order (polynomial degree) of the finite element space.");
|
||||
args.AddOption(&refinements, "-r", "--refinements",
|
||||
"Number of times to refine the mesh uniformly.");
|
||||
args.AddOption((int*)(&scheme), "-es", "--evolution-scheme",
|
||||
"Scheme: 0 - Galerkin Finite Element Approximation,\n\t"
|
||||
" 1 - Monolithic Convex Limiting.");
|
||||
args.AddOption(&OutputDir, "-out", "--output-directory", "Output directory.");
|
||||
args.AddOption(&TransOutput, "-t", "--transitional-output", "-no-t",
|
||||
"--no-transitional-output", "Print transitional output files.");
|
||||
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
args.PrintUsage(cout);
|
||||
return -1;
|
||||
}
|
||||
args.PrintOptions(cout);
|
||||
|
||||
if (order == 0)
|
||||
{
|
||||
scheme = Galerkin;
|
||||
}
|
||||
|
||||
ODESolver *odeSolver = NULL;
|
||||
switch (odeSolverType)
|
||||
{
|
||||
case 1: odeSolver = new ForwardEulerSolver; break;
|
||||
case 2: odeSolver = new RK2Solver(1.0); break;
|
||||
case 3: odeSolver = new RK3SSPSolver; break;
|
||||
case 4: odeSolver = new RK4Solver; break;
|
||||
case 6: odeSolver = new RK6Solver; break;
|
||||
default:
|
||||
cout << "Unknown ODE solver type: " << odeSolverType << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (odeSolverType > 3)
|
||||
{
|
||||
MFEM_WARNING("Non-SSP odeSolver: Maximum principles may be violated.");
|
||||
}
|
||||
|
||||
Mesh mesh(MeshFile, 1, 1);
|
||||
const int dim = mesh.Dimension();
|
||||
|
||||
for (int lev = 0; lev < refinements; lev++)
|
||||
{
|
||||
mesh.UniformRefinement();
|
||||
}
|
||||
if (mesh.NURBSext)
|
||||
{
|
||||
mesh.SetCurvature(max(order, 1));
|
||||
}
|
||||
|
||||
mesh.GetBoundingBox(config.bbMin, config.bbMax, max(order, 1));
|
||||
|
||||
int NumEq;
|
||||
switch (ProblemNum)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3: { NumEq = 1; VisualizeDerived = false; break; }
|
||||
case 4: NumEq = 1 + dim; break;
|
||||
case 5: NumEq = 2 + dim; break;
|
||||
default:
|
||||
cout << "Unknown hyperbolic system: " << ProblemNum << endl;
|
||||
delete odeSolver;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create Bernstein Finite Element Space.
|
||||
const int btype = BasisType::Positive;
|
||||
L2_FECollection fec(order, dim, btype);
|
||||
FiniteElementSpace fes(&mesh, &fec);
|
||||
FiniteElementSpace vfes(&mesh, &fec, NumEq, Ordering::byNODES);
|
||||
|
||||
Array<int> offsets(NumEq + 1);
|
||||
for (int k = 0; k <= NumEq; k++) { offsets[k] = k * fes.GetNDofs(); }
|
||||
BlockVector u_block(offsets);
|
||||
|
||||
const int ProblemSize = vfes.GetVSize();
|
||||
cout << "Number of unknowns: " << ProblemSize << endl;
|
||||
|
||||
DofInfo dofs(&fes);
|
||||
|
||||
bool NodalQuadRule = false;
|
||||
if (scheme == MonolithicConvexLimiting)
|
||||
{
|
||||
NodalQuadRule = true;
|
||||
}
|
||||
|
||||
HyperbolicSystem *hyp;
|
||||
switch (ProblemNum)
|
||||
{
|
||||
case 0: { hyp = new Advection(&vfes, u_block, config, NodalQuadRule); break; }
|
||||
case 1: { hyp = new Burgers(&vfes, u_block, config); break; }
|
||||
case 2: { hyp = new KPP(&vfes, u_block, config); break; }
|
||||
case 3: { hyp = new BuckleyLeverett(&vfes, u_block, config); break; }
|
||||
case 4: { hyp = new ShallowWater(&vfes, u_block, config); break; }
|
||||
case 5: { hyp = new Euler(&vfes, u_block, config); break; }
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (odeSolverType != 1 && hyp->SteadyState)
|
||||
{
|
||||
MFEM_WARNING("Better use forward Euler pseudo time stepping for steady state simulations.");
|
||||
}
|
||||
|
||||
GridFunction u(&vfes, u_block);
|
||||
u = hyp->u0;
|
||||
|
||||
// The main is variable is visualized, printed, and used to check for mass leaks or violation of maximum principles.
|
||||
GridFunction main(&fes, u_block.GetBlock(0));
|
||||
|
||||
ostringstream MeshName, InitName;
|
||||
MeshName << OutputDir << "/grid.mesh";
|
||||
InitName << OutputDir << "/initial.gf";
|
||||
ofstream omesh(MeshName.str().c_str());
|
||||
omesh.precision(precision);
|
||||
mesh.Print(omesh);
|
||||
ofstream initial(InitName.str().c_str());
|
||||
initial.precision(precision);
|
||||
main.Save(initial);
|
||||
|
||||
socketstream sout;
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
VisualizeField(sout, vishost, visport, hyp->ProblemName, main,
|
||||
hyp->glvis_scale);
|
||||
|
||||
FE_Evolution *evol;
|
||||
switch (scheme)
|
||||
{
|
||||
case Galerkin: { evol = new GalerkinEvolution(&vfes, hyp, dofs); break; }
|
||||
case MonolithicConvexLimiting: { evol = new MCL_Evolution(&vfes, hyp, dofs, dt); break; }
|
||||
default:
|
||||
MFEM_ABORT("Unknown evolution scheme");
|
||||
}
|
||||
|
||||
Vector LumpedMassMat(fes.GetVSize());
|
||||
BilinearForm ml(&fes);
|
||||
ml.AddDomainIntegrator(new LumpedIntegrator(new MassIntegrator()));
|
||||
ml.Assemble();
|
||||
ml.Finalize();
|
||||
ml.SpMat().GetDiag(LumpedMassMat);
|
||||
|
||||
double InitialMass = LumpedMassMat * main;
|
||||
|
||||
odeSolver->Init(*evol);
|
||||
if (hyp->SteadyState)
|
||||
{
|
||||
evol->uOld.SetSize(ProblemSize);
|
||||
evol->uOld = 0.;
|
||||
}
|
||||
|
||||
int TransStep = 1;
|
||||
double dtLast, res, t = 0., tol = 1.e-12;
|
||||
bool done = t >= config.tFinal;
|
||||
tic_toc.Clear();
|
||||
tic_toc.Start();
|
||||
cout << "Preprocessing done. Entering time stepping loop.\n";
|
||||
|
||||
for (int ti = 0; !done;)
|
||||
{
|
||||
dtLast = min(dt, config.tFinal - t);
|
||||
odeSolver->Step(u, t, dtLast);
|
||||
ti++;
|
||||
|
||||
done = (t >= config.tFinal - 1.e-8 * dt);
|
||||
|
||||
if (hyp->SteadyState)
|
||||
{
|
||||
res = evol->ConvergenceCheck(dt, u);
|
||||
if (res < tol)
|
||||
{
|
||||
done = true;
|
||||
u = evol->uOld;
|
||||
}
|
||||
}
|
||||
|
||||
if (done || ti % VisSteps == 0)
|
||||
{
|
||||
if (hyp->SteadyState)
|
||||
{
|
||||
cout << "time step: " << ti << ", time: " << t <<
|
||||
", residual: " << res << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "time step: " << ti << ", time: " << t << endl;
|
||||
}
|
||||
|
||||
VisualizeField(sout, vishost, visport, hyp->ProblemName, main,
|
||||
hyp->glvis_scale);
|
||||
if (TransOutput)
|
||||
{
|
||||
ostringstream TransName;
|
||||
TransName << OutputDir << "/trans" << TransStep << ".gf";
|
||||
ofstream trans(TransName.str().c_str());
|
||||
trans.precision(precision);
|
||||
main.Save(trans);
|
||||
TransStep++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tic_toc.Stop();
|
||||
cout << "Time stepping loop done in " << tic_toc.RealTime() << " seconds.\n\n";
|
||||
|
||||
double DomainSize = LumpedMassMat.Sum();
|
||||
if (hyp->SolutionKnown)
|
||||
{
|
||||
Array<double> errors;
|
||||
hyp->ComputeErrors(errors, u, DomainSize, t);
|
||||
cout << "L1 error: " << errors[0] << endl;
|
||||
hyp->WriteErrors(errors);
|
||||
}
|
||||
|
||||
cout << "Min of primary field: " << main.Min() << endl
|
||||
<< "Max of primary field: " << main.Max() << endl
|
||||
<< "Difference in solution mass: "
|
||||
<< abs(InitialMass - LumpedMassMat * main) / DomainSize << "\n\n";
|
||||
|
||||
ostringstream FinalName;
|
||||
FinalName << OutputDir << "/ultimate.gf";
|
||||
ofstream ultimate(FinalName.str().c_str());
|
||||
ultimate.precision(precision);
|
||||
main.Save(ultimate);
|
||||
|
||||
if (VisualizeDerived)
|
||||
{
|
||||
GridFunction v(&fes), p(&fes);
|
||||
hyp->ComputeDerivedQuantities(u, v, p);
|
||||
|
||||
ostringstream VelocityName;
|
||||
VelocityName << OutputDir << "/velocity.gf";
|
||||
ofstream velocity(VelocityName.str().c_str());
|
||||
velocity.precision(precision);
|
||||
v.Save(velocity);
|
||||
|
||||
if (ProblemNum == 5)
|
||||
{
|
||||
ostringstream PressureName;
|
||||
PressureName << OutputDir << "/pressure.gf";
|
||||
ofstream pressure(PressureName.str().c_str());
|
||||
pressure.precision(precision);
|
||||
p.Save(pressure);
|
||||
}
|
||||
}
|
||||
|
||||
delete evol;
|
||||
delete hyp;
|
||||
delete odeSolver;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,416 @@
|
||||
#include "bounds.hpp"
|
||||
|
||||
Bounds::Bounds(FiniteElementSpace *fes_, FiniteElementSpace *fesH1_)
|
||||
: fes(fes_), fesH1(fesH1_), x_min(fesH1_),
|
||||
x_max(fesH1_) //, y_min(fesH1_), y_max(fesH1_)
|
||||
{
|
||||
Mesh *mesh = fes->GetMesh();
|
||||
const FiniteElement *el = fes->GetFE(0);
|
||||
|
||||
nd = el->GetDof();
|
||||
ne = mesh->GetNE();
|
||||
NumEq = fes->GetVSize() / (ne*nd);
|
||||
|
||||
xi_min.SetSize(NumEq*ne*nd);
|
||||
xi_max.SetSize(NumEq*ne*nd);
|
||||
// yi_min.SetSize(NumEq*ne*nd);
|
||||
// yi_max.SetSize(NumEq*ne*nd);
|
||||
|
||||
FillDofMap();
|
||||
}
|
||||
|
||||
void Bounds::FillDofMap()
|
||||
{
|
||||
const FiniteElement *el = fes->GetFE(0);
|
||||
|
||||
if (el->GetGeomType() != Geometry::TRIANGLE)
|
||||
{
|
||||
const TensorBasisElement *TensorElem =
|
||||
dynamic_cast<const TensorBasisElement *>(fesH1->GetFE(0));
|
||||
DofMapH1 = TensorElem->GetDofMap();
|
||||
return;
|
||||
}
|
||||
|
||||
const int p = el->GetOrder();
|
||||
const int nd = (p+1)*(p+2) / 2;
|
||||
DofMapH1.SetSize(nd);
|
||||
|
||||
// Corners
|
||||
DofMapH1[0] = 0;
|
||||
DofMapH1[p] = 1;
|
||||
DofMapH1[nd-1] = 2;
|
||||
|
||||
int ctr1 = 2*p;
|
||||
int ctr2 = nd-3;
|
||||
|
||||
// Element edges
|
||||
for (int i = 1; i < p; i++)
|
||||
{
|
||||
DofMapH1[i] = 2+i;
|
||||
DofMapH1[ctr1] = 2+i+p-1;
|
||||
DofMapH1[ctr2] = 2+i+2*(p-1);
|
||||
ctr1 += (p-i);
|
||||
ctr2 -= 2+i;
|
||||
}
|
||||
|
||||
ctr1 = p+2;
|
||||
ctr2 = 3*p;
|
||||
|
||||
// Element interior
|
||||
for (int j = 1; j < p-1; j++)
|
||||
{
|
||||
for (int i = 1; i < p-j; i++)
|
||||
{
|
||||
DofMapH1[ctr1] = ctr2;
|
||||
ctr1++;
|
||||
ctr2++;
|
||||
}
|
||||
ctr1 += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void Bounds::ComputeBounds(const Vector &x)
|
||||
{
|
||||
x_min = std::numeric_limits<double>::infinity();
|
||||
x_max = -std::numeric_limits<double>::infinity();
|
||||
// y_min = std::numeric_limits<double>::infinity();
|
||||
// y_max = -std::numeric_limits<double>::infinity();
|
||||
|
||||
for (int e = 0; e < ne; e++)
|
||||
{
|
||||
fesH1->GetElementDofs(e, eldofs);
|
||||
ComputeElementBounds(0, e, x);
|
||||
}
|
||||
|
||||
for (int e = 0; e < ne; e++)
|
||||
{
|
||||
fesH1->GetElementDofs(e, eldofs);
|
||||
for (int j = 0; j < nd; j++)
|
||||
{
|
||||
xi_min(e*nd + j) = x_min(eldofs[DofMapH1[j]]);
|
||||
xi_max(e*nd + j) = x_max(eldofs[DofMapH1[j]]);
|
||||
// yi_min(e*nd + j) = y_min(eldofs[DofMapH1[j]]);
|
||||
// yi_max(e*nd + j) = y_max(eldofs[DofMapH1[j]]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int n = 1; n < NumEq; n++)
|
||||
{
|
||||
x_min = std::numeric_limits<double>::infinity();
|
||||
x_max = -std::numeric_limits<double>::infinity();
|
||||
// y_min = std::numeric_limits<double>::infinity();
|
||||
// y_max = -std::numeric_limits<double>::infinity();
|
||||
|
||||
for (int e = 0; e < ne; e++)
|
||||
{
|
||||
fesH1->GetElementDofs(e, eldofs);
|
||||
ComputeSequentialBounds(n, e, x);
|
||||
}
|
||||
|
||||
for (int e = 0; e < ne; e++)
|
||||
{
|
||||
fesH1->GetElementDofs(e, eldofs);
|
||||
for (int j = 0; j < nd; j++)
|
||||
{
|
||||
xi_min(n*ne*nd + e*nd + j) = x_min(eldofs[DofMapH1[j]]);
|
||||
xi_max(n*ne*nd + e*nd + j) = x_max(eldofs[DofMapH1[j]]);
|
||||
// yi_min(n*ne*nd + e*nd + j) = y_min(eldofs[DofMapH1[j]]);
|
||||
// yi_max(n*ne*nd + e*nd + j) = y_max(eldofs[DofMapH1[j]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TightBounds::TightBounds(FiniteElementSpace *fes_, FiniteElementSpace *fesH1_)
|
||||
: Bounds(fes_, fesH1_)
|
||||
{
|
||||
FillClosestNbrs(fes->GetFE(0), ClosestNbrs);
|
||||
}
|
||||
|
||||
void TightBounds::ComputeElementBounds(int n, int e, const Vector &x)
|
||||
{
|
||||
for (int i = 0; i < nd; i++)
|
||||
{
|
||||
const int I = eldofs[DofMapH1[i]];
|
||||
x_min(I) = min(x_min(I), xi_min(n*ne*nd + e*nd + i));
|
||||
x_max(I) = max(x_max(I), xi_max(n*ne*nd + e*nd + i));
|
||||
// y_min(I) = min(y_min(I), yi_min(n*ne*nd + e*nd + i)); // not used for now
|
||||
// y_max(I) = max(y_max(I), yi_max(n*ne*nd + e*nd + i)); // not used for now
|
||||
|
||||
for (int j = 0; j < ClosestNbrs.Width(); j++)
|
||||
{
|
||||
if (ClosestNbrs(i,j) == -1) { break; }
|
||||
|
||||
const int J = n*ne*nd + e*nd + ClosestNbrs(i,j);
|
||||
x_min(I) = min(x_min(I), x(J));
|
||||
x_max(I) = max(x_max(I), x(J));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TightBounds::ComputeSequentialBounds(int n, int e, const Vector &x)
|
||||
{
|
||||
for (int i = 0; i < nd; i++)
|
||||
{
|
||||
const int I = eldofs[DofMapH1[i]];
|
||||
x_min(I) = min(x_min(I), xi_min(n*ne*nd + e*nd + i));
|
||||
x_max(I) = max(x_max(I), xi_max(n*ne*nd + e*nd + i));
|
||||
// y_min(I) = min(y_min(I), yi_min(n*ne*nd + e*nd + i));
|
||||
// y_max(I) = max(y_max(I), yi_max(n*ne*nd + e*nd + i));
|
||||
|
||||
// for (int j = 0; j < ClosestNbrs.Width(); j++)
|
||||
// {
|
||||
// if (ClosestNbrs(i,j) == -1) { break; }
|
||||
|
||||
// const int J = n*ne*nd + e*nd + ClosestNbrs(i,j);
|
||||
// x_min(I) = min(x_min(I), x(J) / x(e*nd + ClosestNbrs(i,j)));
|
||||
// x_max(I) = max(x_max(I), x(J) / x(e*nd + ClosestNbrs(i,j)));
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
LooseBounds::LooseBounds(FiniteElementSpace *fes_, FiniteElementSpace *fesH1_)
|
||||
: Bounds(fes_, fesH1_) { }
|
||||
|
||||
void LooseBounds::ComputeElementBounds(int n, int e, const Vector &x)
|
||||
{
|
||||
double xe_min = std::numeric_limits<double>::infinity();
|
||||
double xe_max = -std::numeric_limits<double>::infinity();
|
||||
|
||||
for (int j = 0; j < nd; j++)
|
||||
{
|
||||
xe_min = min(xe_min, x(n*ne*nd + e*nd+j));
|
||||
xe_max = max(xe_max, x(n*ne*nd + e*nd+j));
|
||||
}
|
||||
|
||||
for (int j = 0; j < nd; j++)
|
||||
{
|
||||
int I = eldofs[DofMapH1[j]];
|
||||
x_min(I) = min(x_min(I), xe_min);
|
||||
x_max(I) = max(x_max(I), xe_max);
|
||||
}
|
||||
}
|
||||
|
||||
void LooseBounds::ComputeSequentialBounds(int n, int e, const Vector &x)
|
||||
{
|
||||
for (int i = 0; i < nd; i++)
|
||||
{
|
||||
const int I = eldofs[DofMapH1[i]];
|
||||
x_min(I) = min(x_min(I), xi_min(n*ne*nd + e*nd + i));
|
||||
x_max(I) = max(x_max(I), xi_max(n*ne*nd + e*nd + i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FillClosestNbrs(const FiniteElement *el, DenseMatrix &ClosestNbrs)
|
||||
{
|
||||
const int nd = el->GetDof();
|
||||
const int p = el->GetOrder();
|
||||
Geometry::Type gtype = el->GetGeomType();
|
||||
|
||||
switch (gtype)
|
||||
{
|
||||
case Geometry::SEGMENT:
|
||||
{
|
||||
ClosestNbrs.SetSize(nd, p==1 ? 2 : 3);
|
||||
ClosestNbrs = -1;
|
||||
|
||||
ClosestNbrs(0,0) = 0;
|
||||
ClosestNbrs(0,1) = 1;
|
||||
|
||||
for (int i = 1; i < p; i++)
|
||||
{
|
||||
ClosestNbrs(i,0) = i-1;
|
||||
ClosestNbrs(i,1) = i;
|
||||
ClosestNbrs(i,2) = i+1;
|
||||
}
|
||||
|
||||
ClosestNbrs(p,0) = p-1;
|
||||
ClosestNbrs(p,1) = p;
|
||||
break;
|
||||
}
|
||||
case Geometry::TRIANGLE:
|
||||
{
|
||||
ClosestNbrs.SetSize(nd, p==1 ? 3 : (p==2 ? 5 : 7));
|
||||
ClosestNbrs = -1;
|
||||
|
||||
ClosestNbrs(0,0) = 0;
|
||||
ClosestNbrs(0,1) = 1;
|
||||
ClosestNbrs(0,2) = p+1;
|
||||
|
||||
for (int i = 1; i < p; i++)
|
||||
{
|
||||
ClosestNbrs(i,0) = i-1;
|
||||
ClosestNbrs(i,1) = i;
|
||||
ClosestNbrs(i,2) = i+1;
|
||||
ClosestNbrs(i,3) = p+i;
|
||||
ClosestNbrs(i,4) = p+i+1;
|
||||
}
|
||||
|
||||
ClosestNbrs(p,0) = p-1;
|
||||
ClosestNbrs(p,1) = p;
|
||||
ClosestNbrs(p,2) = 2*p;
|
||||
|
||||
int ctr = p+1;
|
||||
for (int j = 1; j < p; j++)
|
||||
{
|
||||
int lower = (j-1)*(p+2) - (j-1)*j/2;
|
||||
int upper = lower + 2*(p-j) + 3;
|
||||
|
||||
ClosestNbrs(ctr,0) = lower;
|
||||
ClosestNbrs(ctr,1) = lower+1;
|
||||
ClosestNbrs(ctr,2) = ctr;
|
||||
ClosestNbrs(ctr,3) = ctr+1;
|
||||
ClosestNbrs(ctr,4) = upper;
|
||||
ctr++;
|
||||
|
||||
for (int i = 1; i < p-j; i++)
|
||||
{
|
||||
ClosestNbrs(ctr,0) = lower+i;
|
||||
ClosestNbrs(ctr,1) = lower+i+1;
|
||||
ClosestNbrs(ctr,2) = ctr-1;
|
||||
ClosestNbrs(ctr,3) = ctr;
|
||||
ClosestNbrs(ctr,4) = ctr+1;
|
||||
ClosestNbrs(ctr,5) = upper+i-1;
|
||||
ClosestNbrs(ctr,6) = upper+i;
|
||||
ctr++;
|
||||
}
|
||||
|
||||
ClosestNbrs(ctr,0) = lower + p-j;
|
||||
ClosestNbrs(ctr,1) = lower + p-j+1;
|
||||
ClosestNbrs(ctr,2) = ctr-1;
|
||||
ClosestNbrs(ctr,3) = ctr;
|
||||
ClosestNbrs(ctr,4) = upper+p-j-1;
|
||||
ctr++;
|
||||
}
|
||||
|
||||
ClosestNbrs(nd-1,0) = nd-3;
|
||||
ClosestNbrs(nd-1,1) = nd-2;
|
||||
ClosestNbrs(nd-1,2) = nd-1;
|
||||
|
||||
break;
|
||||
}
|
||||
case Geometry::SQUARE:
|
||||
{
|
||||
ClosestNbrs.SetSize(nd, p == 1 ? 4: 9);
|
||||
ClosestNbrs = -1;
|
||||
|
||||
for (int i = 0; i < nd; i++)
|
||||
{
|
||||
int ctr = 0;
|
||||
|
||||
// lower neighbors
|
||||
if (i > p)
|
||||
{
|
||||
if (i % (p+1) != 0) { ClosestNbrs(i,ctr) = i-p-2; ctr++; }
|
||||
ClosestNbrs(i,ctr) = i-p-1; ctr++;
|
||||
if ((i+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = i-p; ctr++; }
|
||||
}
|
||||
|
||||
// horizontal neighbors
|
||||
if (i % (p+1) != 0) { ClosestNbrs(i,ctr) = i-1; ctr++; }
|
||||
ClosestNbrs(i,ctr) = i; ctr++;
|
||||
if ((i+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = i+1; ctr++; }
|
||||
|
||||
// upper neighbors
|
||||
if (i < p*(p+1))
|
||||
{
|
||||
if (i % (p+1) != 0) { ClosestNbrs(i,ctr) = i+p; ctr++; }
|
||||
ClosestNbrs(i,ctr) = i+p+1; ctr++;
|
||||
if ((i+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = i+p+2; ctr++; }
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case Geometry::CUBE:
|
||||
{
|
||||
ClosestNbrs.SetSize(nd, p==1 ? 8 : 27);
|
||||
ClosestNbrs = -1;
|
||||
|
||||
for (int i = 0; i < nd; i++)
|
||||
{
|
||||
int ctr = 0;
|
||||
|
||||
if (i >= (p+1)*(p+1)) // There is a lower plane
|
||||
{
|
||||
int k = i - (p+1)*(p+1); // lower neighbor in z direction
|
||||
int j = k % ((p+1)*(p+1));
|
||||
|
||||
// lower neighbors in y direction
|
||||
if (j > p)
|
||||
{
|
||||
if (j % (p+1) != 0) { ClosestNbrs(i,ctr) = k-p-2; ctr++; }
|
||||
ClosestNbrs(i,ctr) = k-p-1; ctr++;
|
||||
if ((j+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = k-p; ctr++; }
|
||||
}
|
||||
|
||||
// horizontal neighbors
|
||||
if (j % (p+1) != 0) { ClosestNbrs(i,ctr) = k-1; ctr++; }
|
||||
ClosestNbrs(i,ctr) = k; ctr++;
|
||||
if ((j+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = k+1; ctr++; }
|
||||
|
||||
// upper neighbors
|
||||
if (j < p*(p+1))
|
||||
{
|
||||
if (j % (p+1) != 0) { ClosestNbrs(i,ctr) = k+p; ctr++; }
|
||||
ClosestNbrs(i,ctr) = k+p+1; ctr++;
|
||||
if ((j+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = k+p+2; ctr++; }
|
||||
}
|
||||
}
|
||||
|
||||
int j = i % ((p+1)*(p+1));
|
||||
|
||||
// lower neighbors
|
||||
if (j > p)
|
||||
{
|
||||
if (j % (p+1) != 0) { ClosestNbrs(i,ctr) = i-p-2; ctr++; }
|
||||
ClosestNbrs(i,ctr) = i-p-1; ctr++;
|
||||
if ((j+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = i-p; ctr++; }
|
||||
}
|
||||
|
||||
// horizontal neighbors
|
||||
if (j % (p+1) != 0) { ClosestNbrs(i,ctr) = i-1; ctr++; }
|
||||
ClosestNbrs(i,ctr) = i; ctr++;
|
||||
if ((j+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = i+1; ctr++; }
|
||||
|
||||
// upper neighbors
|
||||
if (j < p*(p+1))
|
||||
{
|
||||
if (j % (p+1) != 0) { ClosestNbrs(i,ctr) = i+p; ctr++; }
|
||||
ClosestNbrs(i,ctr) = i+p+1; ctr++;
|
||||
if ((j+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = i+p+2; ctr++; }
|
||||
}
|
||||
|
||||
if (i < p*(p+1)*(p+1)) // There is an upper plane
|
||||
{
|
||||
int k = i + (p+1)*(p+1); // upper neighbor in z direction
|
||||
int j = k % ((p+1)*(p+1));
|
||||
|
||||
// lower neighbors in y direction
|
||||
if (j > p)
|
||||
{
|
||||
if (j % (p+1) != 0) { ClosestNbrs(i,ctr) = k-p-2; ctr++; }
|
||||
ClosestNbrs(i,ctr) = k-p-1; ctr++;
|
||||
if ((j+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = k-p; ctr++; }
|
||||
}
|
||||
|
||||
// horizontal neighbors
|
||||
if (j % (p+1) != 0) { ClosestNbrs(i,ctr) = k-1; ctr++; }
|
||||
ClosestNbrs(i,ctr) = k; ctr++;
|
||||
if ((j+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = k+1; ctr++; }
|
||||
|
||||
// upper neighbors
|
||||
if (j < p*(p+1))
|
||||
{
|
||||
if (j % (p+1) != 0) { ClosestNbrs(i,ctr) = k+p; ctr++; }
|
||||
ClosestNbrs(i,ctr) = k+p+1; ctr++;
|
||||
if ((j+1) % (p+1) != 0) { ClosestNbrs(i,ctr) = k+p+2; ctr++; }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#ifndef HYPSYS_BOUNDS
|
||||
#define HYPSYS_BOUNDS
|
||||
|
||||
#include "mfem.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
class Bounds
|
||||
{
|
||||
public:
|
||||
FiniteElementSpace *fes, *fesH1;
|
||||
GridFunction x_min, x_max; // element bounds for each H1 dof
|
||||
// GridFunction y_min, y_max; // element bounds for each H1 dof
|
||||
Vector xi_min, xi_max; // element bounds for each L2 dof
|
||||
// Vector yi_min, yi_max; // flux term bounds for each L2 dof
|
||||
Array<int> eldofs, DofMapH1;
|
||||
int nd, ne, NumEq;
|
||||
|
||||
Bounds(FiniteElementSpace *fes_, FiniteElementSpace *fesH1_);
|
||||
|
||||
virtual ~Bounds() { }
|
||||
|
||||
void FillDofMap();
|
||||
|
||||
virtual void ComputeBounds(const Vector &x);
|
||||
virtual void ComputeElementBounds(int n, int e, const Vector &x) = 0;
|
||||
virtual void ComputeSequentialBounds(int n, int e, const Vector &x) = 0;
|
||||
};
|
||||
|
||||
class TightBounds : public Bounds
|
||||
{
|
||||
public:
|
||||
DenseMatrix ClosestNbrs;
|
||||
|
||||
TightBounds(FiniteElementSpace *fes_, FiniteElementSpace *fesH1_);
|
||||
~TightBounds() { }
|
||||
|
||||
virtual void ComputeElementBounds(int n, int e, const Vector &x) override;
|
||||
virtual void ComputeSequentialBounds(int n, int e, const Vector &x) override;
|
||||
};
|
||||
|
||||
class LooseBounds : public Bounds
|
||||
{
|
||||
public:
|
||||
LooseBounds(FiniteElementSpace *fes_, FiniteElementSpace *fesH1_);
|
||||
~LooseBounds() { }
|
||||
|
||||
virtual void ComputeElementBounds(int n, int e, const Vector &x) override;
|
||||
virtual void ComputeSequentialBounds(int n, int e, const Vector &x) override;
|
||||
};
|
||||
|
||||
void FillClosestNbrs(const FiniteElement *el, DenseMatrix &ClosestNbrs);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,847 @@
|
||||
#include "dofs.hpp"
|
||||
|
||||
DofInfo::DofInfo(FiniteElementSpace *fes_)
|
||||
: mesh(fes_->GetMesh()), fes(fes_)
|
||||
{
|
||||
dim = mesh->Dimension();
|
||||
|
||||
FillBdrDofs();
|
||||
NumFaceDofs = BdrDofs.Height();
|
||||
NumBdrs = BdrDofs.Width();
|
||||
|
||||
FillNeighborDofs();
|
||||
FillSubcell2CellDof();
|
||||
FillLoc2Multiindex();
|
||||
}
|
||||
|
||||
void DofInfo::FillLoc2Multiindex()
|
||||
{
|
||||
const FiniteElement *el = fes->GetFE(0);
|
||||
if (el->GetGeomType() != Geometry::TRIANGLE) { return; }
|
||||
|
||||
const int p = el->GetOrder();
|
||||
const int nd = (p+1)*(p+2)/2;
|
||||
Loc2Multiindex.SetSize(nd,3);
|
||||
Vector a(3);
|
||||
a = 0.;
|
||||
a(0) = p;
|
||||
int ctr = 0;
|
||||
|
||||
for (int j = 0; j <= p; j++)
|
||||
{
|
||||
for (int i = 0; i <= p-j; i++)
|
||||
{
|
||||
Loc2Multiindex.SetRow(ctr,a);
|
||||
ctr = ctr+1;
|
||||
a(0)--;
|
||||
a(1)++;
|
||||
}
|
||||
|
||||
a(0) = p-1-j;
|
||||
a(1) = 0;
|
||||
a(2)++;
|
||||
|
||||
if (a.Sum() != p)
|
||||
{
|
||||
MFEM_ABORT("Invalid Multiindex");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int DofInfo::GetLocFromMultiindex(int p, const Vector &a) const
|
||||
{
|
||||
if (a.Sum() != p || a.Min() < 0 || a.Size() != 3)
|
||||
{
|
||||
MFEM_ABORT("Invalid Multiindex");
|
||||
}
|
||||
|
||||
return (p+1)*a(2) - a(2)*(a(2)-1)/2 + a(1);
|
||||
}
|
||||
|
||||
void DofInfo::FillNeighborDofs()
|
||||
{
|
||||
// Use the first mesh element as indicator.
|
||||
const FiniteElement &el = *fes->GetFE(0);
|
||||
int i, j, e, nbr, ne = mesh->GetNE();
|
||||
int nd = el.GetDof(), p = el.GetOrder();
|
||||
Array <int> bdrs, orientation;
|
||||
FaceElementTransformations *Trans;
|
||||
|
||||
Table *face_to_el = mesh->GetFaceToElementTable();
|
||||
|
||||
NbrDofs.SetSize(NumBdrs, NumFaceDofs, ne);
|
||||
|
||||
// Permutations of BdrDofs, taking into account all possible orientations.
|
||||
// Assumes BdrDofs are ordered in xyz order, which is true for 3D hexes,
|
||||
// but it isn't true for 2D quads.
|
||||
int orient_cnt = 1;
|
||||
if (dim == 2) { orient_cnt = 2; }
|
||||
if (dim == 3) { orient_cnt = 8; }
|
||||
const int dof1D_cnt = p+1;
|
||||
DenseTensor fdof_ids(NumFaceDofs, NumBdrs, orient_cnt);
|
||||
for (int ori = 0; ori < orient_cnt; ori++)
|
||||
{
|
||||
for (int face_id = 0; face_id < NumBdrs; face_id++)
|
||||
{
|
||||
for (int fdof_id = 0; fdof_id < NumFaceDofs; fdof_id++)
|
||||
{
|
||||
// Index of fdof_id in the current orientation.
|
||||
const int ori_fdof_id = GetLocalFaceDofIndex(dim, face_id, ori,
|
||||
fdof_id, dof1D_cnt);
|
||||
fdof_ids(ori)(ori_fdof_id, face_id) = BdrDofs(fdof_id, face_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (e = 0; e < ne; e++)
|
||||
{
|
||||
if (dim==1)
|
||||
{
|
||||
mesh->GetElementVertices(e, bdrs);
|
||||
|
||||
for (i = 0; i < NumBdrs; i++)
|
||||
{
|
||||
const int nbr_cnt = face_to_el->RowSize(bdrs[i]);
|
||||
if (nbr_cnt == 1)
|
||||
{
|
||||
// No neighbor element.
|
||||
NbrDofs(i,0,e) = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
int el1_id, el2_id, nbr_id;
|
||||
mesh->GetFaceElements(bdrs[i], &el1_id, &el2_id);
|
||||
if (el2_id < 0)
|
||||
{
|
||||
// This element is in a different mpi task.
|
||||
el2_id = -1 - el2_id + ne;
|
||||
}
|
||||
nbr_id = (el1_id == e) ? el2_id : el1_id;
|
||||
NbrDofs(i,0,e) = nbr_id*nd + BdrDofs(0,(i+1)%2);
|
||||
}
|
||||
}
|
||||
else if (dim==2)
|
||||
{
|
||||
mesh->GetElementEdges(e, bdrs, orientation);
|
||||
|
||||
for (i = 0; i < NumBdrs; i++)
|
||||
{
|
||||
const int nbr_cnt = face_to_el->RowSize(bdrs[i]);
|
||||
if (nbr_cnt == 1)
|
||||
{
|
||||
// No neighbor element.
|
||||
for (j = 0; j < NumFaceDofs; j++) { NbrDofs(i,j,e) = -1; }
|
||||
continue;
|
||||
}
|
||||
|
||||
int el1_id, el2_id, nbr_id;
|
||||
mesh->GetFaceElements(bdrs[i], &el1_id, &el2_id);
|
||||
if (el2_id < 0)
|
||||
{
|
||||
// This element is in a different mpi task.
|
||||
el2_id = -1 - el2_id + ne;
|
||||
}
|
||||
nbr_id = (el1_id == e) ? el2_id : el1_id;
|
||||
|
||||
int el1_info, el2_info;
|
||||
mesh->GetFaceInfos(bdrs[i], &el1_info, &el2_info);
|
||||
const int face_id_nbr = (nbr_id == el1_id) ? el1_info / 64
|
||||
: el2_info / 64;
|
||||
for (j = 0; j < NumFaceDofs; j++)
|
||||
{
|
||||
// Here it is utilized that the orientations of the face for
|
||||
// the two elements are opposite of each other.
|
||||
NbrDofs(i,j,e) = nbr_id*nd + BdrDofs(NumFaceDofs - 1 - j,
|
||||
face_id_nbr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (dim==3)
|
||||
{
|
||||
mesh->GetElementFaces(e, bdrs, orientation);
|
||||
|
||||
for (int f = 0; f < NumBdrs; f++)
|
||||
{
|
||||
const int nbr_cnt = face_to_el->RowSize(bdrs[f]);
|
||||
if (nbr_cnt == 1)
|
||||
{
|
||||
// No neighbor element.
|
||||
for (j = 0; j < NumFaceDofs; j++) { NbrDofs(f,j,e) = -1; }
|
||||
continue;
|
||||
}
|
||||
|
||||
int el1_id, el2_id, nbr_id;
|
||||
mesh->GetFaceElements(bdrs[f], &el1_id, &el2_id);
|
||||
if (el2_id < 0)
|
||||
{
|
||||
// This element is in a different mpi task.
|
||||
el2_id = -1 - el2_id + ne;
|
||||
}
|
||||
nbr_id = (el1_id == e) ? el2_id : el1_id;
|
||||
|
||||
// Local index and orientation of the face, when considered in
|
||||
// the neighbor element.
|
||||
int el1_info, el2_info;
|
||||
mesh->GetFaceInfos(bdrs[f], &el1_info, &el2_info);
|
||||
const int face_id_nbr = (nbr_id == el1_id) ? el1_info / 64
|
||||
: el2_info / 64;
|
||||
const int face_or_nbr = (nbr_id == el1_id) ? el1_info % 64
|
||||
: el2_info % 64;
|
||||
for (j = 0; j < NumFaceDofs; j++)
|
||||
{
|
||||
// What is the index of the j-th dof on the face, given its
|
||||
// orientation.
|
||||
const int loc_face_dof_id =
|
||||
GetLocalFaceDofIndex(dim, face_id_nbr, face_or_nbr,
|
||||
j, dof1D_cnt);
|
||||
// What is the corresponding local dof id on the element,
|
||||
// given the face orientation.
|
||||
const int nbr_dof_id =
|
||||
fdof_ids(face_or_nbr)(loc_face_dof_id, face_id_nbr);
|
||||
|
||||
NbrDofs(f,j,e) = nbr_id*nd + nbr_dof_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (e = 0; e < fes->GetNBE(); e++)
|
||||
{
|
||||
const int bdr_attr = mesh->GetBdrAttribute(e);
|
||||
FaceElementTransformations *tr = mesh->GetBdrFaceTransformations(e);
|
||||
|
||||
if (tr != NULL)
|
||||
{
|
||||
const int el = tr->Elem1No;
|
||||
|
||||
if (dim == 1) { mesh->GetElementVertices(el, bdrs); }
|
||||
else if (dim == 2) { mesh->GetElementEdges(el, bdrs, orientation); }
|
||||
else if (dim == 3) { mesh->GetElementFaces(el, bdrs, orientation); }
|
||||
|
||||
for (i = 0; i < NumBdrs; i++)
|
||||
{
|
||||
if (bdrs[i] == mesh->GetBdrElementEdgeIndex(e))
|
||||
{
|
||||
for (j = 0; j < NumFaceDofs; j++)
|
||||
{
|
||||
NbrDofs(i, j, el) = -bdr_attr;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MFEM_ABORT("Something went wrong.");
|
||||
}
|
||||
}
|
||||
|
||||
delete face_to_el;
|
||||
}
|
||||
|
||||
void DofInfo::FillSubcell2CellDof()
|
||||
{
|
||||
const FiniteElement &el = *fes->GetFE(0);
|
||||
int j, m, aux, p = el.GetOrder();
|
||||
Geometry::Type gtype = el.GetGeomType();
|
||||
|
||||
if (dim==1)
|
||||
{
|
||||
numSubcells = p;
|
||||
numDofsSubcell = 2;
|
||||
}
|
||||
else if (dim==2)
|
||||
{
|
||||
if (gtype == Geometry::TRIANGLE)
|
||||
{
|
||||
numSubcells = 1;
|
||||
numDofsSubcell = 3;
|
||||
for (int i = 1; i < p; i++)
|
||||
{
|
||||
numSubcells += 2*i+1;
|
||||
}
|
||||
}
|
||||
else if (gtype == Geometry::SQUARE)
|
||||
{
|
||||
numSubcells = p*p;
|
||||
numDofsSubcell = 4;
|
||||
}
|
||||
}
|
||||
else if (dim==3)
|
||||
{
|
||||
numSubcells = p*p*p;
|
||||
numDofsSubcell = 8;
|
||||
}
|
||||
|
||||
Sub2Ind.SetSize(numSubcells, numDofsSubcell);
|
||||
|
||||
if (gtype == Geometry::TRIANGLE)
|
||||
{
|
||||
int nd = (p+1)*(p+2) / 2;
|
||||
|
||||
int ctr = numSubcells - 1;
|
||||
int node = nd - 1;
|
||||
int old;
|
||||
aux = 1;
|
||||
for (int iy = p; iy > 0; iy--)
|
||||
{
|
||||
old = node;
|
||||
Sub2Ind(ctr,2) = node;
|
||||
Sub2Ind(ctr,1) = node - aux;
|
||||
Sub2Ind(ctr,0) = node - aux - 1;
|
||||
ctr--;
|
||||
|
||||
for (int ix = p - iy; ix > 0; ix--)
|
||||
{
|
||||
Sub2Ind(ctr,2) = node;
|
||||
Sub2Ind(ctr,1) = node - aux - 1;
|
||||
Sub2Ind(ctr,0) = node - 1;
|
||||
ctr--;
|
||||
node--;
|
||||
|
||||
Sub2Ind(ctr,2) = node;
|
||||
Sub2Ind(ctr,1) = node - aux;
|
||||
Sub2Ind(ctr,0) = node - aux - 1;
|
||||
ctr--;
|
||||
}
|
||||
|
||||
node = old - aux;
|
||||
aux++;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (m = 0; m < numSubcells; m++)
|
||||
{
|
||||
for (j = 0; j < numDofsSubcell; j++)
|
||||
{
|
||||
if (dim == 1) { Sub2Ind(m,j) = m + j; }
|
||||
else if (dim == 2 && gtype == Geometry::SQUARE)
|
||||
{
|
||||
aux = m + m/p;
|
||||
switch (j)
|
||||
{
|
||||
case 0: Sub2Ind(m,j) = aux; break;
|
||||
case 1: Sub2Ind(m,j) = aux + 1; break;
|
||||
case 2: Sub2Ind(m,j) = aux + p+1; break;
|
||||
case 3: Sub2Ind(m,j) = aux + p+2; break;
|
||||
}
|
||||
}
|
||||
else if (dim == 3 && gtype == Geometry::CUBE)
|
||||
{
|
||||
aux = m + m/p + (p+1)*(m/(p*p));
|
||||
switch (j)
|
||||
{
|
||||
case 0: Sub2Ind(m,j) = aux; break;
|
||||
case 1: Sub2Ind(m,j) = aux + 1; break;
|
||||
case 2: Sub2Ind(m,j) = aux + p+1; break;
|
||||
case 3: Sub2Ind(m,j) = aux + p+2; break;
|
||||
case 4: Sub2Ind(m,j) = aux + (p+1)*(p+1); break;
|
||||
case 5: Sub2Ind(m,j) = aux + (p+1)*(p+1)+1; break;
|
||||
case 6: Sub2Ind(m,j) = aux + (p+1)*(p+1)+p+1; break;
|
||||
case 7: Sub2Ind(m,j) = aux + (p+1)*(p+1)+p+2; break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MFEM_ABORT("Tetraheadra are not supported.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DofInfo::FillBdrDofs()
|
||||
{
|
||||
const FiniteElement *el = fes->GetFE(0);
|
||||
Geometry::Type gtype = el->GetGeomType();
|
||||
int p = el->GetOrder();
|
||||
|
||||
switch (gtype)
|
||||
{
|
||||
case Geometry::SEGMENT:
|
||||
{
|
||||
BdrDofs.SetSize(1,2);
|
||||
BdrDofs(0,0) = 0;
|
||||
BdrDofs(0,1) = p;
|
||||
break;
|
||||
}
|
||||
case Geometry::TRIANGLE:
|
||||
{
|
||||
int ctr = 0;
|
||||
BdrDofs.SetSize(p+1, 3);
|
||||
for (int i = 0; i <= p; i++)
|
||||
{
|
||||
BdrDofs(i,0) = i;
|
||||
BdrDofs(i,1) = ctr + p;
|
||||
BdrDofs(p-i,2) = ctr + i;
|
||||
ctr += p - i;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Geometry::SQUARE:
|
||||
{
|
||||
BdrDofs.SetSize(p+1,4);
|
||||
for (int i = 0; i <= p; i++)
|
||||
{
|
||||
BdrDofs(i,0) = i;
|
||||
BdrDofs(i,1) = i*(p+1) + p;
|
||||
BdrDofs(i,2) = (p+1)*(p+1) - 1 - i;
|
||||
BdrDofs(i,3) = (p-i)*(p+1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Geometry::TETRAHEDRON:
|
||||
{
|
||||
int ctr;
|
||||
BdrDofs.SetSize((p+1)*(p+2)/2, 4);
|
||||
for (int bdrID = 0; bdrID < 4; bdrID++)
|
||||
{
|
||||
int o = 0;
|
||||
switch (bdrID)
|
||||
{
|
||||
case 0:
|
||||
ctr = p;
|
||||
for (int i = 0; i <= p; i++)
|
||||
{
|
||||
for (int j = 0; j <= p - i; j++)
|
||||
{
|
||||
BdrDofs(o++,bdrID) = ctr;
|
||||
ctr += p - i - j;
|
||||
}
|
||||
ctr += p - i;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
ctr = 0;
|
||||
for (int i = 0; i <= p; i++)
|
||||
{
|
||||
for (int j = 0; j <= p - i; j++)
|
||||
{
|
||||
BdrDofs(o++,bdrID) = ctr;
|
||||
ctr += p + 1 - i - j;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
ctr = 0;
|
||||
for (int i = 0; i <= p; i++)
|
||||
{
|
||||
for (int j = 0; j <= p - i; j++)
|
||||
{
|
||||
BdrDofs(o++,bdrID) = ctr++;
|
||||
}
|
||||
ctr += - p + i - 1 + (p-i+1)*(p-i+2)/2;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
for (int i = 0; i < (p+1)*(p+2)/2; i++)
|
||||
{
|
||||
BdrDofs(o++,bdrID) = i;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Geometry::CUBE:
|
||||
{
|
||||
BdrDofs.SetSize((p+1)*(p+1), 6);
|
||||
for (int bdrID = 0; bdrID < 6; bdrID++)
|
||||
{
|
||||
int o(0);
|
||||
switch (bdrID)
|
||||
{
|
||||
case 0:
|
||||
for (int i = 0; i < (p+1)*(p+1); i++)
|
||||
{
|
||||
BdrDofs(o++,bdrID) = i;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
for (int i = 0; i <= p*(p+1)*(p+1); i+=(p+1)*(p+1))
|
||||
for (int j = 0; j < p+1; j++)
|
||||
{
|
||||
BdrDofs(o++,bdrID) = i+j;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
for (int i = p; i < (p+1)*(p+1)*(p+1); i+=p+1)
|
||||
{
|
||||
BdrDofs(o++,bdrID) = i;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
for (int i = 0; i <= p*(p+1)*(p+1); i+=(p+1)*(p+1))
|
||||
for (int j = p*(p+1); j < (p+1)*(p+1); j++)
|
||||
{
|
||||
BdrDofs(o++,bdrID) = i+j;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
for (int i = 0; i <= (p+1)*((p+1)*(p+1)-1); i+=p+1)
|
||||
{
|
||||
BdrDofs(o++,bdrID) = i;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
for (int i = p*(p+1)*(p+1); i < (p+1)*(p+1)*(p+1); i++)
|
||||
{
|
||||
BdrDofs(o++,bdrID) = i;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: MFEM_ABORT("Geometry not implemented.");
|
||||
}
|
||||
}
|
||||
|
||||
int DofInfo::GetLocalFaceDofIndex3D(int loc_face_id, int face_orient,
|
||||
int face_dof_id, int face_dof1D_cnt)
|
||||
{
|
||||
int k1, k2;
|
||||
const int kf1 = face_dof_id % face_dof1D_cnt;
|
||||
const int kf2 = face_dof_id / face_dof1D_cnt;
|
||||
switch (loc_face_id)
|
||||
{
|
||||
case 0://BOTTOM
|
||||
switch (face_orient)
|
||||
{
|
||||
case 0://{0, 1, 2, 3}
|
||||
k1 = kf1;
|
||||
k2 = face_dof1D_cnt-1-kf2;
|
||||
break;
|
||||
case 1://{0, 3, 2, 1}
|
||||
k1 = face_dof1D_cnt-1-kf2;
|
||||
k2 = kf1;
|
||||
break;
|
||||
case 2://{1, 2, 3, 0}
|
||||
k1 = face_dof1D_cnt-1-kf2;
|
||||
k2 = face_dof1D_cnt-1-kf1;
|
||||
break;
|
||||
case 3://{1, 0, 3, 2}
|
||||
k1 = face_dof1D_cnt-1-kf1;
|
||||
k2 = face_dof1D_cnt-1-kf2;
|
||||
break;
|
||||
case 4://{2, 3, 0, 1}
|
||||
k1 = face_dof1D_cnt-1-kf1;
|
||||
k2 = kf2;
|
||||
break;
|
||||
case 5://{2, 1, 0, 3}
|
||||
k1 = kf2;
|
||||
k2 = face_dof1D_cnt-1-kf1;
|
||||
break;
|
||||
case 6://{3, 0, 1, 2}
|
||||
k1 = kf2;
|
||||
k2 = kf1;
|
||||
break;
|
||||
case 7://{3, 2, 1, 0}
|
||||
k1 = kf1;
|
||||
k2 = kf2;
|
||||
break;
|
||||
default:
|
||||
mfem_error("This orientation does not exist in 3D");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 1://SOUTH
|
||||
switch (face_orient)
|
||||
{
|
||||
case 0://{0, 1, 2, 3}
|
||||
k1 = kf1;
|
||||
k2 = kf2;
|
||||
break;
|
||||
case 1://{0, 3, 2, 1}
|
||||
k1 = kf2;
|
||||
k2 = kf1;
|
||||
break;
|
||||
case 2://{1, 2, 3, 0}
|
||||
k1 = kf2;
|
||||
k2 = face_dof1D_cnt-1-kf1;
|
||||
break;
|
||||
case 3://{1, 0, 3, 2}
|
||||
k1 = face_dof1D_cnt-1-kf1;
|
||||
k2 = kf2;
|
||||
break;
|
||||
case 4://{2, 3, 0, 1}
|
||||
k1 = face_dof1D_cnt-1-kf1;
|
||||
k2 = face_dof1D_cnt-1-kf2;
|
||||
break;
|
||||
case 5://{2, 1, 0, 3}
|
||||
k1 = face_dof1D_cnt-1-kf2;
|
||||
k2 = face_dof1D_cnt-1-kf1;
|
||||
break;
|
||||
case 6://{3, 0, 1, 2}
|
||||
k1 = face_dof1D_cnt-1-kf2;
|
||||
k2 = kf1;
|
||||
break;
|
||||
case 7://{3, 2, 1, 0}
|
||||
k1 = kf1;
|
||||
k2 = face_dof1D_cnt-1-kf2;
|
||||
break;
|
||||
default:
|
||||
mfem_error("This orientation does not exist in 3D");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2://EAST
|
||||
switch (face_orient)
|
||||
{
|
||||
case 0://{0, 1, 2, 3}
|
||||
k1 = kf1;
|
||||
k2 = kf2;
|
||||
break;
|
||||
case 1://{0, 3, 2, 1}
|
||||
k1 = kf2;
|
||||
k2 = kf1;
|
||||
break;
|
||||
case 2://{1, 2, 3, 0}
|
||||
k1 = kf2;
|
||||
k2 = face_dof1D_cnt-1-kf1;
|
||||
break;
|
||||
case 3://{1, 0, 3, 2}
|
||||
k1 = face_dof1D_cnt-1-kf1;
|
||||
k2 = kf2;
|
||||
break;
|
||||
case 4://{2, 3, 0, 1}
|
||||
k1 = face_dof1D_cnt-1-kf1;
|
||||
k2 = face_dof1D_cnt-1-kf2;
|
||||
break;
|
||||
case 5://{2, 1, 0, 3}
|
||||
k1 = face_dof1D_cnt-1-kf2;
|
||||
k2 = face_dof1D_cnt-1-kf1;
|
||||
break;
|
||||
case 6://{3, 0, 1, 2}
|
||||
k1 = face_dof1D_cnt-1-kf2;
|
||||
k2 = kf1;
|
||||
break;
|
||||
case 7://{3, 2, 1, 0}
|
||||
k1 = kf1;
|
||||
k2 = face_dof1D_cnt-1-kf2;
|
||||
break;
|
||||
default:
|
||||
mfem_error("This orientation does not exist in 3D");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 3://NORTH
|
||||
switch (face_orient)
|
||||
{
|
||||
case 0://{0, 1, 2, 3}
|
||||
k1 = face_dof1D_cnt-1-kf1;
|
||||
k2 = kf2;
|
||||
break;
|
||||
case 1://{0, 3, 2, 1}
|
||||
k1 = kf2;
|
||||
k2 = face_dof1D_cnt-1-kf1;
|
||||
break;
|
||||
case 2://{1, 2, 3, 0}
|
||||
k1 = kf2;
|
||||
k2 = kf1;
|
||||
break;
|
||||
case 3://{1, 0, 3, 2}
|
||||
k1 = kf1;
|
||||
k2 = kf2;
|
||||
break;
|
||||
case 4://{2, 3, 0, 1}
|
||||
k1 = kf1;
|
||||
k2 = face_dof1D_cnt-1-kf2;
|
||||
break;
|
||||
case 5://{2, 1, 0, 3}
|
||||
k1 = face_dof1D_cnt-1-kf2;
|
||||
k2 = kf1;
|
||||
break;
|
||||
case 6://{3, 0, 1, 2}
|
||||
k1 = face_dof1D_cnt-1-kf2;
|
||||
k2 = face_dof1D_cnt-1-kf1;
|
||||
break;
|
||||
case 7://{3, 2, 1, 0}
|
||||
k1 = face_dof1D_cnt-1-kf1;
|
||||
k2 = face_dof1D_cnt-1-kf2;
|
||||
break;
|
||||
default:
|
||||
mfem_error("This orientation does not exist in 3D");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 4://WEST
|
||||
switch (face_orient)
|
||||
{
|
||||
case 0://{0, 1, 2, 3}
|
||||
k1 = face_dof1D_cnt-1-kf1;
|
||||
k2 = kf2;
|
||||
break;
|
||||
case 1://{0, 3, 2, 1}
|
||||
k1 = kf2;
|
||||
k2 = face_dof1D_cnt-1-kf1;
|
||||
break;
|
||||
case 2://{1, 2, 3, 0}
|
||||
k1 = kf2;
|
||||
k2 = kf1;
|
||||
break;
|
||||
case 3://{1, 0, 3, 2}
|
||||
k1 = kf1;
|
||||
k2 = kf2;
|
||||
break;
|
||||
case 4://{2, 3, 0, 1}
|
||||
k1 = kf1;
|
||||
k2 = face_dof1D_cnt-1-kf2;
|
||||
break;
|
||||
case 5://{2, 1, 0, 3}
|
||||
k1 = face_dof1D_cnt-1-kf2;
|
||||
k2 = kf1;
|
||||
break;
|
||||
case 6://{3, 0, 1, 2}
|
||||
k1 = face_dof1D_cnt-1-kf2;
|
||||
k2 = face_dof1D_cnt-1-kf1;
|
||||
break;
|
||||
case 7://{3, 2, 1, 0}
|
||||
k1 = face_dof1D_cnt-1-kf1;
|
||||
k2 = face_dof1D_cnt-1-kf2;
|
||||
break;
|
||||
default:
|
||||
mfem_error("This orientation does not exist in 3D");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 5://TOP
|
||||
switch (face_orient)
|
||||
{
|
||||
case 0://{0, 1, 2, 3}
|
||||
k1 = kf1;
|
||||
k2 = kf2;
|
||||
break;
|
||||
case 1://{0, 3, 2, 1}
|
||||
k1 = kf2;
|
||||
k2 = kf1;
|
||||
break;
|
||||
case 2://{1, 2, 3, 0}
|
||||
k1 = kf2;
|
||||
k2 = face_dof1D_cnt-1-kf1;
|
||||
break;
|
||||
case 3://{1, 0, 3, 2}
|
||||
k1 = face_dof1D_cnt-1-kf1;
|
||||
k2 = kf2;
|
||||
break;
|
||||
case 4://{2, 3, 0, 1}
|
||||
k1 = face_dof1D_cnt-1-kf1;
|
||||
k2 = face_dof1D_cnt-1-kf2;
|
||||
break;
|
||||
case 5://{2, 1, 0, 3}
|
||||
k1 = face_dof1D_cnt-1-kf2;
|
||||
k2 = face_dof1D_cnt-1-kf1;
|
||||
break;
|
||||
case 6://{3, 0, 1, 2}
|
||||
k1 = face_dof1D_cnt-1-kf2;
|
||||
k2 = kf1;
|
||||
break;
|
||||
case 7://{3, 2, 1, 0}
|
||||
k1 = kf1;
|
||||
k2 = face_dof1D_cnt-1-kf2;
|
||||
break;
|
||||
default:
|
||||
mfem_error("This orientation does not exist in 3D");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default: MFEM_ABORT("This face_id does not exist in 3D");
|
||||
}
|
||||
return k1 + face_dof1D_cnt * k2;
|
||||
}
|
||||
|
||||
int DofInfo::GetLocalFaceDofIndex(int dim, int loc_face_id, int face_orient,
|
||||
int face_dof_id, int face_dof1D_cnt)
|
||||
{
|
||||
switch (dim)
|
||||
{
|
||||
case 1: return face_dof_id;
|
||||
case 2:
|
||||
if (loc_face_id <= 1)
|
||||
{
|
||||
// SOUTH or EAST (canonical ordering)
|
||||
return face_dof_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
// NORTH or WEST (counter-canonical ordering)
|
||||
return face_dof1D_cnt - 1 - face_dof_id;
|
||||
}
|
||||
case 3: return GetLocalFaceDofIndex3D(loc_face_id, face_orient,
|
||||
face_dof_id, face_dof1D_cnt);
|
||||
default: MFEM_ABORT("Dimension too high!"); return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void DofInfo::FillSubcellCross()
|
||||
{
|
||||
const FiniteElement &el = *fes->GetFE(0);
|
||||
Geometry::Type gtype = el.GetGeomType();
|
||||
|
||||
switch (gtype)
|
||||
{
|
||||
case Geometry::SEGMENT:
|
||||
{
|
||||
SubcellCross.SetSize(2,1);
|
||||
SubcellCross(0,0) = 1;
|
||||
SubcellCross(1,0) = 0;
|
||||
break;
|
||||
}
|
||||
case Geometry::TRIANGLE:
|
||||
{
|
||||
SubcellCross.SetSize(3,2);
|
||||
SubcellCross(0,0) = 1;
|
||||
SubcellCross(0,1) = 2;
|
||||
SubcellCross(1,0) = 0;
|
||||
SubcellCross(1,1) = 2;
|
||||
SubcellCross(2,0) = 0;
|
||||
SubcellCross(2,1) = 1;
|
||||
break;
|
||||
}
|
||||
case Geometry::SQUARE:
|
||||
{
|
||||
SubcellCross.SetSize(4,2);
|
||||
SubcellCross(0,0) = 1;
|
||||
SubcellCross(0,1) = 2;
|
||||
SubcellCross(1,0) = 0;
|
||||
SubcellCross(1,1) = 3;
|
||||
SubcellCross(2,0) = 0;
|
||||
SubcellCross(2,1) = 3;
|
||||
SubcellCross(3,0) = 1;
|
||||
SubcellCross(3,1) = 2;
|
||||
break;
|
||||
}
|
||||
case Geometry::CUBE:
|
||||
{
|
||||
SubcellCross.SetSize(8,3);
|
||||
SubcellCross(0,0) = 1;
|
||||
SubcellCross(0,1) = 2;
|
||||
SubcellCross(0,2) = 4;
|
||||
SubcellCross(1,0) = 0;
|
||||
SubcellCross(1,1) = 3;
|
||||
SubcellCross(1,2) = 5;
|
||||
SubcellCross(2,0) = 0;
|
||||
SubcellCross(2,1) = 3;
|
||||
SubcellCross(2,2) = 6;
|
||||
SubcellCross(3,0) = 1;
|
||||
SubcellCross(3,1) = 2;
|
||||
SubcellCross(3,2) = 7;
|
||||
SubcellCross(4,0) = 0;
|
||||
SubcellCross(4,1) = 5;
|
||||
SubcellCross(4,2) = 6;
|
||||
SubcellCross(5,0) = 1;
|
||||
SubcellCross(5,1) = 4;
|
||||
SubcellCross(5,2) = 7;
|
||||
SubcellCross(6,0) = 2;
|
||||
SubcellCross(6,1) = 4;
|
||||
SubcellCross(6,2) = 7;
|
||||
SubcellCross(7,0) = 3;
|
||||
SubcellCross(7,1) = 5;
|
||||
SubcellCross(7,2) = 6;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MFEM_ABORT("Other gemoetries are not supported.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#ifndef HYPSYS_DOFS
|
||||
#define HYPSYS_DOFS
|
||||
|
||||
#include "mfem.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
// NOTE: The mesh is assumed to consist of segments, triangles quads or hexes.
|
||||
class DofInfo
|
||||
{
|
||||
public:
|
||||
Mesh *mesh;
|
||||
FiniteElementSpace *fes;
|
||||
|
||||
DenseMatrix BdrDofs, Sub2Ind, SubcellCross, Loc2Multiindex;
|
||||
DenseTensor NbrDofs; // Negative values correspond to the boundary attributes.
|
||||
|
||||
int dim, NumBdrs, NumFaceDofs, numSubcells, numDofsSubcell;
|
||||
Array<int> DofMapH1;
|
||||
|
||||
DofInfo(FiniteElementSpace *fes_);
|
||||
|
||||
virtual ~DofInfo() { }
|
||||
|
||||
// NOTE: This approach will not work for meshes with hanging h- or p-nodes.
|
||||
void FillNeighborDofs();
|
||||
|
||||
void FillBdrDofs();
|
||||
void FillSubcell2CellDof();
|
||||
void FillSubcellCross();
|
||||
|
||||
// The following two routines work only for TRIANGLES.
|
||||
void FillLoc2Multiindex();
|
||||
int GetLocFromMultiindex(int p, const Vector &a) const;
|
||||
|
||||
// Auxiliary routines.
|
||||
int GetLocalFaceDofIndex3D(int loc_face_id, int face_orient,
|
||||
int face_dof_id, int face_dof1D_cnt);
|
||||
|
||||
int GetLocalFaceDofIndex(int dim, int loc_face_id, int face_orient,
|
||||
int face_dof_id, int face_dof1D_cnt);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef HYPSYS_LIB_LIB
|
||||
#define HYPSYS_LIB_LIB
|
||||
|
||||
#include "massmat.hpp"
|
||||
#include "dofs.hpp"
|
||||
#include "bounds.hpp"
|
||||
#include "tools.hpp"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,65 @@
|
||||
#include "massmat.hpp"
|
||||
|
||||
MassMatrixDG::MassMatrixDG(const FiniteElementSpace *fes_) : fes(fes_)
|
||||
{
|
||||
const int nd = fes->GetFE(0)->GetDof();
|
||||
M.SetSize(nd, nd, fes->GetNE());
|
||||
MassIntegrator mi;
|
||||
for (int e = 0; e < fes->GetNE(); e++)
|
||||
{
|
||||
mi.AssembleElementMatrix(*fes->GetFE(e),
|
||||
*fes->GetElementTransformation(e),
|
||||
M(e));
|
||||
}
|
||||
}
|
||||
|
||||
void MassMatrixDG::Mult(const Vector &x, Vector &y) const
|
||||
{
|
||||
Array<int> vdofs;
|
||||
const int nd = fes->GetFE(0)->GetDof();
|
||||
DenseMatrix xel, yel;
|
||||
for (int e = 0; e < fes->GetNE(); e++)
|
||||
{
|
||||
fes->GetElementVDofs(e, vdofs);
|
||||
int nc = vdofs.Size()/nd;
|
||||
xel.SetSize(nd, nc);
|
||||
yel.SetSize(nd, nc);
|
||||
x.GetSubVector(vdofs, xel.Data());
|
||||
mfem::Mult(M(e), xel, yel);
|
||||
y.SetSubVector(vdofs, yel.Data());
|
||||
}
|
||||
}
|
||||
|
||||
InverseMassMatrixDG::InverseMassMatrixDG(const MassMatrixDG *mass_)
|
||||
: mass(mass_),
|
||||
fes(mass->fes)
|
||||
{
|
||||
const int nd = fes->GetFE(0)->GetDof();
|
||||
Minv.SetSize(nd, nd, fes->GetNE());
|
||||
|
||||
DenseMatrix Me(nd);
|
||||
DenseMatrixInverse MeInv(&Me);
|
||||
for (int e = 0; e < fes->GetNE(); e++)
|
||||
{
|
||||
Me = mass->M(e);
|
||||
MeInv.Factor();
|
||||
MeInv.GetInverseMatrix(Minv(e));
|
||||
}
|
||||
}
|
||||
|
||||
void InverseMassMatrixDG::Mult(const Vector &x, Vector &y) const
|
||||
{
|
||||
Array<int> vdofs;
|
||||
const int nd = fes->GetFE(0)->GetDof();
|
||||
DenseMatrix xel, yel;
|
||||
for (int e = 0; e < fes->GetNE(); e++)
|
||||
{
|
||||
fes->GetElementVDofs(e, vdofs);
|
||||
int nc = vdofs.Size()/nd;
|
||||
xel.SetSize(nd, nc);
|
||||
yel.SetSize(nd, nc);
|
||||
x.GetSubVector(vdofs, xel.Data());
|
||||
mfem::Mult(Minv(e), xel, yel);
|
||||
y.SetSubVector(vdofs, yel.Data());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef HYPSYS_MASSMAT
|
||||
#define HYPSYS_MASSMAT
|
||||
|
||||
#include "mfem.hpp"
|
||||
|
||||
using namespace mfem;
|
||||
|
||||
class MassMatrixDG : public Operator
|
||||
{
|
||||
friend class InverseMassMatrixDG;
|
||||
|
||||
const FiniteElementSpace *fes;
|
||||
|
||||
public:
|
||||
DenseTensor M;
|
||||
|
||||
MassMatrixDG(const FiniteElementSpace *fes_);
|
||||
~MassMatrixDG() {};
|
||||
void Mult(const Vector &x, Vector &y) const;
|
||||
};
|
||||
|
||||
class InverseMassMatrixDG : public Operator
|
||||
{
|
||||
const MassMatrixDG *mass;
|
||||
const FiniteElementSpace *fes;
|
||||
|
||||
public:
|
||||
DenseTensor Minv;
|
||||
|
||||
InverseMassMatrixDG(const MassMatrixDG *mass_);
|
||||
~InverseMassMatrixDG() { };
|
||||
virtual void Mult(const Vector &x, Vector &y) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,133 @@
|
||||
#include "pbounds.hpp"
|
||||
|
||||
ParBounds::ParBounds(ParFiniteElementSpace *pfes_,
|
||||
ParFiniteElementSpace *pfesH1_)
|
||||
: Bounds(pfes_, pfesH1_), pfes(pfes_), pfesH1(pfesH1_), px_min(pfesH1_),
|
||||
px_max(pfesH1_) { /* mom_min.SetSize(2*ne*nd); mom_max.SetSize(2*ne*nd); */ }
|
||||
|
||||
void ParBounds::ComputeBounds(const Vector &x)
|
||||
{
|
||||
GroupCommunicator &gcomm = pfesH1->GroupComm();
|
||||
|
||||
px_min = std::numeric_limits<double>::infinity();
|
||||
px_max = -std::numeric_limits<double>::infinity();
|
||||
|
||||
for (int e = 0; e < ne; e++)
|
||||
{
|
||||
pfesH1->GetElementDofs(e, eldofs);
|
||||
ComputeElementBounds(0, e, x);
|
||||
}
|
||||
|
||||
Array<double> minvals(px_min.GetData(), px_min.Size()),
|
||||
maxvals(px_max.GetData(), px_max.Size());
|
||||
|
||||
gcomm.Reduce<double>(minvals, GroupCommunicator::Min);
|
||||
gcomm.Bcast(minvals);
|
||||
gcomm.Reduce<double>(maxvals, GroupCommunicator::Max);
|
||||
gcomm.Bcast(maxvals);
|
||||
|
||||
for (int e = 0; e < ne; e++)
|
||||
{
|
||||
pfesH1->GetElementDofs(e, eldofs);
|
||||
for (int j = 0; j < nd; j++)
|
||||
{
|
||||
xi_min(e*nd + j) = px_min(eldofs[DofMapH1[j]]);
|
||||
xi_max(e*nd + j) = px_max(eldofs[DofMapH1[j]]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int n = 1; n < NumEq; n++)
|
||||
{
|
||||
px_min = std::numeric_limits<double>::infinity();
|
||||
px_max = -std::numeric_limits<double>::infinity();
|
||||
|
||||
for (int e = 0; e < ne; e++)
|
||||
{
|
||||
pfesH1->GetElementDofs(e, eldofs);
|
||||
ComputeSequentialBounds(n, e, x);
|
||||
}
|
||||
|
||||
Array<double> minvals2(px_min.GetData(), px_min.Size()),
|
||||
maxvals2(px_max.GetData(), px_max.Size());
|
||||
|
||||
gcomm.Reduce<double>(minvals2, GroupCommunicator::Min);
|
||||
gcomm.Bcast(minvals2);
|
||||
gcomm.Reduce<double>(maxvals2, GroupCommunicator::Max);
|
||||
gcomm.Bcast(maxvals2);
|
||||
|
||||
for (int e = 0; e < ne; e++)
|
||||
{
|
||||
pfesH1->GetElementDofs(e, eldofs);
|
||||
for (int j = 0; j < nd; j++)
|
||||
{
|
||||
xi_min(n*ne*nd + e*nd + j) = px_min(eldofs[DofMapH1[j]]);
|
||||
xi_max(n*ne*nd + e*nd + j) = px_max(eldofs[DofMapH1[j]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ParTightBounds::ParTightBounds(ParFiniteElementSpace *pfes_,
|
||||
ParFiniteElementSpace *pfesH1_)
|
||||
: ParBounds(pfes_, pfesH1_)
|
||||
{
|
||||
FillClosestNbrs(pfes->GetFE(0), ClosestNbrs);
|
||||
}
|
||||
|
||||
void ParTightBounds::ComputeElementBounds(int n, int e, const Vector &x)
|
||||
{
|
||||
for (int i = 0; i < nd; i++)
|
||||
{
|
||||
const int I = eldofs[DofMapH1[i]];
|
||||
px_min(I) = min(px_min(I), xi_min(n*ne*nd + e*nd + i));
|
||||
px_max(I) = max(px_max(I), xi_max(n*ne*nd + e*nd + i));
|
||||
|
||||
for (int j = 0; j < ClosestNbrs.Width(); j++)
|
||||
{
|
||||
if (ClosestNbrs(i,j) == -1) { break; }
|
||||
|
||||
const int J = n*ne*nd + e*nd + ClosestNbrs(i,j);
|
||||
px_min(I) = min(px_min(I), x(J));
|
||||
px_max(I) = max(px_max(I), x(J));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ParTightBounds::ComputeSequentialBounds(int n, int e, const Vector &x)
|
||||
{
|
||||
for (int i = 0; i < nd; i++)
|
||||
{
|
||||
const int I = eldofs[DofMapH1[i]];
|
||||
px_min(I) = min(px_min(I), xi_min(n*ne*nd + e*nd + i));
|
||||
px_max(I) = max(px_max(I), xi_max(n*ne*nd + e*nd + i));
|
||||
}
|
||||
}
|
||||
|
||||
ParLooseBounds::ParLooseBounds(ParFiniteElementSpace *pfes_,
|
||||
ParFiniteElementSpace *pfesH1_)
|
||||
: ParBounds(pfes_, pfesH1_) { }
|
||||
|
||||
void ParLooseBounds::ComputeElementBounds(int n, int e, const Vector &x)
|
||||
{
|
||||
double xe_min = std::numeric_limits<double>::infinity();
|
||||
double xe_max = -std::numeric_limits<double>::infinity();
|
||||
|
||||
for (int j = 0; j < nd; j++)
|
||||
{
|
||||
xe_min = min(xe_min, x(n*ne*nd + e*nd+j));
|
||||
xe_max = max(xe_max, x(n*ne*nd + e*nd+j));
|
||||
}
|
||||
|
||||
for (int j = 0; j < nd; j++)
|
||||
{
|
||||
int I = eldofs[DofMapH1[j]];
|
||||
px_min(I) = min(px_min(I), xe_min);
|
||||
px_max(I) = max(px_max(I), xe_max);
|
||||
}
|
||||
}
|
||||
|
||||
void ParLooseBounds::ComputeSequentialBounds(int n, int e, const Vector &x)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#ifndef HYPSYS_PBOUNDS
|
||||
#define HYPSYS_PBOUNDS
|
||||
|
||||
#include "bounds.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
class ParBounds : public Bounds
|
||||
{
|
||||
public:
|
||||
ParFiniteElementSpace *pfes, *pfesH1;
|
||||
ParGridFunction px_min, px_max; // min max values for each H1 dof.
|
||||
// Vector mom_min, mom_max;
|
||||
|
||||
ParBounds(ParFiniteElementSpace *pfes_, ParFiniteElementSpace *pfesH1_);
|
||||
|
||||
virtual ~ParBounds() { }
|
||||
|
||||
virtual void ComputeBounds(const Vector &x) override;
|
||||
};
|
||||
|
||||
class ParTightBounds : public ParBounds
|
||||
{
|
||||
public:
|
||||
DenseMatrix ClosestNbrs;
|
||||
|
||||
ParTightBounds(ParFiniteElementSpace *pfes_, ParFiniteElementSpace *pfesH1_);
|
||||
~ParTightBounds() { }
|
||||
|
||||
virtual void ComputeElementBounds(int n, int e, const Vector &x) override;
|
||||
virtual void ComputeSequentialBounds(int n, int e, const Vector &x) override;
|
||||
};
|
||||
|
||||
class ParLooseBounds : public ParBounds
|
||||
{
|
||||
public:
|
||||
ParLooseBounds(ParFiniteElementSpace *pfes_, ParFiniteElementSpace *pfesH1_);
|
||||
~ParLooseBounds() { }
|
||||
|
||||
virtual void ComputeElementBounds(int n, int e, const Vector &x) override;
|
||||
virtual void ComputeSequentialBounds(int n, int e, const Vector &x) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,189 @@
|
||||
#include "pdofs.hpp"
|
||||
|
||||
ParDofInfo::ParDofInfo(ParFiniteElementSpace *pfes_)
|
||||
: DofInfo(pfes_), pmesh(pfes_->GetParMesh()), pfes(pfes_)
|
||||
{
|
||||
FillNeighborDofs();
|
||||
}
|
||||
|
||||
void ParDofInfo::FillNeighborDofs()
|
||||
{
|
||||
// Use the first mesh element as indicator.
|
||||
const FiniteElement &el = *pfes->GetFE(0);
|
||||
int i, j, e, nbr, ne = pmesh->GetNE();
|
||||
int nd = el.GetDof(), p = el.GetOrder();
|
||||
Array <int> bdrs, orientation;
|
||||
FaceElementTransformations *Trans;
|
||||
|
||||
pmesh->ExchangeFaceNbrData();
|
||||
Table *face_to_el = pmesh->GetFaceToAllElementTable();
|
||||
|
||||
NbrDofs.SetSize(NumBdrs, NumFaceDofs, ne);
|
||||
|
||||
// Permutations of BdrDofs, taking into account all possible orientations.
|
||||
// Assumes BdrDofs are ordered in xyz order, which is true for 3D hexes,
|
||||
// but it isn't true for 2D quads.
|
||||
int orient_cnt = 1;
|
||||
if (dim == 2) { orient_cnt = 2; }
|
||||
if (dim == 3) { orient_cnt = 8; }
|
||||
const int dof1D_cnt = p+1;
|
||||
DenseTensor fdof_ids(NumFaceDofs, NumBdrs, orient_cnt);
|
||||
for (int ori = 0; ori < orient_cnt; ori++)
|
||||
{
|
||||
for (int face_id = 0; face_id < NumBdrs; face_id++)
|
||||
{
|
||||
for (int fdof_id = 0; fdof_id < NumFaceDofs; fdof_id++)
|
||||
{
|
||||
// Index of fdof_id in the current orientation.
|
||||
const int ori_fdof_id = GetLocalFaceDofIndex(dim, face_id, ori,
|
||||
fdof_id, dof1D_cnt);
|
||||
fdof_ids(ori)(ori_fdof_id, face_id) = BdrDofs(fdof_id, face_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (e = 0; e < ne; e++)
|
||||
{
|
||||
if (dim==1)
|
||||
{
|
||||
pmesh->GetElementVertices(e, bdrs);
|
||||
|
||||
for (i = 0; i < NumBdrs; i++)
|
||||
{
|
||||
const int nbr_cnt = face_to_el->RowSize(bdrs[i]);
|
||||
if (nbr_cnt == 1)
|
||||
{
|
||||
// No neighbor element.
|
||||
NbrDofs(i,0,e) = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
int el1_id, el2_id, nbr_id;
|
||||
pmesh->GetFaceElements(bdrs[i], &el1_id, &el2_id);
|
||||
if (el2_id < 0)
|
||||
{
|
||||
// This element is in a different mpi task.
|
||||
el2_id = -1 - el2_id + ne;
|
||||
}
|
||||
nbr_id = (el1_id == e) ? el2_id : el1_id;
|
||||
NbrDofs(i,0,e) = nbr_id*nd + BdrDofs(0,(i+1)%2);
|
||||
}
|
||||
}
|
||||
else if (dim==2)
|
||||
{
|
||||
pmesh->GetElementEdges(e, bdrs, orientation);
|
||||
|
||||
for (i = 0; i < NumBdrs; i++)
|
||||
{
|
||||
const int nbr_cnt = face_to_el->RowSize(bdrs[i]);
|
||||
if (nbr_cnt == 1)
|
||||
{
|
||||
// No neighbor element.
|
||||
for (j = 0; j < NumFaceDofs; j++) { NbrDofs(i,j,e) = -1; }
|
||||
continue;
|
||||
}
|
||||
|
||||
int el1_id, el2_id, nbr_id;
|
||||
pmesh->GetFaceElements(bdrs[i], &el1_id, &el2_id);
|
||||
if (el2_id < 0)
|
||||
{
|
||||
// This element is in a different mpi task.
|
||||
el2_id = -1 - el2_id + ne;
|
||||
}
|
||||
nbr_id = (el1_id == e) ? el2_id : el1_id;
|
||||
|
||||
int el1_info, el2_info;
|
||||
pmesh->GetFaceInfos(bdrs[i], &el1_info, &el2_info);
|
||||
const int face_id_nbr = (nbr_id == el1_id) ? el1_info / 64
|
||||
: el2_info / 64;
|
||||
for (j = 0; j < NumFaceDofs; j++)
|
||||
{
|
||||
// Here it is utilized that the orientations of the face for
|
||||
// the two elements are opposite of each other.
|
||||
NbrDofs(i,j,e) = nbr_id*nd + BdrDofs(NumFaceDofs - 1 - j,
|
||||
face_id_nbr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (dim==3)
|
||||
{
|
||||
pmesh->GetElementFaces(e, bdrs, orientation);
|
||||
|
||||
for (int f = 0; f < NumBdrs; f++)
|
||||
{
|
||||
const int nbr_cnt = face_to_el->RowSize(bdrs[f]);
|
||||
if (nbr_cnt == 1)
|
||||
{
|
||||
// No neighbor element.
|
||||
for (j = 0; j < NumFaceDofs; j++) { NbrDofs(f,j,e) = -1; }
|
||||
continue;
|
||||
}
|
||||
|
||||
int el1_id, el2_id, nbr_id;
|
||||
pmesh->GetFaceElements(bdrs[f], &el1_id, &el2_id);
|
||||
if (el2_id < 0)
|
||||
{
|
||||
// This element is in a different mpi task.
|
||||
el2_id = -1 - el2_id + ne;
|
||||
}
|
||||
nbr_id = (el1_id == e) ? el2_id : el1_id;
|
||||
|
||||
// Local index and orientation of the face, when considered in
|
||||
// the neighbor element.
|
||||
int el1_info, el2_info;
|
||||
pmesh->GetFaceInfos(bdrs[f], &el1_info, &el2_info);
|
||||
const int face_id_nbr = (nbr_id == el1_id) ? el1_info / 64
|
||||
: el2_info / 64;
|
||||
const int face_or_nbr = (nbr_id == el1_id) ? el1_info % 64
|
||||
: el2_info % 64;
|
||||
for (j = 0; j < NumFaceDofs; j++)
|
||||
{
|
||||
// What is the index of the j-th dof on the face, given its
|
||||
// orientation.
|
||||
const int loc_face_dof_id =
|
||||
GetLocalFaceDofIndex(dim, face_id_nbr, face_or_nbr,
|
||||
j, dof1D_cnt);
|
||||
// What is the corresponding local dof id on the element,
|
||||
// given the face orientation.
|
||||
const int nbr_dof_id =
|
||||
fdof_ids(face_or_nbr)(loc_face_dof_id, face_id_nbr);
|
||||
|
||||
NbrDofs(f,j,e) = nbr_id*nd + nbr_dof_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (e = 0; e < pfes->GetNBE(); e++)
|
||||
{
|
||||
const int bdr_attr = mesh->GetBdrAttribute(e);
|
||||
FaceElementTransformations *tr = mesh->GetBdrFaceTransformations(e);
|
||||
|
||||
if (tr != NULL)
|
||||
{
|
||||
const int el = tr->Elem1No;
|
||||
|
||||
if (dim == 1) { mesh->GetElementVertices(el, bdrs); }
|
||||
else if (dim == 2) { mesh->GetElementEdges(el, bdrs, orientation); }
|
||||
else if (dim == 3) { mesh->GetElementFaces(el, bdrs, orientation); }
|
||||
|
||||
for (i = 0; i < NumBdrs; i++)
|
||||
{
|
||||
if (bdrs[i] == mesh->GetBdrElementEdgeIndex(e))
|
||||
{
|
||||
for (j = 0; j < NumFaceDofs; j++)
|
||||
{
|
||||
NbrDofs(i, j, el) = -bdr_attr;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MFEM_ABORT("Something went wrong.");
|
||||
}
|
||||
}
|
||||
|
||||
delete face_to_el;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef HYPSYS_PDOFS
|
||||
#define HYPSYS_PDOFS
|
||||
|
||||
#include "dofs.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
class ParDofInfo : public DofInfo
|
||||
{
|
||||
public:
|
||||
ParMesh *pmesh;
|
||||
ParFiniteElementSpace *pfes;
|
||||
|
||||
ParDofInfo(ParFiniteElementSpace *pfes_);
|
||||
|
||||
~ParDofInfo() { }
|
||||
|
||||
// NOTE: This approach will not work for meshes with hanging h- or p-nodes.
|
||||
void FillNeighborDofs();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef HYPSYS_LIB_PLIB
|
||||
#define HYPSYS_LIB_PLIB
|
||||
|
||||
#include "pbounds.hpp"
|
||||
#include "pdofs.hpp"
|
||||
#include "ptools.hpp"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "ptools.hpp"
|
||||
|
||||
void ParVisualizeField(socketstream &sock, const char *vishost, int visport,
|
||||
string ProblemName, ParGridFunction &gf, string glvis_scale, bool vec)
|
||||
{
|
||||
ParMesh &pmesh = *gf.ParFESpace()->GetParMesh();
|
||||
MPI_Comm comm = pmesh.GetComm();
|
||||
|
||||
int myid;
|
||||
MPI_Comm_rank(comm, &myid);
|
||||
|
||||
bool newly_opened = false;
|
||||
|
||||
if (myid == 0)
|
||||
{
|
||||
if (!sock.is_open() && sock)
|
||||
{
|
||||
sock.open(vishost, visport);
|
||||
sock.precision(8);
|
||||
newly_opened = true;
|
||||
}
|
||||
sock << "solution\n";
|
||||
}
|
||||
|
||||
pmesh.PrintAsOne(sock);
|
||||
gf.SaveAsOne(sock);
|
||||
|
||||
if (myid == 0 && newly_opened)
|
||||
{
|
||||
sock << "window_title '" << ProblemName << "'\n"
|
||||
<< "window_geometry "
|
||||
<< 0 << " " << 0 << " " << 1080 << " " << 1080 << "\n"
|
||||
<< "autoscale " << glvis_scale << "\n"
|
||||
<< "keys mcjlppppppppppppppppppppppppppp66666666666666666666666"
|
||||
<< "66666666666666666666666666666666666666666666666662222222222";
|
||||
if ( vec ) { sock << "vvv"; }
|
||||
sock << endl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef HYPSYS_PTOOLS
|
||||
#define HYPSYS_PTOOLS
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include "mfem.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
void ParVisualizeField(socketstream &sock, const char *vishost, int visport,
|
||||
string ProblemName, ParGridFunction &gf, string glvis_scale, bool vec = false);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef HYPSYS_LIB_TEMPLATE
|
||||
#define HYPSYS_LIB_TEMPLATE
|
||||
|
||||
#include "mfem.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
class TEMPLATE
|
||||
{
|
||||
public:
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,77 @@
|
||||
#include "tools.hpp"
|
||||
|
||||
const IntegrationRule* GetElementIntegrationRule(FiniteElementSpace *fes,
|
||||
bool NodalQuadRule)
|
||||
{
|
||||
const FiniteElement *el = fes->GetFE(0);
|
||||
if (NodalQuadRule)
|
||||
{
|
||||
return &(el->GetNodes());
|
||||
}
|
||||
ElementTransformation *eltrans = fes->GetElementTransformation(0);
|
||||
int order = eltrans->OrderGrad(el) + eltrans->Order() + el->GetOrder();
|
||||
|
||||
return &IntRules.Get(el->GetGeomType(), order);
|
||||
}
|
||||
|
||||
const IntegrationRule *GetFaceIntegrationRule(FiniteElementSpace *fes,
|
||||
bool NodalQuadRule)
|
||||
{
|
||||
int i, order;
|
||||
// Use the first mesh face and element as indicator.
|
||||
const FaceElementTransformations *Trans =
|
||||
fes->GetMesh()->GetFaceElementTransformations(0);
|
||||
|
||||
if (NodalQuadRule)
|
||||
{
|
||||
return &IntRules.Get(Trans->FaceGeom, 1);
|
||||
}
|
||||
|
||||
const FiniteElement *el = fes->GetFE(0);
|
||||
|
||||
if (Trans->Elem2No >= 0)
|
||||
{
|
||||
order = min(Trans->Elem1->OrderW(), Trans->Elem2->OrderW())
|
||||
+ 2*el->GetOrder();
|
||||
}
|
||||
else
|
||||
{
|
||||
order = Trans->Elem1->OrderW() + 2*el->GetOrder();
|
||||
}
|
||||
if (el->Space() == FunctionSpace::Pk)
|
||||
{
|
||||
order++;
|
||||
}
|
||||
|
||||
return &IntRules.Get(Trans->FaceGeom, order);
|
||||
}
|
||||
|
||||
void VisualizeField(socketstream &sock, const char *vishost, int visport,
|
||||
string ProblemName, GridFunction &gf, string glvis_scale, bool vec)
|
||||
{
|
||||
Mesh &mesh = *gf.FESpace()->GetMesh();
|
||||
|
||||
bool newly_opened = false;
|
||||
|
||||
if (!sock.is_open() && sock)
|
||||
{
|
||||
sock.open(vishost, visport);
|
||||
sock.precision(8);
|
||||
newly_opened = true;
|
||||
}
|
||||
sock << "solution\n";
|
||||
mesh.Print(sock);
|
||||
gf.Save(sock);
|
||||
|
||||
if (newly_opened)
|
||||
{
|
||||
sock << "window_title '" << ProblemName << "'\n"
|
||||
<< "window_geometry "
|
||||
<< 0 << " " << 0 << " " << 1080 << " " << 1080 << "\n"
|
||||
<< "autoscale " << glvis_scale << "\n"
|
||||
<< "keys mcjlppppppppppppppppppppppppppp66666666666666666666666"
|
||||
<< "66666666666666666666666666666666666666666666666662222222222";
|
||||
if ( vec ) { sock << "vvv"; }
|
||||
sock << endl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef HYPSYS_TOOLS
|
||||
#define HYPSYS_TOOLS
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include "mfem.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
const IntegrationRule* GetElementIntegrationRule(FiniteElementSpace *fes,
|
||||
bool NodalQuadRule = false);
|
||||
|
||||
// Appropriate quadrature rule for faces according to DGTraceIntegrator.
|
||||
const IntegrationRule *GetFaceIntegrationRule(FiniteElementSpace *fes,
|
||||
bool NodalQuadRule = false);
|
||||
|
||||
void VisualizeField(socketstream &sock, const char *vishost, int visport,
|
||||
string ProblemName, GridFunction &gf, string glvis_scale, bool vec = false);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,109 @@
|
||||
# Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at the
|
||||
# Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights reserved.
|
||||
# See file COPYRIGHT for details.
|
||||
#
|
||||
# This file is part of the MFEM library. For more information and source code
|
||||
# availability see http://mfem.org.
|
||||
#
|
||||
# MFEM is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Lesser General Public License (as published by the Free
|
||||
# Software Foundation) version 2.1 dated February 1999.
|
||||
|
||||
# Use the MFEM build directory
|
||||
MFEM_DIR ?= ../..
|
||||
CONFIG_MK = $(MFEM_DIR)/config/config.mk
|
||||
|
||||
MFEM_LIB_FILE = mfem_is_not_built
|
||||
-include $(CONFIG_MK)
|
||||
|
||||
# Code directories in logical order
|
||||
APP_DIR = apps
|
||||
BLD_DIR = build
|
||||
EVL_DIR = fe_evol
|
||||
LIB_DIR = lib
|
||||
OUT_DIR = output
|
||||
|
||||
DIRS = $(APP_DIR) $(EVL_DIR) $(LIB_DIR)
|
||||
|
||||
LIB_FILES = $(BLD_DIR)/massmat.o $(BLD_DIR)/dofs.o $(BLD_DIR)/tools.o $(BLD_DIR)/bounds.o
|
||||
EVL_FILES = $(BLD_DIR)/fe_evol.evl $(BLD_DIR)/galerkin.evl $(BLD_DIR)/monolithic_convex_limiting.evl
|
||||
APP_FILES = $(BLD_DIR)/advection.app $(BLD_DIR)/burgers.app $(BLD_DIR)/kpp.app $(BLD_DIR)/buckley_leverett.app # scalar problems
|
||||
APP_FILES+= $(BLD_DIR)/shallowwater.app $(BLD_DIR)/euler.app # hyperbolic systems
|
||||
|
||||
MAIN_FILES = hypsys
|
||||
|
||||
ifeq ($(MFEM_USE_MPI), YES)
|
||||
MAIN_FILES += phypsys
|
||||
PLIB_FILES += $(BLD_DIR)/pdofs.o
|
||||
PLIB_FILES += $(BLD_DIR)/ptools.o
|
||||
PLIB_FILES += $(BLD_DIR)/pbounds.o
|
||||
PEVL_FILES += $(BLD_DIR)/pgalerkin.evl
|
||||
PEVL_FILES += $(BLD_DIR)/pmonolithic_convex_limiting.evl
|
||||
endif
|
||||
|
||||
# valgrind-test setup
|
||||
PROBLEM = 0
|
||||
VALGRIND-CONFIG = -tf 0.001 -dt 0.001 -p $(PROBLEM) -e 0
|
||||
|
||||
## Makefile rules. #############################################################
|
||||
|
||||
# Keywords that are not associated with files (by default, all are).
|
||||
.PHONY: all library hypsys phypsys clean valgrind-test grid-convergence-test sytle
|
||||
|
||||
# Delete the default suffixes.
|
||||
.SUFFIXES:
|
||||
|
||||
# Define suffixes.
|
||||
.SUFFIXES: .c .cpp
|
||||
|
||||
# Replace the default implicit rule for *.cpp files
|
||||
%: %.cpp $(CONFIG_MK)
|
||||
$(MFEM_CXX) $(MFEM_FLAGS) $< -o $@ $(LIB_FILES) $(APP_FILES) $(MFEM_LIBS)
|
||||
|
||||
%.o: ../$(LIB_DIR)/%.cpp
|
||||
$(MFEM_CXX) $(MFEM_FLAGS) -c $^ -o $@
|
||||
|
||||
%.evl: ../$(EVL_DIR)/%.cpp
|
||||
$(MFEM_CXX) $(MFEM_FLAGS) -c $^ -o $@
|
||||
|
||||
%.app: ../$(APP_DIR)/%.cpp
|
||||
$(MFEM_CXX) $(MFEM_FLAGS) -c $^ -o $@
|
||||
|
||||
all: $(MAIN_FILES)
|
||||
|
||||
library: $(LIB_FILES) $(PLIB_FILES) $(EVL_FILES) $(PEVL_FILES) $(APP_FILES)
|
||||
|
||||
hypsys: library
|
||||
$(MFEM_CXX) $(MFEM_FLAGS) hypsys.cpp -o $@ $(LIB_FILES) $(EVL_FILES) $(APP_FILES) $(MFEM_LIBS)
|
||||
|
||||
phypsys: library
|
||||
$(MFEM_CXX) $(MFEM_FLAGS) phypsys.cpp -o $@ $(LIB_FILES) $(PLIB_FILES) $(EVL_FILES) $(PEVL_FILES) $(APP_FILES) $(MFEM_LIBS)
|
||||
|
||||
clean:
|
||||
@rm -f hypsys phypsys errors.txt *gf* grid* $(OUT_DIR)/* $(BLD_DIR)/*
|
||||
|
||||
valgrind-serial:
|
||||
valgrind ./hypsys $(VALGRIND-CONFIG) -c 1 -m data/inline-4segment.mesh -r 4 -o 1
|
||||
valgrind ./hypsys $(VALGRIND-CONFIG) -c 0 -m data/periodic-square.mesh -r 2 -o 2 -s 1
|
||||
valgrind ./hypsys $(VALGRIND-CONFIG) -c 0 -m data/beam-quad.mesh -r 1 -o 3
|
||||
valgrind ./hypsys $(VALGRIND-CONFIG) -c 1 -m data/wall-bdr-4hex.mesh -r 0 -o 2
|
||||
|
||||
# TODO does not work yet
|
||||
valgrind-parallel:
|
||||
# mpirun -np 2 valgrind --leak-check=yes ./par-hypsys -tf 0.1 -r 0
|
||||
# valgrind --gen-suppressions=yes phypsys $(VALGRIND-CONFIG)
|
||||
# valgrind --suppressions=$(MPI_HOME)/share/openmpi/openmpi-valgrind.supp phypsys $(VALGRIND-CONFIG)
|
||||
valgrind --suppressions=./my-mpi-suppressions.supp phypsys $(VALGRIND-CONFIG)
|
||||
|
||||
$(MFEM_LIB_FILE):
|
||||
$(error The MFEM library is not built)
|
||||
|
||||
ASTYLE = ~/astyle --options=$(MFEM_DIR)/config/mfem.astylerc
|
||||
FORMAT_FILES = $(foreach dir,$(DIRS),"$(dir)/*.?pp")
|
||||
FORMAT_FILES += hypsys.cpp
|
||||
FORMAT_FILES += phypsys.cpp
|
||||
|
||||
style:
|
||||
@if ! $(ASTYLE) $(FORMAT_FILES) | grep Formatted; then\
|
||||
echo "No source files were changed.";\
|
||||
fi
|
||||
@@ -0,0 +1,61 @@
|
||||
ATTENTION
|
||||
|
||||
|
||||
DEBUG
|
||||
|
||||
|
||||
ROADMAP
|
||||
-euler w-c benchmark shows problem with mcl low order method
|
||||
-Change quadrature rules - read up on it/use int rules as in different operators in mfem. Hexes seem off as well.
|
||||
|
||||
|
||||
CLEANUP
|
||||
-lib: check quadrature orders - other than that *tools* *lib.hpp is done
|
||||
TODO: (p-) bounds, dofs, massmat
|
||||
-fe_evol
|
||||
|
||||
TODO
|
||||
Minor Tasks
|
||||
Check if it is actually possible to make Gresho vortex converge to steady state (with galerkin first)
|
||||
Check apps/bl.cpp for correctness
|
||||
|
||||
High Priority:
|
||||
Discrepancy to results in paper :( - already in 1D low order method, Woodward-Colella breaks
|
||||
Cleanup
|
||||
Efficiency
|
||||
|
||||
Medium Priority:
|
||||
Advection - NodalQuadRule
|
||||
|
||||
Low Priority:
|
||||
Test GMS for Euler, remove if unnecessary
|
||||
Try to run MCL on curved geometries
|
||||
Vector output as arrows
|
||||
|
||||
Desirable:
|
||||
-Euler: Implement subsonic in- and outflow.
|
||||
-Sedov setup
|
||||
-Theoretically, double-mach requires a subsonic outlet at the short edge before wall boundaries
|
||||
-Noh problem: zero verlocity part of bdr: wall, rest: supersonic outflow (east, north)
|
||||
and supersonic inflow (south, east), i.e. bdr type changes in time
|
||||
-Expression for momentum in narrowing channel
|
||||
-If possible: Try to distinguish boundary types by considering eigenvalues of systems
|
||||
|
||||
|
||||
next steps
|
||||
-Pressure fix: Required for Woodward-Colella, double-mach, Sedov, Noh
|
||||
|
||||
If possible: try to make advection with non-constant velocity and MCL work
|
||||
|
||||
minor tasks:
|
||||
-C++ type cleanup, e.g for DofInfo classes
|
||||
-Maybe move stuff thats not needed within main routines (e.g. dofs) into fe_evol.cpp
|
||||
-If difficult, move bound computation to MCL Evolution.
|
||||
-Use mfem::Mult for matrix multiplication
|
||||
-Since MCL works only for elements with constant Jacobians, maybe use Vector of size ne
|
||||
-Restructure galerkin, fe_evol and mcl (constructors)
|
||||
|
||||
|
||||
future tasks
|
||||
-Entropy fixes
|
||||
-Smoothness indicator
|
||||
@@ -0,0 +1,344 @@
|
||||
#include "lib/lib.hpp"
|
||||
#include "fe_evol/plib.hpp"
|
||||
#include "apps/lib.hpp"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
MPI_Session mpi(argc, argv);
|
||||
const int myid = mpi.WorldRank();
|
||||
|
||||
Configuration config;
|
||||
int ProblemNum = 0;
|
||||
config.ConfigNum = 1;
|
||||
int VisSteps = 100;
|
||||
config.tFinal = 1.;
|
||||
int odeSolverType = 3;
|
||||
double dt = 0.001;
|
||||
const char *MeshFile = "data/inline-4quad.mesh";
|
||||
int order = 3;
|
||||
int refinements = 1;
|
||||
int prefinements = 0;
|
||||
EvolutionScheme scheme = MonolithicConvexLimiting;
|
||||
const char *OutputDir = "output"; // Directory has to exist to produce output.
|
||||
bool TransOutput = false; // Use this to produce output for videos.
|
||||
bool VisualizeDerived = false;
|
||||
|
||||
int precision = 8;
|
||||
cout.precision(precision);
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&ProblemNum, "-p", "--problem",
|
||||
"Hyperbolic system of equations to solve.");
|
||||
args.AddOption(&config.ConfigNum, "-c", "--configuration",
|
||||
"Problem setup to use.");
|
||||
args.AddOption(&VisSteps, "-vf", "--visualization-frequency",
|
||||
"Visualize every n-th timestep.");
|
||||
args.AddOption(&config.tFinal, "-tf", "--final-time",
|
||||
"Final time; start time is 0.");
|
||||
args.AddOption(&odeSolverType, "-s", "--ode-solver",
|
||||
"ODE solver: 1 - Forward Euler,\n\t"
|
||||
" 2 - RK2 SSP, 3 - RK3 SSP, 4 - RK4, 6 - RK6.");
|
||||
args.AddOption(&dt, "-dt", "--time-step", "Time step.");
|
||||
args.AddOption(&MeshFile, "-m", "--mesh", "Mesh file to use.");
|
||||
args.AddOption(&order, "-o", "--order",
|
||||
"Order (polynomial degree) of the finite element space.");
|
||||
args.AddOption(&refinements, "-r", "--serial-refinements",
|
||||
"Number of times to refine the mesh uniformly in serial.");
|
||||
args.AddOption(&prefinements, "-pr", "--parallel-refinements",
|
||||
"Number of times to refine the mesh uniformly in parallel.");
|
||||
args.AddOption((int*)(&scheme), "-es", "--evolution-scheme",
|
||||
"Scheme: 0 - Galerkin Finite Element Approximation,\n\t"
|
||||
" 1 - Monolithic Convex Limiting.");
|
||||
args.AddOption(&OutputDir, "-out", "--output-directory", "Output directory.");
|
||||
args.AddOption(&TransOutput, "-t", "--transitional-output", "-no-t",
|
||||
"--no-transitional-output", "Print transitional output files.");
|
||||
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
if (myid == 0) { args.PrintUsage(cout); }
|
||||
return -1;
|
||||
}
|
||||
if (myid == 0) { args.PrintOptions(cout); }
|
||||
|
||||
if (order == 0)
|
||||
{
|
||||
scheme = Galerkin;
|
||||
}
|
||||
|
||||
ODESolver *odeSolver = NULL;
|
||||
switch (odeSolverType)
|
||||
{
|
||||
case 1: odeSolver = new ForwardEulerSolver; break;
|
||||
case 2: odeSolver = new RK2Solver(1.0); break;
|
||||
case 3: odeSolver = new RK3SSPSolver; break;
|
||||
case 4: odeSolver = new RK4Solver; break;
|
||||
case 6: odeSolver = new RK6Solver; break;
|
||||
default:
|
||||
cout << "Unknown ODE solver type: " << odeSolverType << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (myid == 0 && odeSolverType > 3)
|
||||
{
|
||||
MFEM_WARNING("Non-SSP odeSolver: Maximum principles may be violated.");
|
||||
}
|
||||
|
||||
// Read the serial mesh from the given mesh file on all processors.
|
||||
Mesh *mesh = new Mesh(MeshFile, 1, 1);
|
||||
const int dim = mesh->Dimension();
|
||||
for (int lev = 0; lev < refinements; lev++)
|
||||
{
|
||||
mesh->UniformRefinement();
|
||||
}
|
||||
mesh->GetBoundingBox(config.bbMin, config.bbMax, max(order, 1));
|
||||
|
||||
// Parallel partitioning of the mesh.
|
||||
ParMesh pmesh(MPI_COMM_WORLD, *mesh);
|
||||
delete mesh;
|
||||
for (int lev = 0; lev < prefinements; lev++)
|
||||
{
|
||||
pmesh.UniformRefinement();
|
||||
}
|
||||
|
||||
if (pmesh.NURBSext)
|
||||
{
|
||||
pmesh.SetCurvature(max(order, 1));
|
||||
}
|
||||
MPI_Comm comm = pmesh.GetComm();
|
||||
|
||||
int NumEq;
|
||||
switch (ProblemNum)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3: {NumEq = 1; VisualizeDerived = false; break; }
|
||||
case 4: NumEq = 1 + dim; break;
|
||||
case 5: NumEq = 2 + dim; break;
|
||||
default:
|
||||
cout << "Unknown hyperbolic system: " << ProblemNum << endl;
|
||||
delete odeSolver;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create Bernstein Finite Element Space.
|
||||
const int btype = BasisType::Positive;
|
||||
L2_FECollection fec(order, dim, btype);
|
||||
ParFiniteElementSpace pfes(&pmesh, &fec);
|
||||
ParFiniteElementSpace vfes(&pmesh, &fec, NumEq, Ordering::byNODES);
|
||||
|
||||
Array<int> offsets(NumEq + 1);
|
||||
for (int k = 0; k <= NumEq; k++) { offsets[k] = k * pfes.GetNDofs(); }
|
||||
BlockVector u_block(offsets);
|
||||
|
||||
const int ProblemSize = vfes.GlobalVSize();
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "Number of unknowns: " << ProblemSize << endl;
|
||||
}
|
||||
|
||||
ParDofInfo pdofs(&pfes);
|
||||
|
||||
bool NodalQuadRule = false;
|
||||
if (scheme == MonolithicConvexLimiting)
|
||||
{
|
||||
NodalQuadRule = true;
|
||||
}
|
||||
|
||||
HyperbolicSystem *hyp;
|
||||
switch (ProblemNum)
|
||||
{
|
||||
case 0: { hyp = new Advection(&vfes, u_block, config, NodalQuadRule); break; }
|
||||
case 1: { hyp = new Burgers(&vfes, u_block, config); break; }
|
||||
case 2: { hyp = new KPP(&vfes, u_block, config); break; }
|
||||
case 3: { hyp = new BuckleyLeverett(&vfes, u_block, config); break; }
|
||||
case 4: { hyp = new ShallowWater(&vfes, u_block, config); break; }
|
||||
case 5: { hyp = new Euler(&vfes, u_block, config); break; }
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (odeSolverType != 1 && hyp->SteadyState && myid == 0)
|
||||
{
|
||||
MFEM_WARNING("Better use forward Euler pseudo time stepping for steady state simulations.");
|
||||
}
|
||||
|
||||
ParGridFunction u(&vfes, u_block);
|
||||
u = hyp->u0;
|
||||
|
||||
// The main is variable is visualized, printed, and used to check for mass leaks or violation of maximum principles.
|
||||
ParGridFunction main(&pfes, u_block.GetBlock(0));
|
||||
|
||||
ostringstream MeshName, InitName;
|
||||
MeshName << OutputDir << "/grid-mesh." << setfill('0') << setw(6) << myid;
|
||||
InitName << OutputDir << "/initial-gf." << setfill('0') << setw(6) << myid;
|
||||
ofstream omesh(MeshName.str().c_str());
|
||||
omesh.precision(precision);
|
||||
pmesh.Print(omesh);
|
||||
ofstream initial(InitName.str().c_str());
|
||||
initial.precision(precision);
|
||||
main.Save(initial);
|
||||
|
||||
socketstream sout;
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
{
|
||||
// Make sure all MPI ranks have sent their 'v' solution before initiating
|
||||
// another set of GLVis connections (one from each rank):
|
||||
MPI_Barrier(comm);
|
||||
ParVisualizeField(sout, vishost, visport, hyp->ProblemName, main,
|
||||
hyp->glvis_scale);
|
||||
}
|
||||
|
||||
FE_Evolution *evol;
|
||||
switch (scheme)
|
||||
{
|
||||
case Galerkin: { evol = new ParGalerkinEvolution(&vfes, hyp, pdofs); break; }
|
||||
case MonolithicConvexLimiting: { evol = new ParMCL_Evolution(&vfes, hyp, pdofs, dt); break; }
|
||||
default:
|
||||
MFEM_ABORT("Unknown evolution scheme");
|
||||
}
|
||||
|
||||
Vector LumpedMassMat(pfes.GetVSize());
|
||||
ParBilinearForm ml(&pfes);
|
||||
ml.AddDomainIntegrator(new LumpedIntegrator(new MassIntegrator()));
|
||||
ml.Assemble();
|
||||
ml.Finalize();
|
||||
ml.SpMat().GetDiag(LumpedMassMat);
|
||||
|
||||
double InitialMass, MassMPI = LumpedMassMat * main;
|
||||
MPI_Allreduce(&MassMPI, &InitialMass, 1, MPI_DOUBLE, MPI_SUM, comm);
|
||||
|
||||
odeSolver->Init(*evol);
|
||||
if (hyp->SteadyState)
|
||||
{
|
||||
evol->uOld.SetSize(ProblemSize);
|
||||
evol->uOld = 0.;
|
||||
}
|
||||
|
||||
int TransStep = 1;
|
||||
double dtLast, res, t = 0., tol = 1.e-12;
|
||||
bool done = t >= config.tFinal;
|
||||
tic_toc.Clear();
|
||||
tic_toc.Start();
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "Preprocessing done. Entering time stepping loop.\n";
|
||||
}
|
||||
|
||||
for (int ti = 0; !done;)
|
||||
{
|
||||
dtLast = min(dt, config.tFinal - t);
|
||||
odeSolver->Step(u, t, dtLast);
|
||||
ti++;
|
||||
|
||||
done = (t >= config.tFinal - 1.e-8 * dt);
|
||||
|
||||
if (hyp->SteadyState)
|
||||
{
|
||||
res = evol->ConvergenceCheck(dt, u);
|
||||
if (res < tol)
|
||||
{
|
||||
done = true;
|
||||
u = evol->uOld;
|
||||
}
|
||||
}
|
||||
|
||||
if (done || ti % VisSteps == 0)
|
||||
{
|
||||
if (myid == 0)
|
||||
{
|
||||
if (hyp->SteadyState)
|
||||
{
|
||||
cout << "time step: " << ti << ", time: " << t << ", residual: " << res << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "time step: " << ti << ", time: " << t << endl;
|
||||
}
|
||||
}
|
||||
|
||||
ParVisualizeField(sout, vishost, visport, hyp->ProblemName, main,
|
||||
hyp->glvis_scale);
|
||||
if (TransOutput)
|
||||
{
|
||||
ostringstream TransName;
|
||||
TransName << OutputDir << "/trans-gf-" << TransStep << "."
|
||||
<< setfill('0') << setw(6) << myid;
|
||||
ofstream trans(TransName.str().c_str());
|
||||
trans.precision(precision);
|
||||
main.Save(trans);
|
||||
TransStep++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tic_toc.Stop();
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "Time stepping loop done in " << tic_toc.RealTime() << " seconds.\n\n";
|
||||
}
|
||||
|
||||
double FinalMass, DomainSize, DomainSizeMPI = LumpedMassMat.Sum();
|
||||
MPI_Allreduce(&DomainSizeMPI, &DomainSize, 1, MPI_DOUBLE, MPI_SUM, comm);
|
||||
|
||||
if (hyp->SolutionKnown)
|
||||
{
|
||||
Array<double> errors;
|
||||
hyp->ComputeErrors(errors, u, DomainSize, t);
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "L1 error: " << errors[0] << endl;
|
||||
hyp->WriteErrors(errors);
|
||||
}
|
||||
}
|
||||
|
||||
double mainMin, mainMax, mainLoc = main.Min();
|
||||
MPI_Allreduce(&mainLoc, &mainMin, 1, MPI_DOUBLE, MPI_MIN, comm);
|
||||
mainLoc = main.Max();
|
||||
MPI_Allreduce(&mainLoc, &mainMax, 1, MPI_DOUBLE, MPI_MAX, comm);
|
||||
|
||||
MassMPI = LumpedMassMat * main;
|
||||
MPI_Allreduce(&MassMPI, &FinalMass, 1, MPI_DOUBLE, MPI_SUM, comm);
|
||||
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "Min of primary field: " << mainMin << endl
|
||||
<< "Max of primary field: " << mainMax << endl
|
||||
<< "Difference in solution mass: "
|
||||
<< abs(InitialMass - FinalMass) / DomainSize << "\n\n";
|
||||
}
|
||||
|
||||
ostringstream FinalName;
|
||||
FinalName << OutputDir << "/ultimate-gf." << setfill('0') << setw(6) << myid;
|
||||
ofstream ultimate(FinalName.str().c_str());
|
||||
ultimate.precision(precision);
|
||||
main.Save(ultimate);
|
||||
|
||||
if (VisualizeDerived)
|
||||
{
|
||||
ParGridFunction v(&pfes), p(&pfes);
|
||||
hyp->ComputeDerivedQuantities(u, v, p);
|
||||
|
||||
ostringstream VelocityName;
|
||||
VelocityName << OutputDir << "/velocity-gf." << setfill('0') << setw(6) << myid;
|
||||
ofstream velocity(VelocityName.str().c_str());
|
||||
velocity.precision(precision);
|
||||
v.Save(velocity);
|
||||
|
||||
if (ProblemNum == 5)
|
||||
{
|
||||
ostringstream PressureName;
|
||||
PressureName << OutputDir << "/pressure-gf." << setfill('0') << setw(6) << myid;
|
||||
ofstream pressure(PressureName.str().c_str());
|
||||
pressure.precision(precision);
|
||||
p.Save(pressure);
|
||||
}
|
||||
}
|
||||
|
||||
delete evol;
|
||||
delete hyp;
|
||||
delete odeSolver;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
# Plot specifications for my benchmarks
|
||||
|
||||
# Advection - Solid Body Rotation: side view
|
||||
# keys lmj6666666666666666666666666666666666666666666666666666666666666666666666662222222222
|
||||
valuerange 0 1
|
||||
# TODO TRIM
|
||||
|
||||
|
||||
# Burgers Equation - Riemann Problem
|
||||
glvis -fn -20
|
||||
keys lRjmc*******
|
||||
valuerange -1 0.8
|
||||
TRIM=1116x1018+576+20
|
||||
|
||||
|
||||
# KPP Equation - 2D Spiral: top view
|
||||
keys laammjR*************
|
||||
valuerange 0.7854 11
|
||||
# TODO TRIM
|
||||
|
||||
# KPP Equation - 2D Spiral: side view
|
||||
keys RRRR44444444444444444444444444444422222222222222222222************** # 5 times Ctrl + UP
|
||||
valuerange 0.7854 11
|
||||
# TODO TRIM
|
||||
|
||||
|
||||
# Shallow Water Equations - Constricted Channel
|
||||
# run in serial to plot boundary
|
||||
keys lRjmmb*************************
|
||||
valuerange 1 1.85
|
||||
TRIM=1886x838+17+121
|
||||
# TODO choice of isolines
|
||||
|
||||
|
||||
# Shallow Water Equations - Radial Dam Break
|
||||
keys mjRRRR222222222222222222222222jmblttt**************** # 4 times Ctrl + UP
|
||||
valuerange 0.1 1
|
||||
TRIM=1096x881+412+191
|
||||
# TODO choice of isolines
|
||||
|
||||
|
||||
# Euler Equations of Gas dynamics - Double Mach Reflection
|
||||
keys aajlmmR***************************
|
||||
valuerange 1.375 23
|
||||
TRIM=1886x472+17+304
|
||||
ISOLINES: 1.375 23 24
|
||||
|
||||
# Euler Equations of Gas dynamics - Double Mach Reflection: Zoom
|
||||
keys jlmmR******************************************************** # 50 times Ctrl + RIGHT, 22 time Ctrl + UP
|
||||
valuerange 1.375 23
|
||||
TRIM=1353x1057+0+0
|
||||
ISOLINES: 4 14 24
|
||||
@@ -0,0 +1,49 @@
|
||||
function cmpRiemannSolvers()
|
||||
|
||||
ul = 0;
|
||||
ur = 1;
|
||||
n = 1/sqrt(2)*[1 1];
|
||||
problem = 1;
|
||||
|
||||
fl = flux(ul, n, problem);
|
||||
fr = flux(ur, n, problem);
|
||||
|
||||
sl = wavespeed(ul, n, problem);
|
||||
sr = wavespeed(ur, n, problem);
|
||||
|
||||
LF = 0.5 * (dot(fl + fr, n) + max(abs(sl),abs(sr)) * (ul - ur))
|
||||
|
||||
if 0 < sl
|
||||
HLL = dot(fl, n);
|
||||
elseif 0 > sr
|
||||
HLL = dot(fr, n);
|
||||
else
|
||||
HLL = (dot(sr*fl - sl*fr, n) + sl*sr*(ur-ul)) / (sr-sl);
|
||||
end
|
||||
|
||||
HLL
|
||||
end
|
||||
|
||||
function f = flux(u, n, problem)
|
||||
|
||||
switch problem
|
||||
case 0
|
||||
f = velocity * u;
|
||||
case 1
|
||||
f = u*u/2 * [1; 1];
|
||||
end
|
||||
end
|
||||
|
||||
function s = wavespeed(u, n, problem)
|
||||
|
||||
switch problem
|
||||
case 0
|
||||
s = dot(velocity, n);
|
||||
case 1
|
||||
s = u * sum(n);
|
||||
end
|
||||
end
|
||||
|
||||
function v = velocity()
|
||||
v=[1; -0.5];
|
||||
end
|
||||
@@ -0,0 +1,69 @@
|
||||
function createTable()
|
||||
|
||||
q = 1; % q=1: L1, q=2: L2, q=3 LInf errors
|
||||
domainSize = 2;
|
||||
|
||||
numElPerDim = [48 64 96 128 192 256 384]' / domainSize;
|
||||
numLvls = length(numElPerDim);
|
||||
maxOrd = 4;
|
||||
data = zeros(numLvls, maxOrd);
|
||||
eoc = zeros(numLvls-1, 3);
|
||||
|
||||
for j = 1:maxOrd
|
||||
file = fopen([num2str(j) '.txt'], 'r');
|
||||
for i = 1:numLvls+1-j
|
||||
aux = str2num(fgets(file));
|
||||
data(i,j) = aux(q);
|
||||
end
|
||||
fclose(file);
|
||||
end
|
||||
|
||||
tab = [];
|
||||
for i=1:maxOrd
|
||||
eoc(:,i) = log(data(2:end,i) ./ data(1:end-1,i)) ./ log(numElPerDim(1:end-1) ./ numElPerDim(2:end));
|
||||
tab = [tab data(2:end,i), eoc(:,i)];
|
||||
end
|
||||
|
||||
% tab
|
||||
% return
|
||||
|
||||
file = fopen('table.txt','wt');
|
||||
fprintf(file, '\\begin{table}[ht!]\n\\centering\n\\begin{tabular}{||c||c|c||c|c||c|c||c|c||}\n\\hline\n$1/h$ & $p=1$ & EOC & $p=2$ & EOC & $p=3$ & EOC & $p=4$ & EOC\\\\\n\\hline\n');
|
||||
fprintf(file, '%d & %1.2E & & %1.2E & & %1.2E & & %1.2E & \\\\\n', numElPerDim(1), data(1,:));
|
||||
for i = 2 : numLvls
|
||||
switch i
|
||||
case {2,3,4}
|
||||
if numElPerDim(i) < 100
|
||||
fprintf(file, '%d & %1.2E & %1.2f & %1.2E & %1.2f & %1.2E & %1.2f & %1.2E & %1.2f \\\\\n', numElPerDim(i), tab(i-1,:));
|
||||
else
|
||||
fprintf(file, '%d & %1.2E & %1.2f & %1.2E & %1.2f & %1.2E & %1.2f & %1.2E & %1.2f \\\\\n', numElPerDim(i), tab(i-1,:));
|
||||
end
|
||||
case 5
|
||||
if numElPerDim(i) < 100
|
||||
fprintf(file, '%d & %1.2E & %1.2f & %1.2E & %1.2f & %1.2E & %1.2f &&\\\\\n', numElPerDim(i), tab(i-1,1:end-2));
|
||||
else
|
||||
fprintf(file, '%d & %1.2E & %1.2f & %1.2E & %1.2f & %1.2E & %1.2f &&\\\\\n', numElPerDim(i), tab(i-1,1:end-2));
|
||||
end
|
||||
case 6
|
||||
if numElPerDim(i) < 100
|
||||
fprintf(file, '%d & %1.2E & %1.2f & %1.2E & %1.2f &&&&\\\\\n', numElPerDim(i), tab(i-1,1:end-4));
|
||||
else
|
||||
fprintf(file, '%d & %1.2E & %1.2f & %1.2E & %1.2f &&&&\\\\\n', numElPerDim(i), tab(i-1,1:end-4));
|
||||
end
|
||||
case 7
|
||||
if numElPerDim(i) < 100
|
||||
fprintf(file, '%d & %1.2E & %1.2f &&&&&&\\\\\n', numElPerDim(i), tab(i-1,1:end-6));
|
||||
else
|
||||
fprintf(file, '%d & %1.2E & %1.2f &&&&&&\\\\\n', numElPerDim(i), tab(i-1,1:end-6));
|
||||
end
|
||||
otherwise
|
||||
error('Change of configuration requires modification of output formatting.');
|
||||
end
|
||||
end
|
||||
e = num2str(q);
|
||||
if q==3
|
||||
e = '\\infty';
|
||||
end
|
||||
fprintf(file, ['\\hline\n\\end{tabular}\n\\caption{The $\\|\\cdot\\|_{L^' e '(\\Omega)}$~errors and corresponding EOC of ...$\\mathbb Q_p$, $p \\in \\{1,\\hdots,4\\}$ solutions to the 1D ... equation with initial condition ...}\\label{tab:}\n\\end{table}']);
|
||||
fclose(file);
|
||||
end
|
||||
@@ -0,0 +1,89 @@
|
||||
// This file is part of BLAST - a high-order finite element hydrocode
|
||||
//
|
||||
// MFEM has to be compiled in serial, then compile this with
|
||||
//
|
||||
// g++ -O3 -std=c++11 -I<MFEM_DIR> gridfunc-scatter.cpp -o gridfunc-scatter -L<MFEM_DIR> -lmfem -lrt
|
||||
//
|
||||
// where <MFEM_DIR> has to be replaced with the absolute path of the mfem directory.
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "mfem.hpp"
|
||||
using namespace mfem;
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 3)
|
||||
{
|
||||
cout << "usage: " << argv[0]
|
||||
<< " in_mesh_file in_gf_file" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Mesh *mesh;
|
||||
|
||||
{
|
||||
ifstream imesh (argv[1]);
|
||||
if (!imesh)
|
||||
{
|
||||
cout << "can not open mesh file: " << argv[1] << endl;
|
||||
return 2;
|
||||
}
|
||||
mesh = new Mesh (imesh, 1, 1);
|
||||
}
|
||||
|
||||
int dim = mesh -> Dimension();
|
||||
cout << "mesh dimension: " << dim << endl;
|
||||
|
||||
|
||||
//////////////////////////////////
|
||||
ofstream scatter_file("scatter.dat");
|
||||
int sd = 4;
|
||||
RefinedGeometry *RefG;
|
||||
Vector values;
|
||||
DenseMatrix pointmat, vec_values;
|
||||
const IntegrationRule *ir;
|
||||
int points_percell=sd;
|
||||
|
||||
cout << "Enter subdivision factor : " << flush;
|
||||
cin >> sd;
|
||||
cout << "Enter subdivisions per cell : " << flush;
|
||||
cin >> points_percell;
|
||||
points_percell--;
|
||||
|
||||
scatter_file.precision(8);
|
||||
for (int lev = 0; lev < sd; lev++)
|
||||
mesh->UniformRefinement();
|
||||
|
||||
GridFunction *gf;
|
||||
{
|
||||
ifstream igf(argv[2]);
|
||||
gf = new GridFunction(mesh, igf);
|
||||
}
|
||||
|
||||
for (int i = 0; i < mesh->GetNE(); i++)
|
||||
{
|
||||
RefG = GlobGeometryRefiner.Refine(mesh->GetElementBaseGeometry(i), points_percell, 1);
|
||||
ir = &(RefG->RefPts);
|
||||
// GET VALUES
|
||||
gf->GetValues(i, *ir, values, pointmat);
|
||||
|
||||
for (int j = 0; j < pointmat.Width(); j++) //num of points per element
|
||||
{
|
||||
scatter_file << pointmat(0, j) << ' ';
|
||||
//cout << pointmat(0,j) << ' ';
|
||||
scatter_file << values(j) << '\n';
|
||||
//cout << values(j) << endl;
|
||||
}
|
||||
//abort();
|
||||
}
|
||||
scatter_file.close();
|
||||
//////////////////////////////////
|
||||
|
||||
delete gf;
|
||||
delete mesh;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
# -*- text -*-
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
###############################################################
|
||||
#
|
||||
# OPAL suppressions
|
||||
#
|
||||
###############################################################
|
||||
|
||||
# weirdness in init routines on Gentoo
|
||||
{
|
||||
linux_pthread_init
|
||||
Memcheck:Leak
|
||||
fun:calloc
|
||||
fun:allocate_dtv
|
||||
fun:_dl_allocate_tls_storage
|
||||
fun:_dl_allocate_tls
|
||||
}
|
||||
{
|
||||
linux_pthread_init2
|
||||
Memcheck:Leak
|
||||
fun:calloc
|
||||
fun:_dl_tls_setup
|
||||
fun:__pthread_initialize_minimal
|
||||
}
|
||||
{
|
||||
linux_pthread_init3
|
||||
Memcheck:Leak
|
||||
fun:memalign
|
||||
fun:_dl_allocate_tls_storage
|
||||
fun:_dl_allocate_tls
|
||||
fun:__pthread_initialize_minimal
|
||||
}
|
||||
|
||||
# The event library leaves some blocks in use that we should clean up,
|
||||
# but it would require much changing of the event library, so it
|
||||
# really isn't worth it...
|
||||
{
|
||||
event_lib_poll
|
||||
Memcheck:Leak
|
||||
fun:malloc
|
||||
fun:realloc
|
||||
fun:opal_realloc
|
||||
fun:poll_dispatch
|
||||
}
|
||||
|
||||
|
||||
###############################################################
|
||||
#
|
||||
# ORTE suppressions
|
||||
#
|
||||
###############################################################
|
||||
|
||||
# inet_ntoa on linux mallocs a static buffer. We can't free
|
||||
# it, so we have to live with it
|
||||
{
|
||||
linux_inet_ntoa
|
||||
Memcheck:Leak
|
||||
fun:malloc
|
||||
fun:inet_ntoa
|
||||
}
|
||||
{
|
||||
linux_inet_ntoa_thread
|
||||
Memcheck:Leak
|
||||
fun:calloc
|
||||
fun:pthread_setspecific
|
||||
fun:inet_ntoa
|
||||
}
|
||||
|
||||
|
||||
###############################################################
|
||||
#
|
||||
# OMPI suppressions
|
||||
#
|
||||
###############################################################
|
||||
{
|
||||
tcp_send
|
||||
Memcheck:Param
|
||||
writev(vector[...])
|
||||
fun:writev
|
||||
fun:mca_btl_tcp_frag_send
|
||||
fun:mca_btl_tcp_endpoint_send
|
||||
}
|
||||
|
||||
###############################################################
|
||||
#
|
||||
# Suppressions for various commonly-used packages
|
||||
#
|
||||
###############################################################
|
||||
|
||||
# Portals reference implementation has a read from invalid issue
|
||||
{
|
||||
portals_send
|
||||
Memcheck:Param
|
||||
socketcall.send(msg)
|
||||
fun:send
|
||||
fun:utcp_sendbytes
|
||||
fun:utcp_sendto
|
||||
fun:utcp_msg_wait
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import numpy as np
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
# exact
|
||||
x=np.linspace(0,1,1000)
|
||||
y=(x>=0.4)*(x<=0.6)
|
||||
plt.plot(x,y,'--k',lw=1)
|
||||
|
||||
# # Order 0
|
||||
# data = np.genfromtxt("scatter0.dat")
|
||||
# index = np.argsort(data[:,0])
|
||||
# plt.plot(data[index,0],data[index,1],'-m',lw=2)
|
||||
|
||||
# Order 1
|
||||
data = np.genfromtxt("scatter1.dat")
|
||||
index = np.argsort(data[:,0])
|
||||
plt.plot(data[index,0],data[index,1],'-k',lw=2)
|
||||
|
||||
# Order 3
|
||||
data = np.genfromtxt("scatter2.dat")
|
||||
index = np.argsort(data[:,0])
|
||||
plt.plot(data[index,0],data[index,1],'-b',lw=2)
|
||||
|
||||
# Order 7
|
||||
data = np.genfromtxt("scatter3.dat")
|
||||
index = np.argsort(data[:,0])
|
||||
plt.plot(data[index,0],data[index,1],'-c',lw=2)
|
||||
|
||||
# Order 15
|
||||
data = np.genfromtxt("scatter4.dat")
|
||||
index = np.argsort(data[:,0])
|
||||
plt.plot(data[index,0],data[index,1],'-g',lw=2)
|
||||
|
||||
# Order 31
|
||||
data = np.genfromtxt("scatter5.dat")
|
||||
index = np.argsort(data[:,0])
|
||||
plt.plot(data[index,0],data[index,1],'-r',lw=2)
|
||||
|
||||
plt.ylim([-0.01,1.01])
|
||||
plt.axis('off')
|
||||
plt.legend(['p=1','p=3','p=7','p=15','p=31'])
|
||||
plt.savefig('img.png')
|
||||
@@ -0,0 +1,37 @@
|
||||
function printEOC(data)
|
||||
|
||||
if nargin == 0
|
||||
filename = '../errors.txt';
|
||||
file = fopen(filename, 'r');
|
||||
data = zeros(0,3);
|
||||
while true
|
||||
aux = fgets(file);
|
||||
if aux == -1
|
||||
break;
|
||||
end
|
||||
data(end+1,:) = str2num(aux);
|
||||
end
|
||||
fclose(file);
|
||||
end
|
||||
|
||||
numElPerDim = [48 64 96 128 192 256 384 512]';
|
||||
% numElPerDim = [4 8 16 32 64 128 256]';
|
||||
numElPerDim = numElPerDim(1:size(data,1));
|
||||
numLvls = length(numElPerDim)-1;
|
||||
eoc = zeros(numLvls, 3);
|
||||
for i=1:3
|
||||
eoc(:,i) = log(data(2:end,i) ./ data(1:end-1,i)) ./ log(numElPerDim(1:end-1) ./ numElPerDim(2:end));
|
||||
end
|
||||
|
||||
tab = [data(2:end,1), eoc(:,1), data(2:end,2), eoc(:,2), data(2:end,3), eoc(:,3)];
|
||||
|
||||
fprintf('\n1/%d & %1.2E & & %1.2E & & %1.2E & \\\\\n', numElPerDim(1), data(1,:));
|
||||
for i = 2:length(numElPerDim)
|
||||
if numElPerDim(i) < 100
|
||||
fprintf('1/%d & %1.2E & %1.2f & %1.2E & %1.2f & %1.2E & %1.2f \\\\\n', numElPerDim(i), tab(i-1,:));
|
||||
else
|
||||
fprintf('1/%d & %1.2E & %1.2f & %1.2E & %1.2f & %1.2E & %1.2f \\\\\n', numElPerDim(i), tab(i-1,:));
|
||||
end
|
||||
end
|
||||
fprintf('\n');
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user