36#include "viscosityModel.H"
43 _args = autoPtr<argList>
45 new argList(argc, argv)
48 if (!
_args->checkRootCase())
50 Foam::FatalError.exit();
53 argList& args =
_args();
56 _simple = autoPtr<simpleControl>
82 "The BC method must be set to lift or penalty or none in ITHACAdict");
85 "The flux method must be set to inconsistent or consistent in ITHACAdict");
100 volScalarField&
p =
_p();
101 volVectorField&
U =
_U();
102 surfaceScalarField&
phi =
_phi();
105 IOMRFZoneList& MRF =
_MRF();
117 for (label
i = 0;
i < mu_now.size();
i++)
131 "./ITHACAoutput/Offline");
139 || type ==
"snapshots",
140 "You must specify the variable type with either snapshots or modes");
141 PtrList<volScalarField> P_sup;
143 if (type ==
"snapshots")
154 volVectorField
U =
_U();
166 dimensionedVector(
"zero",
U.dimensions(), vector::zero)
169 if (type ==
"snapshots")
180 volVectorField
U =
_U();
192 dimensionedVector(
"zero",
U.dimensions(), vector::zero)
194 dimensionedScalar nu_fake
197 dimensionSet(0, 2, -1, 0, 0, 0, 0),
200 Vector<double>
v(0, 0, 0);
202 for (label
i = 0;
i < Usup.boundaryField().size();
i++)
204 if (Usup.boundaryField()[
i].type() !=
"processor")
212 if (type ==
"snapshots")
214 for (label
i = 0;
i < P_sup.size();
i++)
216 fvVectorMatrix u_sup_eqn
218 - fvm::laplacian(nu_fake, Usup)
222 u_sup_eqn == fvc::grad(P_sup[
i])
232 for (label
i = 0;
i < P_sup.size();
i++)
234 fvVectorMatrix u_sup_eqn
236 - fvm::laplacian(nu_fake, Usup)
240 u_sup_eqn == fvc::grad(P_sup[
i])
257 surfaceScalarField&
phi =
_phi();
259 volScalarField
p =
_p();
260 volVectorField
U =
_U();
261 IOMRFZoneList& MRF =
_MRF();
263 volVectorField Ulift(
"Ulift" + name(k),
U);
264 instantList Times =
runTime.times();
266 pisoControl potentialFlow(
mesh,
"potentialFlow");
267 Info <<
"Solving a lifting Problem" << endl;
268 Vector<double> v1(0, 0, 0);
270 Vector<double>
v0(0, 0, 0);
272 for (label j = 0; j <
U.boundaryField().size(); j++)
278 else if (
U.boundaryField()[BCind].type() ==
"fixedValue")
287 phi = linearInterpolate(Ulift) &
mesh.Sf();
290 Info <<
"Constructing velocity potential field Phi\n" << endl;
298 IOobject::READ_IF_PRESENT,
302 dimensionedScalar(
"Phi", dimLength * dimVelocity, 0),
303 p.boundaryField().types()
305 label PhiRefCell = 0;
306 scalar PhiRefValue = 0;
310 potentialFlow.dict(),
314 mesh.setFluxRequired(Phi.name());
315 runTime.functionObjects().start();
316 MRF.makeRelative(
phi);
319 while (potentialFlow.correctNonOrthogonal())
321 fvScalarMatrix PhiEqn
323 fvm::laplacian(dimensionedScalar(
"1", dimless, 1), Phi)
327 PhiEqn.setReference(PhiRefCell, PhiRefValue);
330 if (potentialFlow.finalNonOrthogonalIter())
332 phi -= PhiEqn.flux();
336 MRF.makeAbsolute(
phi);
337 Info <<
"Continuity error = "
338 << mag(fvc::div(
phi))().weightedAverage(
mesh.V()).value()
340 Ulift = fvc::reconstruct(
phi);
341 Ulift.correctBoundaryConditions();
342 Info <<
"Interpolated velocity error = "
343 << (sqrt(sum(sqr((fvc::interpolate(
U) &
mesh.Sf()) -
phi)))
344 / sum(
mesh.magSf())).value()
362 for (label k = 0; k <
liftfield.size(); k++)
370 for (label k = 0; k <
NUmodes; k++)
378 word B_str =
"B_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
390 word K_str =
"K_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
402 word M_str =
"M_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
414 word D_str =
"D_" + name(
NPmodes);
425 word bc3_str =
"BC3_" + name(
liftfield.size()) +
"_" + name(
437 word bc4_str =
"BC4_" + name(
liftfield.size()) +
"_" + name(
449 word C_str =
"C_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
461 word G_str =
"G_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
505 "./ITHACAoutput/Matrices/");
507 "./ITHACAoutput/Matrices/");
519 "./ITHACAoutput/Matrices/");
521 "./ITHACAoutput/Matrices/");
533 "./ITHACAoutput/Matrices/");
535 "./ITHACAoutput/Matrices/");
537 "./ITHACAoutput/Matrices/C");
539 "./ITHACAoutput/Matrices/G");
552 for (label k = 0; k <
liftfield.size(); k++)
560 for (label k = 0; k <
NUmodes; k++)
576 word B_str =
"B_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
588 word K_str =
"K_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
600 word P_str =
"P_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
612 word M_str =
"M_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
624 word C_str =
"C_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
683 "./ITHACAoutput/Matrices/C");
694 Vector<double> inl(0, 0, 0);
698 for (label k = 0; k <
NUmodes; k++)
713 for (label k = 0; k <
NUmodes; k++)
725 Uinl = autoPtr<volVectorField> (
new volVectorField(
_U()));
728 dt_dummy = autoPtr<dimensionedScalar> (
new dimensionedScalar
731 dimensionSet(0, 0, 1, 0, 0, 0, 0),
734 nu_dummy = autoPtr<dimensionedScalar> (
new dimensionedScalar
737 dimensionSet(0, 2, -1, 0, 0, 0, 0),
743 word B_str =
"B_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
755 word K_str =
"K_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
767 word P_str =
"P_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
779 word C_str =
"C_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
791 word Cf_str =
"Cf_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
803 word BP_str =
"BP_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
869 for (label
i = 0;
i < Bsize;
i++)
871 for (label j = 0; j < Bsize; j++)
874 dimensionedScalar(
"1", dimless, 1),
L_U_SUPmodes[j])).value();
878 if (Pstream::parRun())
880 reduce(
B_matrix, sumOp<Eigen::MatrixXd>());
883 if (Pstream::master())
900 for (label
i = 0;
i < Bsize;
i++)
902 for (label j = 0; j < Bsize; j++)
909 if (Pstream::parRun())
911 reduce(
B_matrix, sumOp<Eigen::MatrixXd>());
914 if (Pstream::master())
928 Eigen::MatrixXd
K_matrix(K1size, K2size);
931 for (label
i = 0;
i < K1size;
i++)
933 for (label j = 0; j < K2size; j++)
940 if (Pstream::parRun())
942 reduce(
K_matrix, sumOp<Eigen::MatrixXd>());
945 if (Pstream::master())
962 for (label j = 0; j < Csize; j++)
967 for (label
i = 0;
i < Csize;
i++)
969 for (label j = 0; j < Csize; j++)
971 for (label k = 0; k < Csize; k++)
979 if (Pstream::parRun())
981 reduce(
C_matrix[
i], sumOp<Eigen::MatrixXd>());
985 if (Pstream::master())
1001 C_tensor.resize(Csize, Csize, Csize);
1003 for (label
i = 0;
i < Csize;
i++)
1005 for (label j = 0; j < Csize; j++)
1007 for (label k = 0; k < Csize; k++)
1025 if (Pstream::parRun())
1027 reduce(
C_tensor, sumOp<Eigen::Tensor<double, 3>>());
1030 if (Pstream::master())
1045 Eigen::MatrixXd
M_matrix(Msize, Msize);
1048 for (label
i = 0;
i < Msize;
i++)
1050 for (label j = 0; j < Msize; j++)
1057 if (Pstream::parRun())
1059 reduce(
M_matrix, sumOp<Eigen::MatrixXd>());
1062 if (Pstream::master())
1078 Eigen::MatrixXd
P_matrix(P1size, P2size);
1081 for (label
i = 0;
i < P1size;
i++)
1083 for (label j = 0; j < P2size; j++)
1090 if (Pstream::parRun())
1092 reduce(
P_matrix, sumOp<Eigen::MatrixXd>());
1095 if (Pstream::master())
1113 for (label j = 0; j < G1size; j++)
1115 G_matrix[j].resize(G2size, G2size);
1118 for (label
i = 0;
i < G1size;
i++)
1120 for (label j = 0; j < G2size; j++)
1122 for (label k = 0; k < G2size; k++)
1130 if (Pstream::parRun())
1132 reduce(
G_matrix[
i], sumOp<Eigen::MatrixXd>());
1136 if (Pstream::master())
1151 Eigen::Tensor<double, 3>
gTensor;
1152 gTensor.resize(g1Size, g2Size, g2Size);
1154 for (label
i = 0;
i < g1Size;
i++)
1156 for (label j = 0; j < g2Size; j++)
1158 for (label k = 0; k < g2Size; k++)
1160 gTensor(
i, j, k) = fvc::domainIntegrate(fvc::grad(
Pmodes[
i]) & (fvc::div(
1167 if (Pstream::parRun())
1169 reduce(
gTensor, sumOp<Eigen::Tensor<double, 3>>());
1172 if (Pstream::master())
1186 Eigen::MatrixXd
D_matrix(Dsize, Dsize);
1189 for (label
i = 0;
i < Dsize;
i++)
1191 for (label j = 0; j < Dsize; j++)
1198 if (Pstream::parRun())
1200 reduce(
D_matrix, sumOp<Eigen::MatrixXd>());
1203 if (Pstream::master())
1216 Eigen::MatrixXd
BC1_matrix(P_BC1size, P_BC2size);
1219 for (label
i = 0;
i < P_BC1size;
i++)
1221 for (label j = 0; j < P_BC2size; j++)
1223 surfaceScalarField lpl((fvc::interpolate(fvc::laplacian(
1227 for (label k = 0; k < lpl.boundaryField().size(); k++)
1229 s += gSum(lpl.boundaryField()[k]);
1236 if (Pstream::parRun())
1238 reduce(
BC1_matrix, sumOp<Eigen::MatrixXd>());
1241 if (Pstream::master())
1259 for (label j = 0; j < P2_BC1size; j++)
1261 BC2_matrix[j].resize(P2_BC2size, P2_BC2size);
1264 for (label
i = 0;
i < P2_BC1size;
i++)
1266 for (label j = 0; j < P2_BC2size; j++)
1268 for (label k = 0; k < P2_BC2size; k++)
1270 surfaceScalarField div_m(fvc::interpolate(fvc::div(fvc::interpolate(
1275 for (label k = 0; k < div_m.boundaryField().size(); k++)
1277 s += gSum(div_m.boundaryField()[k]);
1284 if (Pstream::parRun())
1295 label pressureBC1Size =
NPmodes;
1299 bc2Tensor.resize(pressureBC1Size, pressureBC2Size, pressureBC2Size);
1301 for (label
i = 0;
i < pressureBC1Size;
i++)
1303 for (label j = 0; j < pressureBC2Size; j++)
1305 for (label k = 0; k < pressureBC2Size; k++)
1307 surfaceScalarField div_m(fvc::interpolate(fvc::div(fvc::interpolate(
1312 for (label k = 0; k < div_m.boundaryField().size(); k++)
1314 s += gSum(div_m.boundaryField()[k]);
1322 if (Pstream::parRun())
1324 reduce(
bc2Tensor, sumOp<Eigen::Tensor<double, 3>>());
1327 if (Pstream::master())
1342 Eigen::MatrixXd
BC3_matrix(P3_BC1size, P3_BC2size);
1344 surfaceVectorField n(
mesh.Sf() /
mesh.magSf());
1346 for (label
i = 0;
i < P3_BC1size;
i++)
1348 for (label j = 0; j < P3_BC2size; j++)
1350 surfaceVectorField BC3 = fvc::interpolate(fvc::curl(
L_U_SUPmodes[j])).ref();
1351 surfaceVectorField BC4 = (n ^ fvc::interpolate(fvc::grad(
Pmodes[
i]))).ref();
1352 surfaceScalarField BC5 = ((BC3 & BC4) *
mesh.magSf()).ref();
1355 for (label k = 0; k < BC5.boundaryField().size(); k++)
1357 s += gSum(BC5.boundaryField()[k]);
1364 if (Pstream::parRun())
1366 reduce(
BC3_matrix, sumOp<Eigen::MatrixXd>());
1369 if (Pstream::master())
1382 Eigen::MatrixXd
BC4_matrix(P4_BC1size, P4_BC2size);
1384 surfaceVectorField n(
mesh.Sf() /
mesh.magSf());
1386 for (label
i = 0;
i < P4_BC1size;
i++)
1388 for (label j = 0; j < P4_BC2size; j++)
1390 surfaceScalarField BC3 = fvc::interpolate(
Pmodes[
i]).ref();
1391 surfaceScalarField BC4 = (n & fvc::interpolate(
L_U_SUPmodes[j])).ref();
1392 surfaceScalarField BC5 = ((BC3 * BC4) *
mesh.magSf()).ref();
1395 for (label k = 0; k < BC5.boundaryField().size(); k++)
1397 s += gSum(BC5.boundaryField()[k]);
1404 if (Pstream::parRun())
1406 reduce(
BC4_matrix, sumOp<Eigen::MatrixXd>());
1409 if (Pstream::master())
1424 for (label j = 0; j <
inletIndex.rows(); j++)
1429 for (label k = 0; k <
inletIndex.rows(); k++)
1434 for (label
i = 0;
i < BCsize;
i++)
1440 if (Pstream::parRun())
1442 reduce(
bcVelVec[k], sumOp<Eigen::MatrixXd>());
1446 if (Pstream::master())
1449 "./ITHACAoutput/Matrices/bcVelVec");
1460 List <Eigen::MatrixXd>
bcVelMat(BCUsize);
1462 for (label j = 0; j <
inletIndex.rows(); j++)
1464 bcVelMat[j].resize(BCsize, BCsize);
1467 for (label k = 0; k <
inletIndex.rows(); k++)
1472 for (label
i = 0;
i < BCsize;
i++)
1474 for (label j = 0; j < BCsize; j++)
1478 L_U_SUPmodes[j].boundaryField()[BCind].component(BCcomp));
1482 if (Pstream::parRun())
1484 reduce(
bcVelMat[k], sumOp<Eigen::MatrixXd>());
1488 if (Pstream::master())
1491 "./ITHACAoutput/Matrices/bcVelMat");
1498 label NPmodes, label NSUPmodes)
1502 Eigen::MatrixXd
BP_matrix(BPsize1, BPsize2);
1505 for (label
i = 0;
i < BPsize1;
i++)
1507 for (label j = 0; j < BPsize2; j++)
1509 L_U_SUPmodesaux =
dt_dummy * fvc::laplacian(
1512 fvc::div(L_U_SUPmodesaux)).value();
1516 if (Pstream::parRun())
1518 reduce(
BP_matrix, sumOp<Eigen::MatrixXd>());
1521 if (Pstream::master())
1531 label NPmodes, label NSUPmodes)
1533 Eigen::VectorXd ModeVector;
1536 List <Eigen::MatrixXd>
RD_matrix(BCsize);
1540 for (label
i = 0;
i < BCsize;
i++)
1543 Vector<double>
v(0, 0, 0);
1545 volVectorField Upara(
Uinl());
1555 for (label j = 0; j < RDsize; j++)
1558 RD_matrix[
i](j, 0) = ModeVector.dot(b.col(0));
1561 if (Pstream::parRun())
1563 reduce(
RD_matrix[
i], sumOp<Eigen::MatrixXd>());
1566 if (Pstream::master())
1577 label NPmodes, label NSUPmodes)
1579 Eigen::VectorXd ModeVector;
1582 List <Eigen::MatrixXd>
RC_matrix(BCsize);
1586 for (label
i = 0;
i < BCsize;
i++)
1589 Vector<double>
v(0, 0, 0);
1591 volVectorField Upara(
Uinl());
1596 fvm::div(fvc::flux(Upara), Upara)
1601 for (label j = 0; j < RCsize; j++)
1604 RC_matrix[
i](j, 0) = ModeVector.dot(b.col(0));
1607 if (Pstream::parRun())
1609 reduce(
RC_matrix[
i], sumOp<Eigen::MatrixXd>());
1612 if (Pstream::master())
1623 label NPmodes, label NSUPmodes)
1629 Cf_tensor.resize(Csize2, Csize1, Csize1);
1631 for (label
i = 0;
i < Csize2;
i++)
1633 for (label j = 0; j < Csize1; j++)
1635 for (label k = 0; k < Csize1; k++)
1639 L_U_SUPmodesaux =
dt_dummy * (fvc::div(
1645 L_U_SUPmodesaux =
dt_dummy * (fvc::div(
1651 * fvc::div(L_U_SUPmodesaux)).value();
1656 if (Pstream::parRun())
1658 reduce(
Cf_tensor, sumOp<Eigen::Tensor<double, 3>>());
1661 if (Pstream::master())
1674 List<Eigen::MatrixXd> LinSysDivDummy;
1676 volScalarField
p(
_p());
1678 for (label
i = 0;
i < BCsize;
i++)
1681 Vector<double>
v(0, 0, 0);
1683 volVectorField Upara(
Uinl());
1687 fvm::laplacian(
p) == (1.0 /
dt_dummy)*fvc::div(Upara)
1689 pEqn.setReference(0, 0);
1707 List<Eigen::MatrixXd> LinSysConvDummy;
1709 volScalarField
p(
_p());
1711 for (label
i = 0;
i < BCsize;
i++)
1714 Vector<double>
v(0, 0, 0);
1716 volVectorField Upara(
Uinl());
1719 Caux =
dt_dummy * (-fvc::div(fvc::flux(Upara), Upara));
1722 fvm::laplacian(
p) == (1.0 /
dt_dummy)*fvc::div(Caux)
1724 pEqn.setReference(0, 0);
1742 List<Eigen::MatrixXd> LinSysDiffDummy;
1744 volScalarField
p(
_p());
1746 for (label
i = 0;
i < BCsize;
i++)
1749 Vector<double>
v(0, 0, 0);
1751 volVectorField Upara(
Uinl());
1757 fvm::laplacian(
p) == (1.0 /
dt_dummy)*fvc::div(Daux)
1759 pEqn.setReference(0, 0);
1783 volVectorField CoeffA = (fvc::reconstruct(
L_PHImodes[
i])).ref();
1785 for (label j = 0; j < Isize; j++)
1787 surfaceScalarField B = fvc::flux(
L_U_SUPmodes[j]).ref();
1788 volVectorField CoeffB = fvc::reconstruct(B).ref();
1789 I_matrix(
i, j) = fvc::domainIntegrate(CoeffA & CoeffB).value();
1793 if (Pstream::parRun())
1795 reduce(
I_matrix, sumOp<Eigen::MatrixXd>());
1798 if (Pstream::master())
1814 surfaceScalarField phi_tmp(
"Phi_tmp",
_phi());
1818 for (label j = 0; j < DFsize; j++)
1821 dimensionedScalar(
"1", dimless, 1),
1823 volVectorField CoeffB = fvc::reconstruct(phi_tmp).ref();
1824 volVectorField CoeffA = fvc::reconstruct(
L_PHImodes[
i]).ref();
1825 DF_matrix(
i, j) = fvc::domainIntegrate(CoeffA & CoeffB).value();
1829 if (Pstream::parRun())
1831 reduce(
DF_matrix, sumOp<Eigen::MatrixXd>());
1834 if (Pstream::master())
1837 "DF_" + name(
NUmodes) +
"_" + name(
1850 Eigen::MatrixXd
KF_matrix(KF1size, KF2size);
1852 for (label
i = 0;
i < KF1size;
i++)
1854 for (label j = 0; j < KF2size; j++)
1856 volVectorField CoeffA = (fvc::reconstruct(
dt_dummy * fvc::snGrad(
1858 volVectorField CoeffB = fvc::reconstruct(
L_PHImodes[
i]).ref();
1859 KF_matrix(
i, j) = fvc::domainIntegrate(CoeffA & CoeffB).value();
1863 if (Pstream::parRun())
1865 reduce(
KF_matrix, sumOp<Eigen::MatrixXd>());
1868 if (Pstream::master())
1871 "KF_" + name(
NUmodes) +
"_" + name(
1880 label NPmodes, label NSUPmodes)
1886 surfaceScalarField phi_tmp(
"Phi_tmp",
_phi());
1890 for (label j = 0; j < Csize1; j++)
1892 for (label k = 0; k < Csize1; k++)
1895 volVectorField CoeffA = fvc::reconstruct(phi_tmp).ref();
1896 volVectorField CoeffB = fvc::reconstruct(
L_PHImodes[j]).ref();
1897 Ci_tensor(
i, j, k) = fvc::domainIntegrate(CoeffB & CoeffA).value();
1902 if (Pstream::parRun())
1904 reduce(
Ci_tensor, sumOp<Eigen::Tensor<double, 3>>());
1907 if (Pstream::master())
1923 List <Eigen::MatrixXd>
SD_matrix(BCsize);
1924 surfaceScalarField phi_tmp(
"Phi_tmp",
_phi());
1926 for (label
i = 0;
i < BCsize;
i++)
1929 Vector<double>
v(0, 0, 0);
1931 volVectorField Upara(
Uinl());
1936 for (label j = 0; j < SDsize; j++)
1938 volVectorField CoeffB = fvc::reconstruct(
L_PHImodes[j]).ref();
1940 volVectorField CoeffA = fvc::reconstruct(phi_tmp).ref();
1941 SD_matrix[
i](j, 0) = fvc::domainIntegrate(CoeffA & CoeffB).value();
1947 if (Pstream::parRun())
1949 reduce(
SD_matrix[
i], sumOp<Eigen::MatrixXd>());
1962 List <Eigen::MatrixXd>
SC_matrix(BCsize);
1963 surfaceScalarField phi_tmp(
"Phi_tmp",
_phi());
1965 for (label
i = 0;
i < BCsize;
i++)
1968 Vector<double>
v(0, 0, 0);
1970 volVectorField Upara(
Uinl());
1975 for (label j = 0; j < SCsize; j++)
1977 volVectorField CoeffB = fvc::reconstruct(
L_PHImodes[j]).ref();
1978 phi_tmp =
dt_dummy * fvc::flux(fvc::div(fvc::flux(Upara), Upara));
1979 volVectorField CoeffA = fvc::reconstruct(phi_tmp).ref();
1980 SC_matrix[
i](j, 0) = fvc::domainIntegrate(CoeffA & CoeffB).value();
1999 volVectorField
A = fvc::reconstruct(
L_PHImodes[
i]).ref();
2001 for (label j = 0; j <
NUmodes; j++)
2003 volVectorField B = fvc::reconstruct(
L_PHImodes[j]).ref();
2004 W_matrix(
i, j) = fvc::domainIntegrate(
A & B).value();
2017 volScalarField& ciao =
const_cast<volScalarField&
>(
nu);
2020 for (label
i = 0;
i < ciao.boundaryFieldRef().size();
i++)
2034 instantList Times =
runTime.times();
2036 volScalarField&
p =
_p();
2037 volVectorField&
U =
_U();
2039 IOdictionary FORCESdict
2046 IOobject::MUST_READ,
2054 "transportProperties",
2057 IOobject::MUST_READ,
2061 word pName(FORCESdict.lookup(
"pName"));
2062 word UName(FORCESdict.lookup(
"UName"));
2063 functionObjects::ITHACAforces f(
"Forces",
mesh, FORCESdict);
2071 f.calcForcesMoment();
2073 for (label j = 0; j < 3; j++)
2085 f.calcForcesMoment();
2087 for (label j = 0; j < 3; j++)
2089 nMatrix(
i, j) = f.forcePressure()[j];
2096 "./ITHACAoutput/Matrices/");
2103 "./ITHACAoutput/Matrices/");
2110 "./ITHACAoutput/Matrices/");
2122 instantList Times =
runTime.times();
2124 volScalarField&
p =
_p();
2125 volVectorField&
U =
_U();
2127 IOdictionary FORCESdict
2134 IOobject::MUST_READ,
2142 "transportProperties",
2145 IOobject::MUST_READ,
2149 word pName(FORCESdict.lookup(
"pName"));
2150 word UName(FORCESdict.lookup(
"UName"));
2151 functionObjects::ITHACAforces f(
"Forces",
mesh, FORCESdict);
2153 for (label
i = 0;
i < nModes;
i++)
2159 f.calcForcesMoment();
2161 for (label j = 0; j < 3; j++)
2167 for (label
i = 0;
i < nModes;
i++)
2173 f.calcForcesMoment();
2175 for (label j = 0; j < 3; j++)
2177 nMatrix(
i, j) = f.forcePressure()[j];
2184 "./ITHACAoutput/Matrices/");
2191 "./ITHACAoutput/Matrices/");
2198 "./ITHACAoutput/Matrices/");
2204 const Eigen::MatrixXd& pressureCoeffs, fileName folder)
2207 "The number of velocity modes in the coefficients matrix is not equal to the number of modes in the viscous forces matrix.");
2209 "The number of pressure modes in the coefficients matrix is not equal to the number of modes in the pressure forces matrix.");
2211 system(
"ln -s ../../constant " + folder +
"/constant");
2212 system(
"ln -s ../../0 " + folder +
"/0");
2213 system(
"ln -s ../../system " + folder +
"/system");
2215 IOdictionary FORCESdict
2222 IOobject::MUST_READ,
2226 Eigen::MatrixXd fTau;
2228 fTau.setZero(velCoeffs.rows(), 3);
2229 fN.setZero(pressureCoeffs.rows(), 3);
2231 fN = pressureCoeffs *
nMatrix;
2265 argList& args =
_args();
2277 Info <<
"ReReading field p\n" << endl;
2278 _p = autoPtr<volScalarField>
2287 IOobject::MUST_READ,
2288 IOobject::AUTO_WRITE
2293 volScalarField&
p =
_p();
2294 Info <<
"ReReading field U\n" << endl;
2295 _U = autoPtr<volVectorField>
2304 IOobject::MUST_READ,
2305 IOobject::AUTO_WRITE
2310 volVectorField&
U =
_U();
2311 Info <<
"ReReading/calculating face flux field phi\n" << endl;
2312 _phi = autoPtr<surfaceScalarField>
2314 new surfaceScalarField
2321 IOobject::READ_IF_PRESENT,
2322 IOobject::AUTO_WRITE
2324 linearInterpolate(
U) &
mesh.Sf()
2327 surfaceScalarField&
phi =
_phi();
2333 new singlePhaseTransportModel(
U,
phi )
2336 turbulence = autoPtr<incompressible::turbulenceModel>
2340 _MRF = autoPtr<IOMRFZoneList>
2342 new IOMRFZoneList(
mesh)
forAll(example_CG.gList, solutionI)
#define M_Assert(Expr, Msg)
static Eigen::VectorXd field2Eigen(GeometricField< tensor, PatchField, GeoMesh > &field)
Convert a vector OpenFOAM field into an Eigen Vector.
static void fvMatrix2Eigen(fvMatrix< type_foam_matrix > foam_matrix, type_A &A, type_B &b)
Convert a FvMatrix OpenFOAM matrix (Linear System) into a Eigen Matrix A and a source vector b.
static ITHACAparameters * getInstance()
Gets an instance of ITHACAparameters, to be used if the instance is already existing.
List< Eigen::MatrixXd > project(fvMatrix< Type > &Af, label numberOfModes=0, word projType="G")
A function that project an FvMatrix (OpenFoam linear System) on the modes.
void writeMu(List< scalar > mu_now)
Write out a list of scalar corresponding to the parameters used in the truthSolve.
Eigen::MatrixXd mu_samples
Matrix of parameters to be used for PODI, where each row corresponds to a sample point....
label counter
Counter used for the output of the full order solutions.
void assignBC(volVectorField &s, label BC_ind, Vector< double > &value)
Assign Boundary Condition to a volVectorField.
void assignIF(T &s, G &value)
Assign internal field condition.
bool offline
Boolean variable, it is 1 if the Offline phase has already been computed, else 0.
IOdictionary * ITHACAdict
dictionary to store input output infos
Eigen::MatrixXd mu
Row matrix of parameters.
autoPtr< argList > _args
argList
Eigen::MatrixXi inletIndex
Matrix that contains informations about the inlet boundaries.
bool podex
Boolean variable, it is 1 if the POD has already been computed, else 0.
void truthSolve()
Perform a TruthSolve.
void change_viscosity(double mu)
Function to change the viscosity.
List< Eigen::MatrixXd > bcVelVec
Boundary term for penalty method - vector.
scalar maxIter
Number of maximum iterations to be done for the computation of the truth solution.
void restart()
set U and P back to the values into the 0 folder
List< Eigen::MatrixXd > pressure_gradient_term_linsys_div(label NPmodes)
Laplacian of pressure Linear System - Divergence term.
label NPmodes
Number of pressure modes used for the projection.
List< Eigen::MatrixXd > pressure_gradient_term_linsys_conv(label NPmodes)
Laplacian of pressure Linear System - Convection term.
bool supex
Boolean variable to check the existence of the supremizer modes.
void projectPPE(fileName folder, label NUmodes, label NPmodes, label NSUPmodes=0)
Project using the Poisson Equation for pressure.
Eigen::MatrixXd nMatrix
Pressure forces.
Eigen::MatrixXd BC1_matrix
PPE BC1.
Eigen::MatrixXd diffusive_term(label NUmodes, label NPmodes, label NSUPmodes)
Diffusive Term.
autoPtr< surfaceScalarField > _phi
Flux.
Eigen::MatrixXd BC4_matrix
PPE BC4.
Eigen::MatrixXd tauMatrix
Viscous forces.
Eigen::MatrixXd BC3_matrix
PPE BC3.
Eigen::Tensor< double, 3 > C_tensor
Diffusion term.
void forcesMatrices(label NUmodes, label NPmodes, label NSUPmodes)
Compute lift and drag matrices.
autoPtr< simpleControl > _simple
simpleControl
surfaceScalarModes L_PHImodes
List of pointers containing the total number of flux modes.
PtrList< volScalarField > Pfield
List of pointers used to form the pressure snapshots matrix.
volVectorModes supmodes
List of pointers used to form the supremizer modes.
List< Eigen::MatrixXd > bcVelocityVec(label NUmodes, label NSUPmodes)
Boundary integral modes on boundary used by the penaly method.
List< Eigen::MatrixXd > boundary_vector_convection_consistent(label NUmodes, label NSUPmodes)
Boundary vector convection term - Consistent Flux Method.
Eigen::MatrixXd W_matrix
Mass Matrix New Time Step - Consistent Flux Method.
Eigen::MatrixXd mass_matrix_oldtime_consistent(label NUmodes, label NPmodes, label NSUPmodes)
Mass Matrix old time step (consistent flux method)
List< Eigen::MatrixXd > pressure_gradient_term_linsys_diff(label NPmodes)
Laplacian of pressure Linear System - Diffusion term.
autoPtr< fv::options > _fvOptions
fvOptions
Eigen::MatrixXd pressure_BC4(label NPmodes, label NUmodes)
Term N° 4 given by the additional boundary condition using a PPE approach for time-dependent BCs.
void solvesupremizer(word type="snapshots")
solve the supremizer either with the use of the pressure snaphots or the pressure modes
autoPtr< Time > _runTime
Time.
Eigen::MatrixXd I_matrix
Mass Matrix Old Time Step - Consistent Flux Method.
volVectorModes Umodes
List of pointers used to form the velocity modes.
Eigen::MatrixXd diffusive_term_sym(label NUmodes, label NPmodes, label NSUPmodes)
Symetric diffusive Term.
PtrList< volVectorField > Ufield
List of pointers used to form the velocity snapshots matrix.
List< Eigen::MatrixXd > boundary_vector_diffusion_consistent(label NUmodes, label NSUPmodes)
Boundary vector diffusion term (consistent flux method)
List< Eigen::MatrixXd > LinSysDiff
Projection Peqn onto Pressure modes - Diffusion term.
autoPtr< dimensionedScalar > dt_dummy
Dummy time step including unit.
Eigen::MatrixXd diffusive_term_flux_method(label NUmodes, label NPmodes, label NSUPmodes)
Diffusive Flux Method.
Eigen::MatrixXd diffusive_term_consistent(label NUmodes, label NPmodes, label NSUPmodes)
Diffusion Term (consistent flux method)
Eigen::MatrixXd pressure_BC1(label NPmodes, label NUmodes)
Term N° 1 given by the additional boundary condition using a PPE approach.
steadyNS()
Null constructor.
Eigen::MatrixXd divergence_term(label NUmodes, label NPmodes, label NSUPmodes)
Divergence Term (supremizer approach)
List< Eigen::MatrixXd > G_matrix
Divergence of momentum PPE.
scalar tolerance
Tolerance for the residual of the stationary problems, there is the same tolerance for velocity and p...
Eigen::MatrixXd mass_term(label NUmodes, label NPmodes, label NSUPmodes)
Mass Term.
autoPtr< fvMesh > _mesh
Mesh.
autoPtr< singlePhaseTransportModel > _laminarTransport
Laminar transport (used by turbulence model)
label NUmodes
Number of velocity modes used for the projection.
autoPtr< dimensionedScalar > nu_dummy
Dummy viscocity including unit.
List< Eigen::MatrixXd > boundary_vector_diffusion(label NUmodes, label NPmodes, label NSUPmodes)
Boundary vector diffusion term.
List< Eigen::MatrixXd > LinSysDiv
Projection Peqn onto Pressure modes - Divergence term.
PtrList< volVectorField > liftfield
List of pointers used to form the list of lifting functions.
Eigen::Tensor< double, 3 > convective_term_flux_tens(label NUmodes, label NPmodes, label NSUPmodes)
Convective Term.
Eigen::Tensor< double, 3 > convective_term_consistent_tens(label NUmodes, label NPmodes, label NSUPmodes)
Convective Term (consistent flux method)
scalar pRefValue
Reference pressure value.
label pRefCell
Reference pressure cell.
word fluxMethod
Flux Method.
volVectorModes L_U_SUPmodes
List of pointers containing the total number of lift, supremizer and velocity modes.
Eigen::MatrixXd pressure_BC3(label NPmodes, label NUmodes)
Term N° 3 given by the additional boundary condition using a PPE approach.
List< Eigen::MatrixXd > boundary_vector_convection(label NUmodes, label NPmodes, label NSUPmodes)
Boundary vector convection term.
Eigen::MatrixXd B_matrix
Diffusion term.
List< Eigen::MatrixXd > RD_matrix
Boundary term for diffusion term.
Eigen::MatrixXd D_matrix
Laplacian term PPE.
autoPtr< IOMRFZoneList > _MRF
MRF variable.
List< Eigen::MatrixXd > SD_matrix
Boundary term for diffusion term - Consistent Flux Method.
label NSUPmodes
Number of supremizer modes used for the projection.
Eigen::Tensor< double, 3 > gTensor
Divergence of momentum PPE.
Eigen::MatrixXd KF_matrix
Pressure Gradient Term - Consistent Flux Method.
Eigen::MatrixXd K_matrix
Gradient of pressure matrix.
List< Eigen::MatrixXd > C_matrix
Non linear term.
Eigen::Tensor< double, 3 > convective_term_tens(label NUmodes, label NPmodes, label NSUPmodes)
Export convective term as a tensor.
autoPtr< incompressible::turbulenceModel > turbulence
Turbulence model.
List< Eigen::MatrixXd > convective_term(label NUmodes, label NPmodes, label NSUPmodes)
Convective Term.
Eigen::MatrixXd pressure_gradient_term_consistent(label NUmodes, label NPmodes, label NSUPmodes)
Pressure Gradient Term (consistent flux method)
List< Eigen::MatrixXd > pressure_BC2(label NPmodes, label NUmodes)
Term N° 2 given by the additional boundary condition using a PPE approach.
List< Eigen::MatrixXd > LinSysConv
Projection Peqn onto Pressure modes - Convection term.
PtrList< volVectorField > supfield
List of pointers used to form the supremizer snapshots matrix.
Eigen::Tensor< double, 3 > divMomentum(label NUmodes, label NPmodes)
Divergence of convective term (PPE approach)
List< Eigen::MatrixXd > SC_matrix
Boundary term for convection term - Consistent Flux Method.
Eigen::MatrixXd pressure_gradient_term(label NUmodes, label NPmodes, label NSUPmodes)
Gradient of pressure.
Eigen::MatrixXd DF_matrix
Diffusion Term - Consistent Flux Method.
List< Eigen::MatrixXd > bcVelMat
Boundary term for penalty method - matrix.
Eigen::MatrixXd P_matrix
Div of velocity.
List< Eigen::MatrixXd > RC_matrix
Boundary vector for convection term.
Eigen::MatrixXd BP_matrix
Diffusion term for flux method PPE.
Eigen::Tensor< double, 3 > Cf_tensor
Convection term for flux method.
Eigen::MatrixXd M_matrix
Mass Matrix.
List< Eigen::MatrixXd > BC2_matrix
PPE BC2.
autoPtr< volVectorField > Uinl
Initial dummy field with all Dirichlet boundary conditions.
void discretizeThenProject(fileName folder, label NUmodes, label NPmodes, label NSUPmodes=0)
Project using the Discretize-then-project approach.
void projectSUP(fileName folder, label NUmodes, label NPmodes, label NSUPmodes)
Project using a supremizer approach.
Eigen::MatrixXd laplacian_pressure(label NPmodes)
Laplacian of pressure term (PPE approach)
surfaceScalarModes Phimodes
List of pointers used to form the flux modes.
Eigen::MatrixXd mass_matrix_newtime_consistent(label NUmodes, label NPmodes, label NSUPmodes)
Mass Matrix new time step (consistent flux method)
List< Eigen::MatrixXd > bcVelocityMat(label NUmodes, label NSUPmodes)
Boundary integral modes on boundary used by the penaly method.
Eigen::Tensor< double, 3 > bc2Tensor
PPE BC2.
autoPtr< volVectorField > _U
Velocity field.
Eigen::Tensor< double, 3 > pressureBC2(label NPmodes, label NUmodes)
Term N° 2 given by the additional boundary condition using a PPE approach.
Eigen::Tensor< double, 3 > Ci_tensor
Convection term - Consistent Flux Method.
void liftSolve()
Perform a lift solve.
List< Eigen::MatrixXd > div_momentum(label NUmodes, label NPmodes)
Divergence of convective term (PPE approach)
volScalarModes Pmodes
List of pointers used to form the pressure modes.
word bcMethod
Boundary Method.
void reconstructLiftAndDrag(const Eigen::MatrixXd &velCoeffs, const Eigen::MatrixXd &pressureCoeffs, fileName folder)
Method to reconstruct the forces using velocity and pressure coefficients.
autoPtr< volScalarField > _p
Pressure field.
void ReadDenseMatrix(MatrixType &Matrix, word folder, word MatrixName)
Read a dense matrix from a binary format file.
void exportSolution(GeometricField< Type, PatchField, GeoMesh > &s, fileName subfolder, fileName folder, word fieldName)
Export a field to file in a certain folder and subfolder.
void exportMatrix(Eigen::Matrix< T, -1, dim > &matrix, word Name, word type, word folder)
Export the reduced matrices in numpy (type=python), matlab (type=matlab) and txt (type=eigen) format ...
void SaveDenseMatrix(MatrixType &Matrix, word folder, word MatrixName)
Save a dense matrix to a binary format file.
void ReadDenseTensor(TensorType &Tensor, word folder, word MatrixName)
Read a dense tensor from file.
void read_fields(PtrList< GeometricField< Type, PatchField, GeoMesh > > &Lfield, word Name, fileName casename, int first_snap, int n_snap)
Function to read a list of fields from the name of the field and casename.
void exportTensor(Eigen::Tensor< T, 3 > tensor, word Name, word type, word folder)
Export the reduced tensor in numpy (tipo=python), matlab (tipo=matlab) and txt (tipo=eigen) format.
void SaveDenseTensor(TensorType &Tensor, word folder, word MatrixName)
Save a dense tensor to file.
bool check_pod()
Check if the POD data folder "./ITHACAoutput/POD" exists.
bool check_off()
Check if the offline data folder "./ITHACAoutput/Offline" exists.
void assignZeroDirichlet(GeometricField< Type, fvPatchField, volMesh > &field)
Assign zero internal field.
bool check_folder(word folder)
Checks if a folder exists.
bool check_file(std::string fileName)
Function that returns true if a file exists.
bool check_sup()
Check if the supremizer folder exists.
void createSymLink(word folder)
Creates symbolic links to 0, system and constant.
void changeBCtype(GeometricField< Type, fvPatchField, volMesh > &field, word BCtype, label BC_ind)
Change the boundary condition type for a GeometricField.
simpleControl simple(mesh)
IOdictionary transportProperties(IOobject("transportProperties", runTime.constant(), mesh, IOobject::MUST_READ_IF_MODIFIED, IOobject::NO_WRITE))
singlePhaseTransportModel & laminarTransport
setRefCell(p, mesh.solutionDict().subDict("SIMPLE"), pRefCell, pRefValue)
Header file of the steadyNS class.