39#include <boost/algorithm/string/predicate.hpp>
40#include <boost/core/ignore_unused.hpp>
41#include <boost/math/special_functions/gamma.hpp>
103 int nConvectiveFields = pFields.size();
104 int nScalars = nConvectiveFields - 1;
105 int nDim = pFields[0]->GetCoordim(0);
106 int nSolutionPts = pFields[0]->GetTotPoints();
107 int nTracePts = pFields[0]->GetTrace()->GetTotPoints();
110 if (pSession->DefinesSolverInfo(
"HOMOGENEOUS"))
140 for (i = 0; i < nScalars; ++i)
149 for (j = 0; j < nDim; ++j)
160 for (i = 0; i < nConvectiveFields; ++i)
168 for (j = 0; j < nDim; ++j)
179 for (j = 0; j < nScalars; ++j)
189 for (j = 0; j < nScalars + 1; ++j)
216 boost::ignore_unused(pSession);
221 int nLocalSolutionPts;
222 int nElements = pFields[0]->GetExpSize();
223 int nDimensions = pFields[0]->GetCoordim(0);
224 int nSolutionPts = pFields[0]->GetTotPoints();
225 int nTracePts = pFields[0]->GetTrace()->GetTotPoints();
228 for (i = 0; i < nDimensions; ++i)
247 for (n = 0; n < nElements; ++n)
249 ptsKeys = pFields[0]->GetExp(n)->GetPointsKeys();
250 nLocalSolutionPts = pFields[0]->GetExp(n)->GetTotPoints();
251 phys_offset = pFields[0]->GetPhys_Offset(n);
258 for (i = 0; i < nLocalSolutionPts; ++i)
260 m_jac[i + phys_offset] = jac[0];
278 for (n = 0; n < nElements; ++n)
280 base = pFields[0]->GetExp(n)->GetBase();
281 nquad0 = base[0]->GetNumPoints();
282 nquad1 = base[1]->GetNumPoints();
290 pFields[0]->GetExp(n)->GetTraceQFactors(0, auxArray1 =
292 pFields[0]->GetExp(n)->GetTraceQFactors(1, auxArray1 =
294 pFields[0]->GetExp(n)->GetTraceQFactors(2, auxArray1 =
296 pFields[0]->GetExp(n)->GetTraceQFactors(3, auxArray1 =
299 ptsKeys = pFields[0]->GetExp(n)->GetPointsKeys();
300 nLocalSolutionPts = pFields[0]->GetExp(n)->GetTotPoints();
301 phys_offset = pFields[0]->GetPhys_Offset(n);
314 ->GetDerivFactors(ptsKeys);
323 for (i = 0; i < nLocalSolutionPts; ++i)
325 m_jac[i + phys_offset] = jac[i];
326 m_gmat[0][i + phys_offset] = gmat[0][i];
327 m_gmat[1][i + phys_offset] = gmat[1][i];
328 m_gmat[2][i + phys_offset] = gmat[2][i];
329 m_gmat[3][i + phys_offset] = gmat[3][i];
334 for (i = 0; i < nLocalSolutionPts; ++i)
336 m_jac[i + phys_offset] = jac[0];
337 m_gmat[0][i + phys_offset] = gmat[0][0];
338 m_gmat[1][i + phys_offset] = gmat[1][0];
339 m_gmat[2][i + phys_offset] = gmat[2][0];
340 m_gmat[3][i + phys_offset] = gmat[3][0];
348 ASSERTL0(
false,
"3DFR Metric terms not implemented yet");
353 ASSERTL0(
false,
"Expansion dimension not recognised");
379 boost::ignore_unused(pSession);
385 int nquad0, nquad1, nquad2;
386 int nmodes0, nmodes1, nmodes2;
389 int nElements = pFields[0]->GetExpSize();
390 int nDim = pFields[0]->GetCoordim(0);
399 for (n = 0; n < nElements; ++n)
401 base = pFields[0]->GetExp(n)->GetBase();
402 nquad0 = base[0]->GetNumPoints();
403 nmodes0 = base[0]->GetNumModes();
407 base[0]->GetZW(z0, w0);
419 int p0 = nmodes0 - 1;
425 NekDouble ap0 = boost::math::tgamma(2 * p0 + 1) /
426 (pow(2.0, p0) * boost::math::tgamma(p0 + 1) *
427 boost::math::tgamma(p0 + 1));
437 ((2.0 * p0 + 1.0) * (p0 + 1.0) *
438 (ap0 * boost::math::tgamma(p0 + 1)) *
439 (ap0 * boost::math::tgamma(p0 + 1)));
443 c0 = 2.0 * (p0 + 1.0) /
444 ((2.0 * p0 + 1.0) * p0 *
445 (ap0 * boost::math::tgamma(p0 + 1)) *
446 (ap0 * boost::math::tgamma(p0 + 1)));
450 c0 = -2.0 / ((2.0 * p0 + 1.0) *
451 (ap0 * boost::math::tgamma(p0 + 1)) *
452 (ap0 * boost::math::tgamma(p0 + 1)));
456 c0 = 10000000000000000.0;
459 NekDouble etap0 = 0.5 * c0 * (2.0 * p0 + 1.0) *
460 (ap0 * boost::math::tgamma(p0 + 1)) *
461 (ap0 * boost::math::tgamma(p0 + 1));
463 NekDouble overeta0 = 1.0 / (1.0 + etap0);
476 for (i = 0; i < nquad0; ++i)
486 for (i = 0; i < nquad0; ++i)
509 for (n = 0; n < nElements; ++n)
511 base = pFields[0]->GetExp(n)->GetBase();
512 nquad0 = base[0]->GetNumPoints();
513 nquad1 = base[1]->GetNumPoints();
514 nmodes0 = base[0]->GetNumModes();
515 nmodes1 = base[1]->GetNumModes();
522 base[0]->GetZW(z0, w0);
523 base[1]->GetZW(z1, w1);
540 int p0 = nmodes0 - 1;
541 int p1 = nmodes1 - 1;
548 NekDouble ap0 = boost::math::tgamma(2 * p0 + 1) /
549 (pow(2.0, p0) * boost::math::tgamma(p0 + 1) *
550 boost::math::tgamma(p0 + 1));
552 NekDouble ap1 = boost::math::tgamma(2 * p1 + 1) /
553 (pow(2.0, p1) * boost::math::tgamma(p1 + 1) *
554 boost::math::tgamma(p1 + 1));
565 ((2.0 * p0 + 1.0) * (p0 + 1.0) *
566 (ap0 * boost::math::tgamma(p0 + 1)) *
567 (ap0 * boost::math::tgamma(p0 + 1)));
570 ((2.0 * p1 + 1.0) * (p1 + 1.0) *
571 (ap1 * boost::math::tgamma(p1 + 1)) *
572 (ap1 * boost::math::tgamma(p1 + 1)));
576 c0 = 2.0 * (p0 + 1.0) /
577 ((2.0 * p0 + 1.0) * p0 *
578 (ap0 * boost::math::tgamma(p0 + 1)) *
579 (ap0 * boost::math::tgamma(p0 + 1)));
581 c1 = 2.0 * (p1 + 1.0) /
582 ((2.0 * p1 + 1.0) * p1 *
583 (ap1 * boost::math::tgamma(p1 + 1)) *
584 (ap1 * boost::math::tgamma(p1 + 1)));
588 c0 = -2.0 / ((2.0 * p0 + 1.0) *
589 (ap0 * boost::math::tgamma(p0 + 1)) *
590 (ap0 * boost::math::tgamma(p0 + 1)));
592 c1 = -2.0 / ((2.0 * p1 + 1.0) *
593 (ap1 * boost::math::tgamma(p1 + 1)) *
594 (ap1 * boost::math::tgamma(p1 + 1)));
598 c0 = 10000000000000000.0;
599 c1 = 10000000000000000.0;
602 NekDouble etap0 = 0.5 * c0 * (2.0 * p0 + 1.0) *
603 (ap0 * boost::math::tgamma(p0 + 1)) *
604 (ap0 * boost::math::tgamma(p0 + 1));
606 NekDouble etap1 = 0.5 * c1 * (2.0 * p1 + 1.0) *
607 (ap1 * boost::math::tgamma(p1 + 1)) *
608 (ap1 * boost::math::tgamma(p1 + 1));
610 NekDouble overeta0 = 1.0 / (1.0 + etap0);
611 NekDouble overeta1 = 1.0 / (1.0 + etap1);
630 for (i = 0; i < nquad0; ++i)
640 for (i = 0; i < nquad1; ++i)
650 for (i = 0; i < nquad0; ++i)
660 for (i = 0; i < nquad1; ++i)
680 for (n = 0; n < nElements; ++n)
682 base = pFields[0]->GetExp(n)->GetBase();
683 nquad0 = base[0]->GetNumPoints();
684 nquad1 = base[1]->GetNumPoints();
685 nquad2 = base[2]->GetNumPoints();
686 nmodes0 = base[0]->GetNumModes();
687 nmodes1 = base[1]->GetNumModes();
688 nmodes2 = base[2]->GetNumModes();
697 base[0]->GetZW(z0, w0);
698 base[1]->GetZW(z1, w1);
699 base[1]->GetZW(z2, w2);
721 int p0 = nmodes0 - 1;
722 int p1 = nmodes1 - 1;
723 int p2 = nmodes2 - 1;
731 NekDouble ap0 = boost::math::tgamma(2 * p0 + 1) /
732 (pow(2.0, p0) * boost::math::tgamma(p0 + 1) *
733 boost::math::tgamma(p0 + 1));
736 NekDouble ap1 = boost::math::tgamma(2 * p1 + 1) /
737 (pow(2.0, p1) * boost::math::tgamma(p1 + 1) *
738 boost::math::tgamma(p1 + 1));
741 NekDouble ap2 = boost::math::tgamma(2 * p2 + 1) /
742 (pow(2.0, p2) * boost::math::tgamma(p2 + 1) *
743 boost::math::tgamma(p2 + 1));
755 ((2.0 * p0 + 1.0) * (p0 + 1.0) *
756 (ap0 * boost::math::tgamma(p0 + 1)) *
757 (ap0 * boost::math::tgamma(p0 + 1)));
760 ((2.0 * p1 + 1.0) * (p1 + 1.0) *
761 (ap1 * boost::math::tgamma(p1 + 1)) *
762 (ap1 * boost::math::tgamma(p1 + 1)));
765 ((2.0 * p2 + 1.0) * (p2 + 1.0) *
766 (ap2 * boost::math::tgamma(p2 + 1)) *
767 (ap2 * boost::math::tgamma(p2 + 1)));
771 c0 = 2.0 * (p0 + 1.0) /
772 ((2.0 * p0 + 1.0) * p0 *
773 (ap0 * boost::math::tgamma(p0 + 1)) *
774 (ap0 * boost::math::tgamma(p0 + 1)));
776 c1 = 2.0 * (p1 + 1.0) /
777 ((2.0 * p1 + 1.0) * p1 *
778 (ap1 * boost::math::tgamma(p1 + 1)) *
779 (ap1 * boost::math::tgamma(p1 + 1)));
781 c2 = 2.0 * (p2 + 1.0) /
782 ((2.0 * p2 + 1.0) * p2 *
783 (ap2 * boost::math::tgamma(p2 + 1)) *
784 (ap2 * boost::math::tgamma(p2 + 1)));
788 c0 = -2.0 / ((2.0 * p0 + 1.0) *
789 (ap0 * boost::math::tgamma(p0 + 1)) *
790 (ap0 * boost::math::tgamma(p0 + 1)));
792 c1 = -2.0 / ((2.0 * p1 + 1.0) *
793 (ap1 * boost::math::tgamma(p1 + 1)) *
794 (ap1 * boost::math::tgamma(p1 + 1)));
796 c2 = -2.0 / ((2.0 * p2 + 1.0) *
797 (ap2 * boost::math::tgamma(p2 + 1)) *
798 (ap2 * boost::math::tgamma(p2 + 1)));
802 c0 = 10000000000000000.0;
803 c1 = 10000000000000000.0;
804 c2 = 10000000000000000.0;
807 NekDouble etap0 = 0.5 * c0 * (2.0 * p0 + 1.0) *
808 (ap0 * boost::math::tgamma(p0 + 1)) *
809 (ap0 * boost::math::tgamma(p0 + 1));
811 NekDouble etap1 = 0.5 * c1 * (2.0 * p1 + 1.0) *
812 (ap1 * boost::math::tgamma(p1 + 1)) *
813 (ap1 * boost::math::tgamma(p1 + 1));
815 NekDouble etap2 = 0.5 * c2 * (2.0 * p2 + 1.0) *
816 (ap2 * boost::math::tgamma(p2 + 1)) *
817 (ap2 * boost::math::tgamma(p2 + 1));
819 NekDouble overeta0 = 1.0 / (1.0 + etap0);
820 NekDouble overeta1 = 1.0 / (1.0 + etap1);
821 NekDouble overeta2 = 1.0 / (1.0 + etap2);
846 for (i = 0; i < nquad0; ++i)
856 for (i = 0; i < nquad1; ++i)
866 for (i = 0; i < nquad2; ++i)
876 for (i = 0; i < nquad0; ++i)
886 for (i = 0; i < nquad1; ++i)
896 for (i = 0; i < nquad2; ++i)
909 ASSERTL0(
false,
"Expansion dimension not recognised");
924 const std::size_t nConvectiveFields,
931 boost::ignore_unused(pFwd, pBwd);
939 Basis = fields[0]->GetExp(0)->GetBase();
941 int nElements = fields[0]->GetExpSize();
942 int nDim = fields[0]->GetCoordim(0);
943 int nScalars = inarray.size();
944 int nSolutionPts = fields[0]->GetTotPoints();
945 int nCoeffs = fields[0]->GetNcoeffs();
948 for (i = 0; i < nConvectiveFields; ++i)
961 for (i = 0; i < nScalars; ++i)
965 for (n = 0; n < nElements; n++)
967 phys_offset = fields[0]->GetPhys_Offset(n);
969 fields[i]->GetExp(n)->PhysDeriv(
970 0, auxArray1 = inarray[i] + phys_offset,
971 auxArray2 =
m_DU1[i][0] + phys_offset);
987 1, &
m_D1[i][0][0], 1);
1000 for (i = 0; i < nConvectiveFields; ++i)
1004 for (n = 0; n < nElements; n++)
1006 phys_offset = fields[0]->GetPhys_Offset(n);
1008 fields[i]->GetExp(n)->PhysDeriv(
1010 auxArray2 =
m_DD1[i][0] + phys_offset);
1026 1, &outarray[i][0], 1);
1029 if (!(
Basis[0]->Collocation()))
1031 fields[i]->FwdTrans(outarray[i], outarrayCoeff[i]);
1032 fields[i]->BwdTrans(outarrayCoeff[i], outarray[i]);
1040 for (i = 0; i < nScalars; ++i)
1042 for (j = 0; j < nDim; ++j)
1051 &
m_gmat[0][0], 1, &u1_hat[0], 1);
1057 &
m_gmat[1][0], 1, &u2_hat[0], 1);
1065 &
m_gmat[2][0], 1, &u1_hat[0], 1);
1071 &
m_gmat[3][0], 1, &u2_hat[0], 1);
1077 for (n = 0; n < nElements; n++)
1079 phys_offset = fields[0]->GetPhys_Offset(n);
1081 fields[i]->GetExp(n)->StdPhysDeriv(
1082 0, auxArray1 = u1_hat + phys_offset,
1083 auxArray2 =
m_tmp1[i][j] + phys_offset);
1085 fields[i]->GetExp(n)->StdPhysDeriv(
1086 1, auxArray1 = u2_hat + phys_offset,
1087 auxArray2 =
m_tmp2[i][j] + phys_offset);
1095 &
m_DU1[i][j][0], 1);
1099 DerCFlux_2D(nConvectiveFields, j, fields, inarray[i],
1105 for (j = 0; j < nSolutionPts; ++j)
1126 for (j = 0; j < nSolutionPts; j++)
1138 for (j = 0; j < nDim; ++j)
1148 for (i = 0; i < nScalars; ++i)
1163 for (i = 0; i < nConvectiveFields; ++i)
1169 for (j = 0; j < nSolutionPts; j++)
1180 for (n = 0; n < nElements; n++)
1182 phys_offset = fields[0]->GetPhys_Offset(n);
1184 fields[0]->GetExp(n)->StdPhysDeriv(
1185 0, auxArray1 = f_hat + phys_offset,
1186 auxArray2 =
m_DD1[i][0] + phys_offset);
1188 fields[0]->GetExp(n)->StdPhysDeriv(
1189 1, auxArray1 = g_hat + phys_offset,
1190 auxArray2 =
m_DD1[i][1] + phys_offset);
1198 if (
Basis[0]->GetPointsType() ==
1200 Basis[1]->GetPointsType() ==
1214 &outarray[i][0], 1);
1219 &outarray[i][0], 1);
1222 if (!(
Basis[0]->Collocation()))
1224 fields[i]->FwdTrans(outarray[i], outarrayCoeff[i]);
1225 fields[i]->BwdTrans(outarrayCoeff[i], outarray[i]);
1233 ASSERTL0(
false,
"3D FRDG case not implemented yet");
1249 int nTracePts = fields[0]->GetTrace()->GetTotPoints();
1250 int nScalars = inarray.size();
1251 int nDim = fields[0]->GetCoordim(0);
1257 for (i = 0; i < nDim; ++i)
1259 fields[0]->ExtractTracePhys(inarray[i],
m_traceVel[i]);
1269 for (i = 0; i < nScalars; ++i)
1274 fields[i]->GetFwdBwdTracePhys(inarray[i], Fwd[i], Bwd[i]);
1275 fields[0]->GetTrace()->Upwind(Vn, Fwd[i], Bwd[i], numflux[i]);
1279 if (fields[0]->GetBndCondExpansions().size())
1285 for (j = 0; j < nDim; ++j)
1287 for (i = 0; i < nScalars; ++i)
1289 Vmath::Vcopy(nTracePts, numflux[i], 1, numericalFluxO1[i][j], 1);
1307 int nBndEdgePts, nBndEdges, nBndRegions;
1309 int nTracePts = fields[0]->GetTrace()->GetTotPoints();
1310 int nScalars = inarray.size();
1320 for (i = 0; i < nScalars; ++i)
1325 fields[i]->ExtractTracePhys(inarray[i], uplus[i]);
1329 for (i = 0; i < nScalars - 1; ++i)
1334 nBndRegions = fields[i + 1]->GetBndCondExpansions().size();
1335 for (j = 0; j < nBndRegions; ++j)
1338 ->GetBndConditions()[j]
1344 nBndEdges = fields[i + 1]->GetBndCondExpansions()[j]->GetExpSize();
1345 for (e = 0; e < nBndEdges; ++e)
1347 nBndEdgePts = fields[i + 1]
1348 ->GetBndCondExpansions()[j]
1353 fields[i + 1]->GetBndCondExpansions()[j]->GetPhys_Offset(e);
1355 id2 = fields[0]->GetTrace()->GetPhys_Offset(
1356 fields[0]->GetTraceMap()->GetBndCondIDToGlobalTraceID(
1361 fields[i]->GetBndConditions()[j]->GetUserDefined(),
1364 fields[i]->GetBndConditions()[j]->GetUserDefined(),
1367 Vmath::Zero(nBndEdgePts, &scalarVariables[i][id2], 1);
1372 ->GetBndConditions()[j]
1373 ->GetBoundaryConditionType() ==
1378 ->GetBndCondExpansions()[j]
1379 ->UpdatePhys())[id1],
1382 ->GetBndCondExpansions()[j]
1383 ->UpdatePhys())[id1],
1384 1, &scalarVariables[i][id2], 1);
1389 ->GetBndConditions()[j]
1390 ->GetBoundaryConditionType() ==
1394 &penaltyfluxO1[i][id2], 1);
1398 else if ((fields[i]->GetBndConditions()[j])
1399 ->GetBoundaryConditionType() ==
1403 &penaltyfluxO1[i][id2], 1);
1407 Vmath::Vmul(nBndEdgePts, &scalarVariables[i][id2], 1,
1408 &scalarVariables[i][id2], 1, &tmp1[id2], 1);
1410 Vmath::Smul(nBndEdgePts, 0.5, &tmp1[id2], 1, &tmp1[id2], 1);
1412 Vmath::Vadd(nBndEdgePts, &tmp2[id2], 1, &tmp1[id2], 1,
1420 nBndRegions = fields[nScalars]->GetBndCondExpansions().size();
1421 for (j = 0; j < nBndRegions; ++j)
1423 nBndEdges = fields[nScalars]->GetBndCondExpansions()[j]->GetExpSize();
1425 if (fields[nScalars]
1426 ->GetBndConditions()[j]
1432 for (e = 0; e < nBndEdges; ++e)
1434 nBndEdgePts = fields[nScalars]
1435 ->GetBndCondExpansions()[j]
1440 fields[nScalars]->GetBndCondExpansions()[j]->GetPhys_Offset(e);
1442 id2 = fields[0]->GetTrace()->GetPhys_Offset(
1443 fields[0]->GetTraceMap()->GetBndCondIDToGlobalTraceID(cnt++));
1447 fields[i]->GetBndConditions()[j]->GetUserDefined(),
1451 &scalarVariables[nScalars - 1][id2], 1);
1456 ->GetBndConditions()[j]
1457 ->GetBoundaryConditionType() ==
1464 ->GetBndCondExpansions()[j]
1466 1, &(fields[0]->GetBndCondExpansions()[j]->GetPhys())[id1],
1467 1, &scalarVariables[nScalars - 1][id2], 1);
1470 Vmath::Vsub(nBndEdgePts, &scalarVariables[nScalars - 1][id2], 1,
1471 &tmp2[id2], 1, &scalarVariables[nScalars - 1][id2],
1476 &scalarVariables[nScalars - 1][id2], 1,
1477 &scalarVariables[nScalars - 1][id2], 1);
1481 if (fields[nScalars]
1482 ->GetBndConditions()[j]
1483 ->GetBoundaryConditionType() ==
1486 fields[nScalars]->GetBndConditions()[j]->GetUserDefined(),
1489 Vmath::Vcopy(nBndEdgePts, &scalarVariables[nScalars - 1][id2],
1490 1, &penaltyfluxO1[nScalars - 1][id2], 1);
1494 else if (((fields[nScalars]->GetBndConditions()[j])
1495 ->GetBoundaryConditionType() ==
1497 boost::iequals(fields[nScalars]
1498 ->GetBndConditions()[j]
1502 Vmath::Vcopy(nBndEdgePts, &uplus[nScalars - 1][id2], 1,
1503 &penaltyfluxO1[nScalars - 1][id2], 1);
1520 int nTracePts = fields[0]->GetTrace()->GetTotPoints();
1521 int nVariables = fields.size();
1522 int nDim = fields[0]->GetCoordim(0);
1533 for (i = 0; i < nDim; ++i)
1535 fields[0]->ExtractTracePhys(ufield[i],
m_traceVel[i]);
1543 for (i = 1; i < nVariables; ++i)
1546 for (j = 0; j < nDim; ++j)
1549 fields[i]->GetFwdBwdTracePhys(qfield[j][i], qFwd, qBwd);
1552 fields[i]->GetTrace()->Upwind(Vn, qBwd, qFwd, qfluxtemp);
1559 if (fields[0]->GetBndCondExpansions().size())
1565 Vmath::Vadd(nTracePts, qfluxtemp, 1, qflux[i], 1, qflux[i], 1);
1580 int nBndEdges, nBndEdgePts;
1584 int nTracePts = fields[0]->GetTrace()->GetTotPoints();
1585 int nBndRegions = fields[var]->GetBndCondExpansions().size();
1591 fields[var]->ExtractTracePhys(qfield, qtemp);
1594 for (i = 0; i < nBndRegions; ++i)
1597 nBndEdges = fields[var]->GetBndCondExpansions()[i]->GetExpSize();
1599 if (fields[var]->GetBndConditions()[i]->GetBoundaryConditionType() ==
1606 for (e = 0; e < nBndEdges; ++e)
1608 nBndEdgePts = fields[var]
1609 ->GetBndCondExpansions()[i]
1613 id2 = fields[0]->GetTrace()->GetPhys_Offset(
1614 fields[0]->GetTraceMap()->GetBndCondIDToGlobalTraceID(cnt++));
1619 ->GetBndConditions()[i]
1620 ->GetBoundaryConditionType() ==
1623 fields[var]->GetBndConditions()[i]->GetUserDefined(),
1627 &qtemp[id2], 1, &penaltyflux[id2], 1);
1631 else if ((fields[var]->GetBndConditions()[i])
1632 ->GetBoundaryConditionType() ==
1635 ASSERTL0(
false,
"Neumann bcs not implemented for LFRNS");
1637 else if (boost::iequals(
1638 fields[var]->GetBndConditions()[i]->GetUserDefined(),
1649 &qtemp[id2], 1, &penaltyflux[id2], 1);
1667 const int nConvectiveFields,
1672 boost::ignore_unused(nConvectiveFields);
1675 int nLocalSolutionPts, phys_offset;
1683 Basis = fields[0]->GetExp(0)->GetBasis(0);
1685 int nElements = fields[0]->GetExpSize();
1686 int nPts = fields[0]->GetTotPoints();
1697 fields[0]->GetTraceMap()->GetElmtToTrace();
1699 for (n = 0; n < nElements; ++n)
1701 nLocalSolutionPts = fields[0]->GetExp(n)->GetTotPoints();
1702 phys_offset = fields[0]->GetPhys_Offset(n);
1706 Vmath::Vcopy(nLocalSolutionPts, &flux[phys_offset], 1, &tmparrayX1[0],
1709 fields[0]->GetExp(n)->GetTracePhysVals(0, elmtToTrace[n][0], tmparrayX1,
1711 JumpL[n] = iFlux[n] - tmpFluxVertex[0];
1713 fields[0]->GetExp(n)->GetTracePhysVals(1, elmtToTrace[n][1], tmparrayX1,
1715 JumpR[n] = iFlux[n + 1] - tmpFluxVertex[0];
1718 for (n = 0; n < nElements; ++n)
1720 ptsKeys = fields[0]->GetExp(n)->GetPointsKeys();
1721 nLocalSolutionPts = fields[0]->GetExp(n)->GetTotPoints();
1722 phys_offset = fields[0]->GetPhys_Offset(n);
1730 JumpL[n] = JumpL[n] * jac[0];
1731 JumpR[n] = JumpR[n] * jac[0];
1742 Vmath::Vadd(nLocalSolutionPts, &DCL[0], 1, &DCR[0], 1,
1743 &derCFlux[phys_offset], 1);
1763 const int nConvectiveFields,
const int direction,
1768 boost::ignore_unused(nConvectiveFields);
1770 int n, e, i, j, cnt;
1774 int nElements = fields[0]->GetExpSize();
1775 int trace_offset, phys_offset;
1776 int nLocalSolutionPts;
1784 fields[0]->GetTraceMap()->GetElmtToTrace();
1787 for (n = 0; n < nElements; ++n)
1790 phys_offset = fields[0]->GetPhys_Offset(n);
1791 nLocalSolutionPts = fields[0]->GetExp(n)->GetTotPoints();
1792 ptsKeys = fields[0]->GetExp(n)->GetPointsKeys();
1801 base = fields[0]->GetExp(n)->GetBase();
1802 nquad0 = base[0]->GetNumPoints();
1803 nquad1 = base[1]->GetNumPoints();
1811 for (e = 0; e < fields[0]->GetExp(n)->GetNtraces(); ++e)
1814 nEdgePts = fields[0]->GetExp(n)->GetTraceNumPoints(e);
1820 trace_offset = fields[0]->GetTrace()->GetPhys_Offset(
1821 elmtToTrace[n][e]->GetElmtId());
1826 fields[0]->GetExp(n)->GetTracePhysVals(
1827 e, elmtToTrace[n][e], flux + phys_offset, auxArray1 = tmparray);
1832 Vmath::Vsub(nEdgePts, &iFlux[trace_offset], 1, &tmparray[0], 1,
1837 if (fields[0]->GetExp(n)->GetTraceOrient(e) ==
1846 ->as<LocalRegions::Expansion2D>()
1854 fields[0]->GetExp(n)->GetTracePhysVals(
1855 e, elmtToTrace[n][e], jac, auxArray1 = jacEdge);
1859 if (fields[0]->GetExp(n)->GetTraceOrient(e) ==
1867 for (j = 0; j < nEdgePts; j++)
1869 fluxJumps[j] = fluxJumps[j] * jacEdge[j];
1877 Vmath::Smul(nEdgePts, jac[0], fluxJumps, 1, fluxJumps, 1);
1886 for (i = 0; i < nquad0; ++i)
1888 for (j = 0; j < nquad1; ++j)
1890 cnt = i + j * nquad0;
1891 divCFluxE0[cnt] = fluxJumps[i] *
m_dGL_xi2[n][j];
1896 for (i = 0; i < nquad1; ++i)
1898 for (j = 0; j < nquad0; ++j)
1900 cnt = (nquad0)*i + j;
1901 divCFluxE1[cnt] = fluxJumps[i] *
m_dGR_xi1[n][j];
1906 for (i = 0; i < nquad0; ++i)
1908 for (j = 0; j < nquad1; ++j)
1910 cnt = j * nquad0 + i;
1911 divCFluxE2[cnt] = fluxJumps[i] *
m_dGR_xi2[n][j];
1916 for (i = 0; i < nquad1; ++i)
1918 for (j = 0; j < nquad0; ++j)
1920 cnt = j + i * nquad0;
1921 divCFluxE3[cnt] = fluxJumps[i] *
m_dGL_xi1[n][j];
1927 ASSERTL0(
false,
"edge value (< 3) is out of range");
1936 Vmath::Vadd(nLocalSolutionPts, &divCFluxE1[0], 1, &divCFluxE3[0], 1,
1937 &derCFlux[phys_offset], 1);
1939 else if (direction == 1)
1941 Vmath::Vadd(nLocalSolutionPts, &divCFluxE0[0], 1, &divCFluxE2[0], 1,
1942 &derCFlux[phys_offset], 1);
1961 const int nConvectiveFields,
1968 boost::ignore_unused(nConvectiveFields);
1970 int n, e, i, j, cnt;
1972 int nElements = fields[0]->GetExpSize();
1974 int nLocalSolutionPts;
1985 fields[0]->GetTraceMap()->GetElmtToTrace();
1988 for (n = 0; n < nElements; ++n)
1991 phys_offset = fields[0]->GetPhys_Offset(n);
1992 nLocalSolutionPts = fields[0]->GetExp(n)->GetTotPoints();
1994 base = fields[0]->GetExp(n)->GetBase();
1995 nquad0 = base[0]->GetNumPoints();
1996 nquad1 = base[1]->GetNumPoints();
2004 for (e = 0; e < fields[0]->GetExp(n)->GetNtraces(); ++e)
2007 nEdgePts = fields[0]->GetExp(n)->GetTraceNumPoints(e);
2016 trace_offset = fields[0]->GetTrace()->GetPhys_Offset(
2017 elmtToTrace[n][e]->GetElmtId());
2021 fields[0]->GetExp(n)->GetTraceNormal(e);
2025 fields[0]->GetExp(n)->GetTracePhysVals(e, elmtToTrace[n][e],
2026 fluxX1 + phys_offset,
2027 auxArray1 = tmparrayX1);
2031 fields[0]->GetExp(n)->GetTracePhysVals(e, elmtToTrace[n][e],
2032 fluxX2 + phys_offset,
2033 auxArray1 = tmparrayX2);
2036 for (i = 0; i < nEdgePts; ++i)
2043 Vmath::Vsub(nEdgePts, &numericalFlux[trace_offset], 1, &fluxN[0], 1,
2047 if (fields[0]->GetExp(n)->GetTraceOrient(e) ==
2051 auxArray2 = fluxJumps, 1);
2054 for (i = 0; i < nEdgePts; ++i)
2059 fluxJumps[i] = -fluxJumps[i];
2067 for (i = 0; i < nquad0; ++i)
2070 fluxJumps[i] = -(
m_Q2D_e0[n][i]) * fluxJumps[i];
2072 for (j = 0; j < nquad1; ++j)
2074 cnt = i + j * nquad0;
2075 divCFluxE0[cnt] = fluxJumps[i] *
m_dGL_xi2[n][j];
2080 for (i = 0; i < nquad1; ++i)
2083 fluxJumps[i] = (
m_Q2D_e1[n][i]) * fluxJumps[i];
2085 for (j = 0; j < nquad0; ++j)
2087 cnt = (nquad0)*i + j;
2088 divCFluxE1[cnt] = fluxJumps[i] *
m_dGR_xi1[n][j];
2093 for (i = 0; i < nquad0; ++i)
2096 fluxJumps[i] = (
m_Q2D_e2[n][i]) * fluxJumps[i];
2098 for (j = 0; j < nquad1; ++j)
2100 cnt = j * nquad0 + i;
2101 divCFluxE2[cnt] = fluxJumps[i] *
m_dGR_xi2[n][j];
2106 for (i = 0; i < nquad1; ++i)
2109 fluxJumps[i] = -(
m_Q2D_e3[n][i]) * fluxJumps[i];
2110 for (j = 0; j < nquad0; ++j)
2112 cnt = j + i * nquad0;
2113 divCFluxE3[cnt] = fluxJumps[i] *
m_dGL_xi1[n][j];
2119 ASSERTL0(
false,
"edge value (< 3) is out of range");
2125 Vmath::Vadd(nLocalSolutionPts, &divCFluxE0[0], 1, &divCFluxE1[0], 1,
2126 &divCFlux[phys_offset], 1);
2128 Vmath::Vadd(nLocalSolutionPts, &divCFlux[phys_offset], 1,
2129 &divCFluxE2[0], 1, &divCFlux[phys_offset], 1);
2131 Vmath::Vadd(nLocalSolutionPts, &divCFlux[phys_offset], 1,
2132 &divCFluxE3[0], 1, &divCFlux[phys_offset], 1);
2151 const int nConvectiveFields,
2158 boost::ignore_unused(nConvectiveFields);
2160 int n, e, i, j, cnt;
2162 int nElements = fields[0]->GetExpSize();
2163 int nLocalSolutionPts;
2174 fields[0]->GetTraceMap()->GetElmtToTrace();
2177 for (n = 0; n < nElements; ++n)
2180 phys_offset = fields[0]->GetPhys_Offset(n);
2181 nLocalSolutionPts = fields[0]->GetExp(n)->GetTotPoints();
2183 base = fields[0]->GetExp(n)->GetBase();
2184 nquad0 = base[0]->GetNumPoints();
2185 nquad1 = base[1]->GetNumPoints();
2193 for (e = 0; e < fields[0]->GetExp(n)->GetNtraces(); ++e)
2196 nEdgePts = fields[0]->GetExp(n)->GetTraceNumPoints(e);
2205 trace_offset = fields[0]->GetTrace()->GetPhys_Offset(
2206 elmtToTrace[n][e]->GetElmtId());
2210 fields[0]->GetExp(n)->GetTraceNormal(e);
2219 fields[0]->GetExp(n)->GetTracePhysVals(e, elmtToTrace[n][e],
2220 fluxX2 + phys_offset,
2221 auxArray1 = fluxN_D);
2226 Vmath::Vcopy(nEdgePts, &numericalFlux[trace_offset], 1,
2230 if (fields[0]->GetExp(n)->GetTraceOrient(e) ==
2234 auxArray2 = fluxN, 1);
2237 auxArray2 = fluxN_D, 1);
2241 for (i = 0; i < nquad0; ++i)
2244 fluxN_R[i] = (
m_Q2D_e0[n][i]) * fluxN[i];
2247 for (i = 0; i < nEdgePts; ++i)
2254 fluxN_R[i] = -fluxN_R[i];
2260 Vmath::Vsub(nEdgePts, &fluxN_R[0], 1, &fluxN_D[0], 1,
2265 for (i = 0; i < nquad0; ++i)
2267 for (j = 0; j < nquad1; ++j)
2269 cnt = i + j * nquad0;
2270 divCFluxE0[cnt] = -fluxJumps[i] *
m_dGL_xi2[n][j];
2278 fields[0]->GetExp(n)->GetTracePhysVals(e, elmtToTrace[n][e],
2279 fluxX1 + phys_offset,
2280 auxArray1 = fluxN_D);
2283 Vmath::Vcopy(nEdgePts, &numericalFlux[trace_offset], 1,
2287 if (fields[0]->GetExp(n)->GetTraceOrient(e) ==
2291 auxArray2 = fluxN, 1);
2294 auxArray2 = fluxN_D, 1);
2298 for (i = 0; i < nquad1; ++i)
2301 fluxN_R[i] = (
m_Q2D_e1[n][i]) * fluxN[i];
2304 for (i = 0; i < nEdgePts; ++i)
2311 fluxN_R[i] = -fluxN_R[i];
2317 Vmath::Vsub(nEdgePts, &fluxN_R[0], 1, &fluxN_D[0], 1,
2322 for (i = 0; i < nquad1; ++i)
2324 for (j = 0; j < nquad0; ++j)
2326 cnt = (nquad0)*i + j;
2327 divCFluxE1[cnt] = fluxJumps[i] *
m_dGR_xi1[n][j];
2337 fields[0]->GetExp(n)->GetTracePhysVals(e, elmtToTrace[n][e],
2338 fluxX2 + phys_offset,
2339 auxArray1 = fluxN_D);
2342 Vmath::Vcopy(nEdgePts, &numericalFlux[trace_offset], 1,
2346 if (fields[0]->GetExp(n)->GetTraceOrient(e) ==
2350 auxArray2 = fluxN, 1);
2353 auxArray2 = fluxN_D, 1);
2357 for (i = 0; i < nquad0; ++i)
2360 fluxN_R[i] = (
m_Q2D_e2[n][i]) * fluxN[i];
2363 for (i = 0; i < nEdgePts; ++i)
2370 fluxN_R[i] = -fluxN_R[i];
2377 Vmath::Vsub(nEdgePts, &fluxN_R[0], 1, &fluxN_D[0], 1,
2382 for (i = 0; i < nquad0; ++i)
2384 for (j = 0; j < nquad1; ++j)
2386 cnt = j * nquad0 + i;
2387 divCFluxE2[cnt] = fluxJumps[i] *
m_dGR_xi2[n][j];
2396 fields[0]->GetExp(n)->GetTracePhysVals(e, elmtToTrace[n][e],
2397 fluxX1 + phys_offset,
2398 auxArray1 = fluxN_D);
2402 Vmath::Vcopy(nEdgePts, &numericalFlux[trace_offset], 1,
2406 if (fields[0]->GetExp(n)->GetTraceOrient(e) ==
2410 auxArray2 = fluxN, 1);
2413 auxArray2 = fluxN_D, 1);
2417 for (i = 0; i < nquad1; ++i)
2420 fluxN_R[i] = (
m_Q2D_e3[n][i]) * fluxN[i];
2423 for (i = 0; i < nEdgePts; ++i)
2430 fluxN_R[i] = -fluxN_R[i];
2437 Vmath::Vsub(nEdgePts, &fluxN_R[0], 1, &fluxN_D[0], 1,
2442 for (i = 0; i < nquad1; ++i)
2444 for (j = 0; j < nquad0; ++j)
2446 cnt = j + i * nquad0;
2447 divCFluxE3[cnt] = -fluxJumps[i] *
m_dGL_xi1[n][j];
2452 ASSERTL0(
false,
"edge value (< 3) is out of range");
2458 Vmath::Vadd(nLocalSolutionPts, &divCFluxE0[0], 1, &divCFluxE1[0], 1,
2459 &divCFlux[phys_offset], 1);
2461 Vmath::Vadd(nLocalSolutionPts, &divCFlux[phys_offset], 1,
2462 &divCFluxE2[0], 1, &divCFlux[phys_offset], 1);
2464 Vmath::Vadd(nLocalSolutionPts, &divCFlux[phys_offset], 1,
2465 &divCFluxE3[0], 1, &divCFlux[phys_offset], 1);
#define ASSERTL0(condition, msg)
Represents a basis of a given type.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
const SpatialDomains::GeomFactorsSharedPtr & GetMetricInfo() const
DiffusionFluxVecCBNS m_fluxVectorNS
virtual void v_Diffuse(const std::size_t nConvective, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const Array< OneD, Array< OneD, NekDouble > > &pFwd, const Array< OneD, Array< OneD, NekDouble > > &pBwd) override
Calculate FR Diffusion for the Navier-Stokes (NS) equations using an LDG interface flux.
void SetupMetrics(LibUtilities::SessionReaderSharedPtr pSession, Array< OneD, MultiRegions::ExpListSharedPtr > pFields)
Setup the metric terms to compute the contravariant fluxes. (i.e. this special metric terms transform...
NekDouble m_thermalConductivity
static std::string type[]
Array< OneD, Array< OneD, NekDouble > > m_traceVel
Array< OneD, Array< OneD, NekDouble > > m_divFD
Array< OneD, NekDouble > m_jac
void DerCFlux_1D(const int nConvectiveFields, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, const NekDouble > &flux, const Array< OneD, const NekDouble > &iFlux, Array< OneD, NekDouble > &derCFlux)
Compute the derivative of the corrective flux for 1D problems.
void NumericalFluxO1(const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, Array< OneD, NekDouble > > > &numericalFluxO1)
Builds the numerical flux for the 1st order derivatives.
Array< OneD, Array< OneD, NekDouble > > m_viscFlux
void WeakPenaltyO1(const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &penaltyfluxO1)
Imposes appropriate bcs for the 1st order derivatives.
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_tmp2
Array< OneD, Array< OneD, NekDouble > > m_Q2D_e1
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_DFC2
Array< OneD, Array< OneD, NekDouble > > m_dGR_xi2
Array< OneD, Array< OneD, NekDouble > > m_divFC
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_DFC1
Array< OneD, Array< OneD, NekDouble > > m_dGR_xi3
Array< OneD, Array< OneD, NekDouble > > m_gmat
Array< OneD, Array< OneD, NekDouble > > m_Q2D_e3
Array< OneD, Array< OneD, NekDouble > > m_traceNormals
Array< OneD, Array< OneD, NekDouble > > m_Q2D_e2
Array< OneD, Array< OneD, NekDouble > > m_dGL_xi2
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_viscTensor
void SetupCFunctions(LibUtilities::SessionReaderSharedPtr pSession, Array< OneD, MultiRegions::ExpListSharedPtr > pFields)
Setup the derivatives of the correction functions. For more details see J Sci Comput (2011) 47: 50–72...
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_tmp1
Array< OneD, Array< OneD, NekDouble > > m_dGL_xi3
Array< OneD, Array< OneD, NekDouble > > m_Q2D_e0
void DivCFlux_2D(const int nConvectiveFields, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, const NekDouble > &fluxX1, const Array< OneD, const NekDouble > &fluxX2, const Array< OneD, const NekDouble > &numericalFlux, Array< OneD, NekDouble > &divCFlux)
Compute the divergence of the corrective flux for 2D problems.
void DerCFlux_2D(const int nConvectiveFields, const int direction, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, const NekDouble > &flux, const Array< OneD, NekDouble > &iFlux, Array< OneD, NekDouble > &derCFlux)
Compute the derivative of the corrective flux wrt a given coordinate for 2D problems.
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_IF1
void DivCFlux_2D_Gauss(const int nConvectiveFields, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, const NekDouble > &fluxX1, const Array< OneD, const NekDouble > &fluxX2, const Array< OneD, const NekDouble > &numericalFlux, Array< OneD, NekDouble > &divCFlux)
Compute the divergence of the corrective flux for 2D problems where POINTSTYPE="GaussGaussLegendre".
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_D1
DiffusionLFRNS(std::string diffType)
DiffusionLFRNS uses the Flux Reconstruction (FR) approach to compute the diffusion term....
LibUtilities::SessionReaderSharedPtr m_session
Array< OneD, Array< OneD, NekDouble > > m_homoDerivs
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_BD1
Array< OneD, Array< OneD, NekDouble > > m_dGR_xi1
void NumericalFluxO2(const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const Array< OneD, Array< OneD, NekDouble > > &ufield, Array< OneD, Array< OneD, Array< OneD, NekDouble > > > &qfield, Array< OneD, Array< OneD, NekDouble > > &qflux)
Build the numerical flux for the 2nd order derivatives.
static DiffusionSharedPtr create(std::string diffType)
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_DU1
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_DD1
void WeakPenaltyO2(const Array< OneD, MultiRegions::ExpListSharedPtr > &fields, const int var, const int dir, const Array< OneD, const NekDouble > &qfield, Array< OneD, NekDouble > &penaltyflux)
Imposes appropriate bcs for the 2nd order derivatives.
virtual void v_InitObject(LibUtilities::SessionReaderSharedPtr pSession, Array< OneD, MultiRegions::ExpListSharedPtr > pFields) override
Initiliase DiffusionLFRNS objects and store them before starting the time-stepping.
Array< OneD, Array< OneD, NekDouble > > m_dGL_xi1
std::string m_ViscosityType
std::shared_ptr< Basis > BasisSharedPtr
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::vector< PointsKey > PointsKeyVector
@ eGaussGaussLegendre
1D Gauss-Gauss-Legendre quadrature points
DiffusionFactory & GetDiffusionFactory()
@ eDeformed
Geometry is curved or has non-constant factors.
The above copyright notice and this permission notice shall be included.
void jacobd(const int np, const double *z, double *polyd, const int n, const double alpha, const double beta)
Calculate the derivative of Jacobi polynomials.
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
void Neg(int n, T *x, const int incx)
Negate x = -x.
void Vvtvp(int n, const T *w, const int incw, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
vvtvp (vector times vector plus vector): z = w*x + y
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
void Vdiv(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x/y.
void Zero(int n, T *x, const int incx)
Zero vector.
void Reverse(int n, const T *x, const int incx, T *y, const int incy)
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
void Vsub(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Subtract vector z = x-y.