35#include <boost/algorithm/string.hpp>
76 int expdim =
m_graph->GetMeshDimension();
86 ASSERTL0(
false,
"Last field is defined as pressure but this is not "
87 "suitable for this solver, please remove this field as "
88 "it is implicitly defined");
98 "components of velocity variables");
100 m_fields[0]->GetHomogeneousBasis()->GetBasisKey();
107 "Non binary number of planes have been specified");
131 "For single mode calculation can only have nz <= 2");
132 if (
m_session->DefinesSolverInfo(
"BetaZero"))
162 for (i = 2; i < nz; ++i)
169 else if (expdim == 3)
173 ASSERTL0(
false,
"Setup mapping aray");
177 ASSERTL0(
false,
"Exp dimension not recognised");
183 std::string vExtrapolation =
"Standard";
185 if (
m_session->DefinesSolverInfo(
"Extrapolation"))
187 vExtrapolation =
m_session->GetSolverInfo(
"Extrapolation");
204 bool IsLinearNSEquation)
216 m_session->LoadParameter(
"imagShift", lambda_imag,
222 "single mode linear NS solver");
256 for (n = 1; n < nz; ++n)
406 bool IsLinearNSEquation,
const int HomogeneousMode,
416 bool AddAdvectionTerms =
457 for (n = 0; n < nel; ++n)
459 nsize_bndry[n] = nvel *
462 nsize_bndry_p1[n] = nsize_bndry[n] + nz_loc;
466 nsize_p[n] =
m_pressure->GetExp(n)->GetNcoeffs() * nz_loc;
467 nsize_p_m1[n] = nsize_p[n] - nz_loc;
473 nsize_bndry_p1, nsize_bndry_p1, blkmatStorage);
475 nsize_bndry, nsize_int, blkmatStorage);
477 nsize_bndry, nsize_int, blkmatStorage);
479 nsize_int, nsize_int, blkmatStorage);
482 nsize_p, nsize_bndry, blkmatStorage);
485 nsize_p, nsize_int, blkmatStorage);
490 nsize_bndry_p1, nsize_p_m1, blkmatStorage);
493 nsize_p_m1, nsize_bndry_p1, blkmatStorage);
501 for (n = 0; n < nel; ++n)
503 nbndry = nsize_bndry[n];
505 k = nsize_bndry_p1[n];
521 nsize_p[n], nsize_bndry[n], zero);
523 nsize_p[n], nsize_int[n], zero);
526 locExp->GetBoundaryMap(bmap);
527 locExp->GetInteriorMap(imap);
535 size_t nbmap = bmap.size();
536 size_t nimap = imap.size();
540 size_t psize =
m_pressure->GetExp(n)->GetNcoeffs();
541 size_t pqsize =
m_pressure->GetExp(n)->GetTotPoints();
546 if (AddAdvectionTerms ==
false)
552 CondMat = locExp->GetLocStaticCondMatrix(helmkey);
554 for (k = 0; k < nvel * nz_loc; ++k)
557 rows = SubBlock.GetRows();
558 cols = SubBlock.GetColumns();
559 for (i = 0; i < rows; ++i)
561 for (j = 0; j < cols; ++j)
563 (*Ah)(i + k * rows, j + k * cols) =
569 for (k = 0; k < nvel * nz_loc; ++k)
573 rows = SubBlock.GetRows();
574 cols = SubBlock.GetColumns();
575 for (i = 0; i < rows; ++i)
577 for (j = 0; j < cols; ++j)
579 (*B)(i + k * rows, j + k * cols) = SubBlock(i, j);
580 (*C)(i + k * rows, j + k * cols) =
586 for (k = 0; k < nvel * nz_loc; ++k)
590 rows = SubBlock.GetRows();
591 cols = SubBlock.GetColumns();
592 for (i = 0; i < rows; ++i)
594 for (j = 0; j < cols; ++j)
596 (*D)(i + k * rows, j + k * cols) =
597 inv_kinvis * SubBlock(i, j);
603 for (i = 0; i < bmap.size(); ++i)
607 coeffs[bmap[i]] = 1.0;
611 for (j = 0; j < nvel; ++j)
613 if ((nz_loc == 2) && (j == 2))
619 beta, phys, 1, deriv, 1);
621 m_pressure->GetExp(n)->IProductWRTBase(deriv, pcoeffs);
625 ((nz_loc * j + 1) * bmap.size() + i) *
632 ((nz_loc * j) * bmap.size() + i) *
647 for (k = 0; k < nz_loc; ++k)
650 psize, &(pcoeffs)[0], 1,
652 ((nz_loc * j + k) * bmap.size() + i) *
662 for (i = 0; i < imap.size(); ++i)
666 coeffs[imap[i]] = 1.0;
670 for (j = 0; j < nvel; ++j)
672 if ((nz_loc == 2) && (j == 2))
678 beta, phys, 1, deriv, 1);
680 m_pressure->GetExp(n)->IProductWRTBase(deriv, pcoeffs);
684 ((nz_loc * j + 1) * imap.size() + i) *
691 ((nz_loc * j) * imap.size() + i) *
710 for (k = 0; k < nz_loc; ++k)
713 psize, &(pcoeffs)[0], 1,
715 ((nz_loc * j + k) * imap.size() + i) *
736 HelmMat.GetOwnedMatrix()->GetPtr();
737 NekDouble HelmMatScale = HelmMat.Scale();
738 int HelmMatRows = HelmMat.GetRows();
754 int npoints = locExp->GetTotPoints();
757 if (IsLinearNSEquation)
762 for (nv = 0; nv < nvel; ++nv)
764 for (nv1 = 0; nv1 < nvel; ++nv1)
766 if (cnt < nvel * nvel - 1)
768 AdvDeriv[cnt + 1] = AdvDeriv[cnt] + npoints;
781 Advfield[nv] + phys_offset,
782 AdvDeriv[nv * nvel + nv1]);
788 for (i = 0; i < nbmap; ++i)
793 coeffs[bmap[i]] = 1.0;
794 locExp->BwdTrans(coeffs, phys);
796 for (k = 0; k < nvel * nz_loc; ++k)
798 for (j = 0; j < nbmap; ++j)
803 Ah_data[i + k * nbmap + (j + k * nbmap) * AhRows] +=
805 HelmMat_data[bmap[i] + HelmMatRows * bmap[j]];
808 for (j = 0; j < nimap; ++j)
810 B_data[i + k * nbmap + (j + k * nimap) * nbndry] +=
812 HelmMat_data[bmap[i] + HelmMatRows * imap[j]];
819 for (k = 0; k < nvel; ++k)
821 for (j = 0; j < nbmap; ++j)
823 Ah_data[i + 2 * k * nbmap +
824 (j + (2 * k + 1) * nbmap) * AhRows] -=
825 lambda_imag * (*MassMat)(bmap[i], bmap[j]);
828 for (j = 0; j < nbmap; ++j)
830 Ah_data[i + (2 * k + 1) * nbmap +
831 (j + 2 * k * nbmap) * AhRows] +=
832 lambda_imag * (*MassMat)(bmap[i], bmap[j]);
835 for (j = 0; j < nimap; ++j)
837 B_data[i + 2 * k * nbmap +
838 (j + (2 * k + 1) * nimap) * nbndry] -=
839 lambda_imag * (*MassMat)(bmap[i], imap[j]);
842 for (j = 0; j < nimap; ++j)
844 B_data[i + (2 * k + 1) * nbmap +
845 (j + 2 * k * nimap) * nbndry] +=
846 lambda_imag * (*MassMat)(bmap[i], imap[j]);
851 for (k = 0; k < nvel; ++k)
853 if ((nz_loc == 2) && (k == 2))
860 m_pressure->GetExp(n)->IProductWRTBase(deriv, pcoeffs);
863 ((nz_loc * k + 1) * bmap.size() + i) *
871 ((nz_loc * k) * bmap.size() + i) *
877 Vmath::Vmul(npoints, Advtmp = Advfield[k] + phys_offset,
878 1, deriv, 1, tmpphys, 1);
880 locExp->IProductWRTBase(tmpphys, coeffs);
883 for (nv = 0; nv < nvel; ++nv)
885 for (j = 0; j < nbmap; ++j)
887 Ah_data[j + 2 * nv * nbmap +
888 (i + (2 * nv + 1) * nbmap) * AhRows] +=
892 for (j = 0; j < nimap; ++j)
894 C_data[i + (2 * nv + 1) * nbmap +
895 (j + 2 * nv * nimap) * nbndry] +=
902 for (nv = 0; nv < nvel; ++nv)
904 for (j = 0; j < nbmap; ++j)
906 Ah_data[j + (2 * nv + 1) * nbmap +
907 (i + 2 * nv * nbmap) * AhRows] +=
911 for (j = 0; j < nimap; ++j)
913 C_data[i + 2 * nv * nbmap +
914 (j + (2 * nv + 1) * nimap) * nbndry] +=
926 Advtmp = Advfield[k] + phys_offset, 1,
927 deriv, 1, tmpphys, 1);
928 locExp->IProductWRTBase(tmpphys, coeffs);
930 for (nv = 0; nv < nvel * nz_loc; ++nv)
932 for (j = 0; j < nbmap; ++j)
934 Ah_data[j + nv * nbmap +
935 (i + nv * nbmap) * AhRows] +=
939 for (j = 0; j < nimap; ++j)
941 C_data[i + nv * nbmap +
942 (j + nv * nimap) * nbndry] +=
950 for (j = 0; j < nz_loc; ++j)
953 psize, &(pcoeffs)[0], 1,
955 ((nz_loc * k + j) * bmap.size() + i) *
963 if (IsLinearNSEquation)
965 for (nv = 0; nv < nvel; ++nv)
969 AdvDeriv[k * nvel + nv], 1, tmpphys, 1);
970 locExp->IProductWRTBase(tmpphys, coeffs);
972 for (
size_t n1 = 0; n1 < nz_loc; ++n1)
974 for (j = 0; j < nbmap; ++j)
976 Ah_data[j + (k * nz_loc + n1) * nbmap +
977 (i + (nv * nz_loc + n1) * nbmap) *
978 AhRows] += coeffs[bmap[j]];
981 for (j = 0; j < nimap; ++j)
983 C_data[i + (nv * nz_loc + n1) * nbmap +
984 (j + (k * nz_loc + n1) * nimap) *
985 nbndry] += coeffs[imap[j]];
993 for (i = 0; i < nimap; ++i)
997 coeffs[imap[i]] = 1.0;
998 locExp->BwdTrans(coeffs, phys);
1000 for (k = 0; k < nvel * nz_loc; ++k)
1002 for (j = 0; j < nbmap; ++j)
1004 C_data[j + k * nbmap + (i + k * nimap) * nbndry] +=
1006 HelmMat_data[imap[i] + HelmMatRows * bmap[j]];
1009 for (j = 0; j < nimap; ++j)
1011 D_data[i + k * nimap + (j + k * nimap) * nint] +=
1013 HelmMat_data[imap[i] + HelmMatRows * imap[j]];
1020 for (k = 0; k < nvel; ++k)
1022 for (j = 0; j < nbmap; ++j)
1024 C_data[j + 2 * k * nbmap +
1025 (i + (2 * k + 1) * nimap) * nbndry] +=
1026 lambda_imag * (*MassMat)(bmap[j], imap[i]);
1029 for (j = 0; j < nbmap; ++j)
1031 C_data[j + (2 * k + 1) * nbmap +
1032 (i + 2 * k * nimap) * nbndry] -=
1033 lambda_imag * (*MassMat)(bmap[j], imap[i]);
1036 for (j = 0; j < nimap; ++j)
1038 D_data[i + 2 * k * nimap +
1039 (j + (2 * k + 1) * nimap) * nint] -=
1040 lambda_imag * (*MassMat)(imap[i], imap[j]);
1043 for (j = 0; j < nimap; ++j)
1045 D_data[i + (2 * k + 1) * nimap +
1046 (j + 2 * k * nimap) * nint] +=
1047 lambda_imag * (*MassMat)(imap[i], imap[j]);
1052 for (k = 0; k < nvel; ++k)
1054 if ((nz_loc == 2) && (k == 2))
1060 m_pressure->GetExp(n)->IProductWRTBase(deriv, pcoeffs);
1063 ((nz_loc * k + 1) * imap.size() + i) *
1070 ((nz_loc * k) * imap.size() + i) *
1077 Vmath::Vmul(npoints, Advtmp = Advfield[k] + phys_offset,
1078 1, deriv, 1, tmpphys, 1);
1079 locExp->IProductWRTBase(tmpphys, coeffs);
1082 for (nv = 0; nv < nvel; ++nv)
1084 for (j = 0; j < nbmap; ++j)
1086 B_data[j + 2 * nv * nbmap +
1087 (i + (2 * nv + 1) * nimap) * nbndry] +=
1091 for (j = 0; j < nimap; ++j)
1093 D_data[j + 2 * nv * nimap +
1094 (i + (2 * nv + 1) * nimap) * nint] +=
1100 for (nv = 0; nv < nvel; ++nv)
1102 for (j = 0; j < nbmap; ++j)
1104 B_data[j + (2 * nv + 1) * nbmap +
1105 (i + 2 * nv * nimap) * nbndry] +=
1109 for (j = 0; j < nimap; ++j)
1111 D_data[j + (2 * nv + 1) * nimap +
1112 (i + 2 * nv * nimap) * nint] +=
1126 Advtmp = Advfield[k] + phys_offset, 1,
1127 deriv, 1, tmpphys, 1);
1128 locExp->IProductWRTBase(tmpphys, coeffs);
1130 for (nv = 0; nv < nvel * nz_loc; ++nv)
1132 for (j = 0; j < nbmap; ++j)
1134 B_data[j + nv * nbmap +
1135 (i + nv * nimap) * nbndry] +=
1139 for (j = 0; j < nimap; ++j)
1141 D_data[j + nv * nimap +
1142 (i + nv * nimap) * nint] +=
1147 m_pressure->GetExp(n)->IProductWRTBase(deriv,
1149 for (j = 0; j < nz_loc; ++j)
1152 psize, &(pcoeffs)[0], 1,
1154 ((nz_loc * k + j) * imap.size() + i) *
1162 if (IsLinearNSEquation)
1165 for (nv = 0; nv < nvel; ++nv)
1169 AdvDeriv[k * nvel + nv], 1, tmpphys, 1);
1170 locExp->IProductWRTBase(tmpphys, coeffs);
1172 for (n1 = 0; n1 < nz_loc; ++n1)
1174 for (j = 0; j < nbmap; ++j)
1176 B_data[j + (k * nz_loc + n1) * nbmap +
1177 (i + (nv * nz_loc + n1) * nimap) *
1178 nbndry] += coeffs[bmap[j]];
1181 for (j = 0; j < nimap; ++j)
1183 D_data[j + (k * nz_loc + n1) * nimap +
1184 (i + (nv * nz_loc + n1) * nimap) *
1185 nint] += coeffs[imap[j]];
1199 Blas::Dgemm(
'N',
'T', B->GetRows(), C->GetRows(), B->GetColumns(),
1200 -1.0, B->GetRawPtr(), B->GetRows(), C->GetRawPtr(),
1201 C->GetRows(), 1.0, Ah->GetRawPtr(), Ah->GetRows());
1224 DNekMat DintCinvDTint, BCinvDTint_m_DTbnd, DintCinvBTtilde_m_Dbnd;
1230 DintCinvDTint = (*Dint) * (*Cinv) *
Transpose(*Dint);
1234 DintCinvBTtilde_m_Dbnd =
1235 (*Dint) * (*Cinv) *
Transpose(*Btilde) - (*Dbnd);
1239 nsize_bndry_p1[n], nsize_p_m1[n], zero);
1241 nsize_p_m1[n], nsize_bndry_p1[n], zero);
1243 nsize_p_m1[n], nsize_p_m1[n], zero);
1248 for (n1 = 0; n1 < nz_loc; ++n1)
1250 for (i = 0; i < psize - 1; ++i)
1252 for (n2 = 0; n2 < nz_loc; ++n2)
1254 for (j = 0; j < psize - 1; ++j)
1258 Dh_data[(i + n1 * (psize - 1)) +
1259 (j + n2 * (psize - 1)) * Dh->GetRows()] =
1260 -DintCinvDTint(i + 1 + n1 * psize,
1261 j + 1 + n2 * psize);
1267 for (n1 = 0; n1 < nz_loc; ++n1)
1269 for (i = 0; i < nsize_bndry_p1[n] - nz_loc; ++i)
1271 (*Ah)(i, nsize_bndry_p1[n] - nz_loc + n1) =
1272 BCinvDTint_m_DTbnd(i, n1 * psize);
1273 (*Ah)(nsize_bndry_p1[n] - nz_loc + n1, i) =
1274 DintCinvBTtilde_m_Dbnd(n1 * psize, i);
1278 for (n1 = 0; n1 < nz_loc; ++n1)
1280 for (n2 = 0; n2 < nz_loc; ++n2)
1282 (*Ah)(nsize_bndry_p1[n] - nz_loc + n1,
1283 nsize_bndry_p1[n] - nz_loc + n2) =
1284 -DintCinvDTint(n1 * psize, n2 * psize);
1288 for (n1 = 0; n1 < nz_loc; ++n1)
1290 for (j = 0; j < psize - 1; ++j)
1292 for (i = 0; i < nsize_bndry_p1[n] - nz_loc; ++i)
1294 (*Bh)(i, j + n1 * (psize - 1)) =
1295 BCinvDTint_m_DTbnd(i, j + 1 + n1 * psize);
1296 (*Ch)(j + n1 * (psize - 1), i) =
1297 DintCinvBTtilde_m_Dbnd(j + 1 + n1 * psize, i);
1302 for (n1 = 0; n1 < nz_loc; ++n1)
1304 for (n2 = 0; n2 < nz_loc; ++n2)
1306 for (j = 0; j < psize - 1; ++j)
1308 (*Bh)(nsize_bndry_p1[n] - nz_loc + n1,
1309 j + n2 * (psize - 1)) =
1310 -DintCinvDTint(n1 * psize, j + 1 + n2 * psize);
1311 (*Ch)(j + n2 * (psize - 1),
1312 nsize_bndry_p1[n] - nz_loc + n1) =
1313 -DintCinvDTint(j + 1 + n2 * psize, n1 * psize);
1320 (*Bh) = (*Bh) * (*Dh);
1322 Blas::Dgemm(
'N',
'N', Bh->GetRows(), Ch->GetColumns(), Bh->GetColumns(),
1323 -1.0, Bh->GetRawPtr(), Bh->GetRows(), Ch->GetRawPtr(),
1324 Ch->GetRows(), 1.0, Ah->GetRawPtr(), Ah->GetRows());
1342 cout <<
"Matrix Setup Costs: " << timer.
TimePerTest(1) << endl;
1409 for (
size_t i = 0; i <
m_velocity.size(); ++i)
1416 "Advection Velocity section must be defined in "
1419 std::vector<std::string> fieldStr;
1420 for (
size_t i = 0; i <
m_velocity.size(); ++i)
1425 GetFunction(
"AdvectionVelocity")->Evaluate(fieldStr, AdvField);
1444 "Restart section must be defined in session file.");
1447 for (
size_t i = 0; i <
m_velocity.size(); ++i)
1452 std::vector<std::string> fieldStr;
1453 for (
size_t i = 0; i <
m_velocity.size(); ++i)
1458 GetFunction(
"Restart")->Evaluate(fieldStr, Restart);
1460 for (
size_t i = 0; i <
m_velocity.size(); ++i)
1465 cout <<
"Saving the RESTART file for m_kinvis = " <<
m_kinvis
1466 <<
" (<=> Re = " << 1 /
m_kinvis <<
")" << endl;
1477 cout <<
"Saving the Stokes Flow for m_kinvis = " <<
m_kinvis
1478 <<
" (<=> Re = " << 1 /
m_kinvis <<
")" << endl;
1487 for (
size_t i = 0; i <
m_velocity.size(); ++i)
1494 "Advection Velocity section must be defined in "
1497 std::vector<std::string> fieldStr;
1498 for (
size_t i = 0; i <
m_velocity.size(); ++i)
1503 GetFunction(
"AdvectionVelocity")->Evaluate(fieldStr, AdvField);
1511 "Unknown or undefined equation type for CoupledLinearNS");
1524 x->Apply(
m_fields, outarray, outarray, time);
1539 if (fabs(lambda_store - lambda) > 1e-10)
1542 lambda_store = lambda;
1571 for (
size_t k = 0; k < nfields; ++k)
1582 for (
size_t k = 0; k < nfields; ++k)
1609 Generaltimer.
Start();
1617 cout <<
"We execute INITIALLY SolveSteadyNavierStokes for m_kinvis "
1626 cout <<
"We execute SolveSteadyNavierStokes for m_kinvis = "
1638 cout <<
"We execute SolveSteadyNavierStokes for m_kinvis = "
1647 Generaltimer.
Stop();
1648 cout <<
"\nThe total calculation time is : "
1649 << Generaltimer.
TimePerTest(1) / 60 <<
" minute(s). \n\n";
1656 "Unknown or undefined equation type for CoupledLinearNS");
1676 for (
size_t i = 0; i < ncmpt; ++i)
1687 x->Apply(
m_fields, forcing_phys, forcing_phys, time);
1689 for (
size_t i = 0; i < ncmpt; ++i)
1693 m_fields[i]->IProductWRTBase(forcing_phys[i], forcing[i]);
1694 m_fields[i]->SetWaveSpace(waveSpace);
1706 for (
size_t i = 0; i <
m_velocity.size(); ++i)
1714 if (
m_session->DefinesFunction(
"ForcingTerm"))
1716 std::vector<std::string> fieldStr;
1717 for (
size_t i = 0; i <
m_velocity.size(); ++i)
1723 for (
size_t i = 0; i <
m_velocity.size(); ++i)
1731 cout <<
"'ForcingTerm' section has not been defined in the input file "
1740 Newtontimer.
Start();
1749 for (
size_t i = 0; i <
m_velocity.size(); ++i)
1759 L2Norm(delta_velocity_Phys, L2_norm);
1762 while (max(L2_norm[0], L2_norm[1]) >
m_tol)
1770 for (
size_t i = 0; i <
m_velocity.size(); ++i)
1778 for (
size_t i = 0; i <
m_velocity.size(); ++i)
1803 for (
size_t i = 0; i <
m_velocity.size(); ++i)
1810 for (
size_t i = 0; i <
m_velocity.size(); ++i)
1812 Vmath::Vadd(Velocity_Phys[i].size(), Velocity_Phys[i], 1,
1813 delta_velocity_Phys[i], 1, Velocity_Phys[i], 1);
1817 L2Norm(delta_velocity_Phys, L2_norm);
1819 if (max(Inf_norm[0], Inf_norm[1]) > 100)
1821 cout <<
"\nThe Newton method has failed at m_kinvis = " <<
m_kinvis
1822 <<
" (<=> Re = " << 1 /
m_kinvis <<
")" << endl;
1823 ASSERTL0(0,
"The Newton method has failed... \n");
1832 for (
size_t i = 0; i <
m_velocity.size(); ++i)
1840 cout <<
"We have done " <<
m_counter - 1 <<
" iteration(s) in "
1841 << Newtontimer.
TimePerTest(1) / 60 <<
" minute(s). \n\n";
1851 cout <<
"We apply the continuation method: " << endl;
1853 for (
size_t i = 0; i <
m_velocity.size(); ++i)
1877 for (
size_t i = 0; i <
m_velocity.size(); ++i)
1886 Vmath::Vadd(u_star[i].size(), u_star[i], 1, u_N[i], 1, u_star[i], 1);
1898 for (
size_t i = 0; i <
m_velocity.size(); ++i)
1901 for (
size_t j = 0; j < inarray[i].size(); ++j)
1903 if (inarray[i][j] > outarray[i])
1905 outarray[i] = inarray[i][j];
1908 cout <<
"InfNorm[" << i <<
"] = " << outarray[i] << endl;
1915 for (
size_t i = 0; i <
m_velocity.size(); ++i)
1918 for (
size_t j = 0; j < inarray[i].size(); ++j)
1920 outarray[i] += inarray[i][j] * inarray[i][j];
1922 outarray[i] =
sqrt(outarray[i]);
1923 cout <<
"L2Norm[" << i <<
"] = " << outarray[i] << endl;
1937 for (
size_t i = 0; i <
m_velocity.size(); ++i)
1961 for (
size_t i = 0; i <
m_velocity.size(); ++i)
1968 i, tmp_DerVel[i], ViscTerm[i]);
1973 Vmath::Vsub(outarray[i].size(), outarray[i], 1, AdvTerm[i], 1,
1975 Vmath::Vsub(outarray[i].size(), outarray[i], 1, ViscTerm[i], 1,
1978 Vmath::Vadd(outarray[i].size(), outarray[i], 1, Forc[i], 1, outarray[i],
1992 for (
auto &expMapIter : VelExp)
1996 for (
size_t i = 0; i < expMapIter.second->m_basisKeyVector.size(); ++i)
2001 "Velocity polynomial space not sufficiently high (>= 4)");
2005 BasisVec.push_back(newB);
2011 expMapIter.second->m_geomShPtr, BasisVec);
2012 (*returnval)[expMapIter.first] = expansionElementShPtr;
2016 m_graph->SetExpansionInfo(
"p", returnval);
2109 force[i] = forcing[i] + 2 * n * ncoeffsplane;
2126 force[i] = forcing[i];
2137 size_t i, j, k, n, cnt, cnt1;
2138 size_t nbnd, nint, offset;
2140 size_t nel = fields[0]->GetNumElmts();
2170 for (i = 0; i < fields.size(); ++i)
2173 tmp = fields[i]->UpdateCoeffs() + nplanecoeffs,
2182 for (k = 0; k < nvel; ++k)
2185 std::dynamic_pointer_cast<MultiRegions::ContField>(fields[k]);
2188 cfield->GetLocalToGlobalMap()->GetBndCondCoeffsToLocalCoeffsSign();
2190 cfield->GetLocalToGlobalMap()->GetBndCondCoeffsToLocalCoeffsMap();
2194 fields[k]->GetBndConditions();
2200 m_fields[k]->GetPlane(2 * mode)->GetBndCondExpansions();
2204 bndCondExp =
m_fields[k]->GetBndCondExpansions();
2207 for (n = 0; n < nz_loc; ++n)
2210 for (i = 0; i < bndCondExp.size(); ++i)
2213 bndCondExp[i]->GetCoeffs();
2214 size_t nCoeffs = (bndCondExp[i])->
GetNcoeffs();
2217 if (bndConds[i]->GetBoundaryConditionType() ==
2219 bndConds[i]->GetBoundaryConditionType() ==
2224 for (j = 0; j < nCoeffs; j++)
2226 forcing[k][n * nplanecoeffs + map[bndcnt + j]] +=
2227 sign[bndcnt + j] * bndcoeffs[j];
2232 for (j = 0; j < nCoeffs; j++)
2234 forcing[k][n * nplanecoeffs + map[bndcnt + j]] +=
2240 bndcnt += bndCondExp[i]->GetNcoeffs();
2251 for (i = 0; i < nel; ++i)
2253 fields[
m_velocity[0]]->GetExp(i)->GetBoundaryMap(bmap);
2254 fields[
m_velocity[0]]->GetExp(i)->GetInteriorMap(imap);
2257 offset = fields[
m_velocity[0]]->GetCoeff_Offset(i);
2259 for (j = 0; j < nvel; ++j)
2263 for (n = 0; n < nz_loc; ++n)
2265 for (k = 0; k < nbnd; ++k)
2268 forcing[j][n * nplanecoeffs + offset + bmap[k]];
2270 bnd[bndoffset + (n + j * nz_loc) * nbnd + k] =
2271 incoeffs[n * nplanecoeffs + offset + bmap[k]];
2273 for (k = 0; k < nint; ++k)
2276 forcing[j][n * nplanecoeffs + offset + imap[k]];
2284 nvel * nz_loc * nbnd + nz_loc * (
pressure->GetExp(i)->GetNcoeffs());
2292 F_bnd = F_bnd - (*
m_mat[mode].m_BCinv) * F_int;
2293 F_p_tmp = (*
m_mat[mode].m_Cinv) * F_int;
2294 F_p = (*
m_mat[mode].m_D_int) * F_p_tmp;
2301 for (i = 0; i < nel; ++i)
2303 nbnd = nz_loc * fields[0]->GetExp(i)->NumBndryCoeffs();
2305 for (j = 0; j < nvel; ++j)
2307 for (k = 0; k < nbnd; ++k)
2309 fh_bnd[offset + j * nbnd + k] = f_bnd[cnt + k];
2314 nint =
pressure->GetExp(i)->GetNcoeffs();
2315 offset += nvel * nbnd + nint * nz_loc;
2319 for (i = 0; i < nel; ++i)
2321 nbnd = nz_loc * fields[0]->GetExp(i)->NumBndryCoeffs();
2322 nint =
pressure->GetExp(i)->GetNcoeffs();
2324 for (n = 0; n < nz_loc; ++n)
2326 for (j = 0; j < nint; ++j)
2328 fh_bnd[offset + nvel * nbnd + n * nint + j] = f_p[cnt1 + j];
2332 offset += nvel * nbnd + nz_loc * nint;
2338 int totpcoeffs =
pressure->GetNcoeffs();
2340 for (i = 0; i < nel; ++i)
2342 nbnd = nz_loc * fields[0]->GetExp(i)->NumBndryCoeffs();
2343 nint =
pressure->GetExp(i)->GetNcoeffs();
2344 for (j = 0; j < nvel; ++j)
2346 for (k = 0; k < nbnd; ++k)
2348 f_bnd[cnt + k] = bnd[offset + j * nbnd + k];
2352 offset += nvel * nbnd + nint * nz_loc;
2357 offset = cnt = cnt1 = 0;
2358 for (i = 0; i < nel; ++i)
2360 nint =
pressure->GetExp(i)->GetNcoeffs();
2361 nbnd = fields[0]->GetExp(i)->NumBndryCoeffs();
2362 cnt1 =
pressure->GetCoeff_Offset(i);
2364 for (n = 0; n < nz_loc; ++n)
2366 for (j = 0; j < nint; ++j)
2368 p_coeffs[n * totpcoeffs + cnt1 + j] = f_p[cnt + j] =
2369 bnd[offset + nvel * nz_loc * nbnd + n * nint + j];
2373 offset += (nvel * nbnd + nint) * nz_loc;
2380 F_int = (*
m_mat[mode].m_Cinv) * F_int;
2384 for (i = 0; i < nel; ++i)
2386 fields[0]->GetExp(i)->GetBoundaryMap(bmap);
2387 fields[0]->GetExp(i)->GetInteriorMap(imap);
2390 offset = fields[0]->GetCoeff_Offset(i);
2392 for (j = 0; j < nvel; ++j)
2394 for (n = 0; n < nz_loc; ++n)
2396 for (k = 0; k < nbnd; ++k)
2398 fields[j]->SetCoeff(n * nplanecoeffs + offset + bmap[k],
2402 for (k = 0; k < nint; ++k)
2404 fields[j]->SetCoeff(n * nplanecoeffs + offset + imap[k],
2413 for (j = 0; j < nvel; ++j)
2415 fields[j]->SetPhysState(
false);
2421 std::vector<Array<OneD, NekDouble>> fieldcoeffs(
m_fields.size() + 1);
2422 std::vector<std::string> variables(
m_fields.size() + 1);
2425 for (i = 0; i <
m_fields.size(); ++i)
2427 fieldcoeffs[i] =
m_fields[i]->UpdateCoeffs();
2442 m_fields[0]->GetPlane(0)->FwdTransLocalElmt(
2443 m_pressure->GetPlane(0)->GetPhys(), fieldcoeffs[i]);
2444 m_fields[0]->GetPlane(1)->FwdTransLocalElmt(
2445 m_pressure->GetPlane(1)->GetPhys(), tmpfieldcoeffs);
2446 for (
int e = 0; e <
m_fields[0]->GetNcoeffs() / 2; e++)
2448 fieldcoeffs[i][e +
m_fields[0]->GetNcoeffs() / 2] =
2459 if (!
m_comm->IsParallelInTime())
2466 if (!fs::is_directory(newdir))
2468 fs::create_directory(newdir);
2473 m_comm->GetTimeComm()->GetRank() + 1) +
2475 m_fields[0], fieldcoeffs, variables);
2481 return m_session->GetVariables().size();
#define ASSERTL0(condition, msg)
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
#define sign(a, b)
return the sign(b)*a
void L2Norm(Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, NekDouble > &outarray)
CoupledLinearNS(const LibUtilities::SessionReaderSharedPtr &pSesssion, const SpatialDomains::MeshGraphSharedPtr &pGraph)
void v_GenerateSummary(SolverUtils::SummaryList &s) override
Print a summary of time stepping parameters.
void EvaluateNewtonRHS(Array< OneD, Array< OneD, NekDouble > > &Velocity, Array< OneD, Array< OneD, NekDouble > > &outarray)
void v_DoSolve(void) override
Solves an unsteady problem.
Array< OneD, CoupledLocalToGlobalC0ContMapSharedPtr > m_locToGloMap
void DefineForcingTerm(void)
void SolveUnsteadyStokesSystem(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time, const NekDouble a_iixDt)
void SolveLinearNS(const Array< OneD, Array< OneD, NekDouble > > &forcing)
void v_Output(void) override
void SolveSteadyNavierStokes(void)
void v_DoInitialise(bool dumpInitialConditions=true) override
Sets up initial conditions.
const SpatialDomains::ExpansionInfoMap & GenPressureExp(const SpatialDomains::ExpansionInfoMap &VelExp)
bool v_NegatedOp(void) override
void EvaluateAdvection(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time)
static SolverUtils::EquationSystemSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
Creates an instance of this class.
void v_InitObject(bool DeclareField=true) override
Initialisation object for EquationSystem.
static std::string className
Name of class.
bool m_zeroMode
Id to identify when single mode is mean mode (i.e. beta=0);.
Array< OneD, Array< OneD, NekDouble > > m_ForcingTerm_Coeffs
Array< OneD, Array< OneD, NekDouble > > m_ForcingTerm
void v_TransPhysToCoeff(void) override
Virtual function for transformation to coefficient space.
void SetUpCoupledMatrix(const NekDouble lambda=0.0, const Array< OneD, Array< OneD, NekDouble > > &Advfield=NullNekDoubleArrayOfArray, bool IsLinearNSEquation=true)
int v_GetForceDimension(void) override
NekDouble m_KinvisPercentage
void InfNorm(Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, NekDouble > &outarray)
void v_TransCoeffToPhys(void) override
Virtual function for transformation to physical space.
Array< OneD, CoupledSolverMatrices > m_mat
static std::string solverTypeLookupId
This class is the base class for Navier Stokes problems.
MultiRegions::ExpListSharedPtr m_pressure
Pointer to field holding pressure field.
NekDouble m_kinvis
Kinematic viscosity.
void v_InitObject(bool DeclareField=true) override
Initialisation object for EquationSystem.
ExtrapolateSharedPtr m_extrapolation
Array< OneD, int > m_velocity
int which identifies which components of m_fields contains the velocity (u,v,w);
EquationType m_equationType
equation type;
int m_nConvectiveFields
Number of fields to be convected;.
std::vector< SolverUtils::ForcingSharedPtr > m_forcing
Forcing terms.
void EvaluateAdvectionTerms(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray, const NekDouble time)
Describes the specification for a Basis.
BasisType GetBasisType() const
Return type of expansion basis.
PointsKey GetPointsKey() const
Return distribution of points.
int GetNumModes() const
Returns the order of the basis.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
static std::string RegisterEnumValue(std::string pEnum, std::string pString, int pEnumValue)
Registers an enumeration value.
void DefineOdeRhs(FuncPointerT func, ObjectPointerT obj)
void DefineImplicitSolve(FuncPointerT func, ObjectPointerT obj)
NekDouble TimePerTest(unsigned int n)
Returns amount of seconds per iteration in a test with n iterations.
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
Describe a linear system.
SolverUtils::AdvectionSharedPtr m_advObject
Advection term.
bool m_useFFT
Flag to determine if FFT is used for homogeneous transform.
SpatialDomains::MeshGraphSharedPtr m_graph
Pointer to graph defining mesh.
LibUtilities::CommSharedPtr m_comm
Communicator.
NekDouble m_time
Current time of simulation.
Array< OneD, MultiRegions::ExpListSharedPtr > m_fields
Array holding all dependent variables.
int m_windowPIT
Index of windows for parallel-in-time time iteration.
NekDouble m_lambda
Lambda constant in real system if one required.
int m_npointsZ
number of points in Z direction (if homogeneous)
SOLVER_UTILS_EXPORT void Checkpoint_Output(const int n)
Write checkpoint file of m_fields.
SOLVER_UTILS_EXPORT void WriteFld(const std::string &outname)
Write field data to the given filename.
std::string m_sessionName
Name of the session.
LibUtilities::SessionReaderSharedPtr m_session
The session reader.
bool m_singleMode
Flag to determine if single homogeneous mode is used.
enum HomogeneousType m_HomogeneousType
SOLVER_UTILS_EXPORT int GetNpoints()
bool m_homogen_dealiasing
Flag to determine if dealiasing is used for homogeneous simulations.
SOLVER_UTILS_EXPORT int GetNcoeffs()
SpatialDomains::BoundaryConditionsSharedPtr m_boundaryConditions
Pointer to boundary conditions object.
NekDouble m_LhomZ
physical length in Z direction (if homogeneous)
SOLVER_UTILS_EXPORT void SetInitialConditions(NekDouble initialtime=0.0, bool dumpInitialConditions=true, const int domain=0)
Initialise the data in the dependent fields.
SOLVER_UTILS_EXPORT SessionFunctionSharedPtr GetFunction(std::string name, const MultiRegions::ExpListSharedPtr &field=MultiRegions::NullExpListSharedPtr, bool cache=false)
Get a SessionFunction by name.
SOLVER_UTILS_EXPORT int GetTotPoints()
Base class for unsteady solvers.
LibUtilities::TimeIntegrationSchemeOperators m_ode
The time integration scheme operators to use.
SOLVER_UTILS_EXPORT void v_DoSolve() override
Solves an unsteady problem.
static void Dcopy(const int &n, const double *x, const int &incx, double *y, const int &incy)
BLAS level 1: Copy x to y.
static void Dgemm(const char &transa, const char &transb, const int &m, const int &n, const int &k, const double &alpha, const double *a, const int &lda, const double *b, const int &ldb, const double &beta, double *c, const int &ldc)
BLAS level 3: Matrix-matrix multiply C = A x B where op(A)[m x k], op(B)[k x n], C[m x n] DGEMM perfo...
std::vector< BasisKey > BasisKeyVector
Name for a vector of BasisKeys.
std::shared_ptr< SessionReader > SessionReaderSharedPtr
@ beta
Gauss Radau pinned at x=-1,.
MultiRegions::Direction const DirCartesianMap[]
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
std::shared_ptr< ContField > ContFieldSharedPtr
static const NekDouble kNekUnsetDouble
std::vector< std::pair< std::string, std::string > > SummaryList
EquationSystemFactory & GetEquationSystemFactory()
void AddSummaryItem(SummaryList &l, const std::string &name, const std::string &value)
Adds a summary item to the summary info list.
std::shared_ptr< ExpansionInfoMap > ExpansionInfoMapShPtr
std::shared_ptr< ExpansionInfo > ExpansionInfoShPtr
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
std::map< int, ExpansionInfoShPtr > ExpansionInfoMap
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
@ eLinearAdvectionReaction
std::map< ConstFactorType, NekDouble > ConstFactorMap
StdRegions::ConstFactorMap factors
std::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
static Array< OneD, Array< OneD, NekDouble > > NullNekDoubleArrayOfArray
std::shared_ptr< DNekScalBlkMat > DNekScalBlkMatSharedPtr
ExtrapolateFactory & GetExtrapolateFactory()
NekMatrix< InnerMatrixType, BlockMatrixTag > Transpose(NekMatrix< InnerMatrixType, BlockMatrixTag > &rhs)
std::shared_ptr< CoupledLocalToGlobalC0ContMap > CoupledLocalToGlobalC0ContMapSharedPtr
std::shared_ptr< DNekMat > DNekMatSharedPtr
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 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 Zero(int n, T *x, const int incx)
Zero vector.
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.
scalarT< T > sqrt(scalarT< T > in)
DNekScalBlkMatSharedPtr m_D_int
Inner product of pressure system with divergence of the interior velocity space .
DNekScalBlkMatSharedPtr m_D_bnd
Inner product of pressure system with divergence of the boundary velocity space .
DNekScalBlkMatSharedPtr m_Cinv
Interior-Interior Laplaican plus linearised convective terms inverted, i.e. the inverse of .
DNekScalBlkMatSharedPtr m_Btilde
Interior-boundary Laplacian plus linearised convective terms .
DNekScalBlkMatSharedPtr m_BCinv
Boundary-interior Laplacian plus linearised convective terms pre-multiplying Cinv: .
MultiRegions::GlobalLinSysSharedPtr m_CoupledBndSys