36#include "viscosityModel.H"
44 _args = autoPtr<argList>
46 new argList(argc, argv)
49 if (!
_args->checkRootCase())
51 Foam::FatalError.exit();
54 argList& args =
_args();
57 _simple = autoPtr<simpleControl>
83 "The BC method must be set to lift or penalty or none in ITHACAdict");
86 "The flux method must be set to inconsistent or consistent in ITHACAdict");
101 volScalarField&
p =
_p();
102 volVectorField&
U =
_U();
103 surfaceScalarField&
phi =
_phi();
106 IOMRFZoneList& MRF =
_MRF();
118 for (label
i = 0;
i < mu_now.size();
i++)
132 "./ITHACAoutput/Offline");
140 || type ==
"snapshots",
141 "You must specify the variable type with either snapshots or modes");
142 PtrList<volScalarField> P_sup;
144 if (type ==
"snapshots")
155 volVectorField
U =
_U();
167 dimensionedVector(
"zero",
U.dimensions(), vector::zero)
170 if (type ==
"snapshots")
181 volVectorField
U =
_U();
193 dimensionedVector(
"zero",
U.dimensions(), vector::zero)
195 dimensionedScalar nu_fake
198 dimensionSet(0, 2, -1, 0, 0, 0, 0),
201 Vector<double>
v(0, 0, 0);
203 for (label
i = 0;
i < Usup.boundaryField().size();
i++)
205 if (Usup.boundaryField()[
i].type() !=
"processor")
213 if (type ==
"snapshots")
215 for (label
i = 0;
i < P_sup.size();
i++)
217 fvVectorMatrix u_sup_eqn
219 - fvm::laplacian(nu_fake, Usup)
223 u_sup_eqn == fvc::grad(P_sup[
i])
233 for (label
i = 0;
i < P_sup.size();
i++)
235 fvVectorMatrix u_sup_eqn
237 - fvm::laplacian(nu_fake, Usup)
241 u_sup_eqn == fvc::grad(P_sup[
i])
258 surfaceScalarField&
phi =
_phi();
260 volScalarField
p =
_p();
261 volVectorField
U =
_U();
262 IOMRFZoneList& MRF =
_MRF();
264 volVectorField Ulift(
"Ulift" + name(k),
U);
265 instantList Times =
runTime.times();
267 pisoControl potentialFlow(
mesh,
"potentialFlow");
268 Info <<
"Solving a lifting Problem" << endl;
269 Vector<double> v1(0, 0, 0);
271 Vector<double>
v0(0, 0, 0);
273 for (label j = 0; j <
U.boundaryField().size(); j++)
279 else if (
U.boundaryField()[BCind].type() ==
"fixedValue")
288 phi = linearInterpolate(Ulift) &
mesh.Sf();
291 Info <<
"Constructing velocity potential field Phi\n" << endl;
299 IOobject::READ_IF_PRESENT,
303 dimensionedScalar(
"Phi", dimLength * dimVelocity, 0),
304 p.boundaryField().types()
306 label PhiRefCell = 0;
307 scalar PhiRefValue = 0;
311 potentialFlow.dict(),
315 mesh.setFluxRequired(Phi.name());
316 runTime.functionObjects().start();
317 MRF.makeRelative(
phi);
320 while (potentialFlow.correctNonOrthogonal())
322 fvScalarMatrix PhiEqn
324 fvm::laplacian(dimensionedScalar(
"1", dimless, 1), Phi)
328 PhiEqn.setReference(PhiRefCell, PhiRefValue);
331 if (potentialFlow.finalNonOrthogonalIter())
333 phi -= PhiEqn.flux();
337 MRF.makeAbsolute(
phi);
338 Info <<
"Continuity error = "
339 << mag(fvc::div(
phi))().weightedAverage(
mesh.V()).value()
341 Ulift = fvc::reconstruct(
phi);
342 Ulift.correctBoundaryConditions();
343 Info <<
"Interpolated velocity error = "
344 << (sqrt(sum(sqr((fvc::interpolate(
U) &
mesh.Sf()) -
phi)))
345 / sum(
mesh.magSf())).value()
363 for (label k = 0; k <
liftfield.size(); k++)
371 for (label k = 0; k <
NUmodes; k++)
379 word B_str =
"B_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
391 word K_str =
"K_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
403 word M_str =
"M_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
415 word D_str =
"D_" + name(
NPmodes);
426 word bc3_str =
"BC3_" + name(
liftfield.size()) +
"_" + name(
438 word bc4_str =
"BC4_" + name(
liftfield.size()) +
"_" + name(
450 word C_str =
"C_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
462 word G_str =
"G_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
499 if (
para->exportPython)
506 "./ITHACAoutput/Matrices/");
508 "./ITHACAoutput/Matrices/");
513 if (
para->exportMatlab)
520 "./ITHACAoutput/Matrices/");
522 "./ITHACAoutput/Matrices/");
534 "./ITHACAoutput/Matrices/");
536 "./ITHACAoutput/Matrices/");
538 "./ITHACAoutput/Matrices/C");
540 "./ITHACAoutput/Matrices/G");
565 for (label k = 0; k <
liftfield.size(); k++)
573 for (label k = 0; k <
NUmodes; k++)
589 word B_str =
"B_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
601 word K_str =
"K_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
613 word P_str =
"P_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
625 word M_str =
"M_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
637 word C_str =
"C_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
671 if (
para->exportPython)
680 if (
para->exportMatlab)
696 "./ITHACAoutput/Matrices/C");
716 Vector<double> inl(0, 0, 0);
720 for (label k = 0; k <
NUmodes; k++)
735 for (label k = 0; k <
NUmodes; k++)
747 Uinl = autoPtr<volVectorField> (
new volVectorField(
_U()));
750 dt_dummy = autoPtr<dimensionedScalar> (
new dimensionedScalar
753 dimensionSet(0, 0, 1, 0, 0, 0, 0),
756 nu_dummy = autoPtr<dimensionedScalar> (
new dimensionedScalar
759 dimensionSet(0, 2, -1, 0, 0, 0, 0),
765 word B_str =
"B_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
777 word K_str =
"K_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
789 word P_str =
"P_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
801 word C_str =
"C_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
813 word Cf_str =
"Cf_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
825 word BP_str =
"BP_" + name(
liftfield.size()) +
"_" + name(
NUmodes) +
"_" + name(
891 for (label
i = 0;
i < Bsize;
i++)
893 for (label j = 0; j < Bsize; j++)
896 dimensionedScalar(
"1", dimless, 1),
L_U_SUPmodes[j])).value();
900 if (Pstream::master())
917 for (label
i = 0;
i < Bsize;
i++)
919 for (label j = 0; j < Bsize; j++)
926 if (Pstream::master())
940 Eigen::MatrixXd
K_matrix(K1size, K2size);
943 for (label
i = 0;
i < K1size;
i++)
945 for (label j = 0; j < K2size; j++)
952 if (Pstream::master())
969 for (label j = 0; j < Csize; j++)
974 for (label
i = 0;
i < Csize;
i++)
976 for (label j = 0; j < Csize; j++)
978 for (label k = 0; k < Csize; k++)
987 if (Pstream::master())
1003 C_tensor.resize(Csize, Csize, Csize);
1005 for (label
i = 0;
i < Csize;
i++)
1007 for (label j = 0; j < Csize; j++)
1009 for (label k = 0; k < Csize; k++)
1027 if (Pstream::master())
1043 Eigen::Tensor<double, 3>
C_tensor(Csize, Csize, Csize);
1045 for (label j = 0; j < Csize; ++j)
1050 List<tmp<volVectorField>> divRow(Csize);
1051 for (label k = 0; k < Csize; ++k)
1063 for (label
i = 0;
i < Csize; ++
i)
1065 for (label k = 0; k < Csize; ++k)
1067 const volVectorField& divField = divRow[k]();
1073 if (Pstream::master())
1088 Eigen::MatrixXd
M_matrix(Msize, Msize);
1091 for (label
i = 0;
i < Msize;
i++)
1093 for (label j = 0; j < Msize; j++)
1100 if (Pstream::master())
1115 Eigen::MatrixXd
P_matrix(P1size, P2size);
1118 for (label
i = 0;
i < P1size;
i++)
1120 for (label j = 0; j < P2size; j++)
1127 if (Pstream::master())
1145 for (label j = 0; j < G1size; j++)
1147 G_matrix[j].resize(G2size, G2size);
1150 for (label
i = 0;
i < G1size;
i++)
1152 for (label j = 0; j < G2size; j++)
1154 for (label k = 0; k < G2size; k++)
1163 if (Pstream::master())
1178 Eigen::Tensor<double, 3>
gTensor;
1179 gTensor.resize(g1Size, g2Size, g2Size);
1181 for (label
i = 0;
i < g1Size;
i++)
1183 for (label j = 0; j < g2Size; j++)
1185 for (label k = 0; k < g2Size; k++)
1187 gTensor(
i, j, k) = fvc::domainIntegrate(fvc::grad(
Pmodes[
i]) & (fvc::div(
1194 if (Pstream::master())
1209 Eigen::Tensor<double, 3>
gTensor (g1Size, g2Size, g2Size);
1211 List<tmp<volVectorField>> PmodesGrad(g1Size);
1212 for (label
i = 0;
i < g1Size;
i++)
1214 PmodesGrad[
i] = fvc::grad(
Pmodes[
i]);
1217 for (label j = 0; j < g2Size; j++)
1222 List<tmp<volVectorField>> divRow(g2Size);
1223 for (label k = 0; k < g2Size; ++k)
1228 for (label
i = 0;
i < g1Size;
i++)
1230 const volVectorField& gradPi = PmodesGrad[
i]();
1231 for (label k = 0; k < g2Size; k++)
1233 const volVectorField& divField = divRow[k]();
1234 gTensor(
i, j, k) = fvc::domainIntegrate(gradPi & divField).value();
1239 if (Pstream::master())
1254 Eigen::MatrixXd
L_matrix(Lsize, Lsize);
1255 for (label
i = 0;
i < Lsize;
i++)
1257 for (label j = 0; j < Lsize; j++)
1260 fvc::interpolate(vls) & vls.mesh().Sf(),
1272 Eigen::MatrixXd
L_D_matrix(LDsize1, LDsize2);
1273 for (label
i = 0;
i < LDsize1;
i++)
1275 for (label j = 0; j < LDsize2; j++)
1278 fvc::interpolate(vls) & vls.mesh().Sf(),
1289 Eigen::MatrixXd
D_matrix(Dsize, Dsize);
1292 for (label
i = 0;
i < Dsize;
i++)
1294 for (label j = 0; j < Dsize; j++)
1301 if (Pstream::master())
1313 Eigen::MatrixXd
BC1_matrix(P_BC1size, P_BC2size);
1316 for (label
i = 0;
i < P_BC1size;
i++)
1318 for (label j = 0; j < P_BC2size; j++)
1320 surfaceScalarField lpl((fvc::interpolate(fvc::laplacian(
1324 for (label k = 0; k < lpl.boundaryField().size(); k++)
1326 s += gSum(lpl.boundaryField()[k]);
1333 if (Pstream::master())
1351 for (label j = 0; j < P2_BC1size; j++)
1353 BC2_matrix[j].resize(P2_BC2size, P2_BC2size);
1356 for (label
i = 0;
i < P2_BC1size;
i++)
1358 for (label j = 0; j < P2_BC2size; j++)
1360 for (label k = 0; k < P2_BC2size; k++)
1362 surfaceScalarField div_m(fvc::interpolate(fvc::div(fvc::interpolate(
1367 for (label k = 0; k < div_m.boundaryField().size(); k++)
1369 s += gSum(div_m.boundaryField()[k]);
1382 label pressureBC1Size =
NPmodes;
1386 bc2Tensor.resize(pressureBC1Size, pressureBC2Size, pressureBC2Size);
1388 for (label
i = 0;
i < pressureBC1Size;
i++)
1390 for (label j = 0; j < pressureBC2Size; j++)
1392 for (label k = 0; k < pressureBC2Size; k++)
1394 surfaceScalarField div_m(fvc::interpolate(fvc::div(fvc::interpolate(
1399 for (label k = 0; k < div_m.boundaryField().size(); k++)
1401 s += gSum(div_m.boundaryField()[k]);
1409 if (Pstream::master())
1424 Eigen::MatrixXd
BC3_matrix(P3_BC1size, P3_BC2size);
1426 surfaceVectorField n(
mesh.Sf() /
mesh.magSf());
1427 for (label
i = 0;
i < P3_BC1size;
i++)
1429 for (label j = 0; j < P3_BC2size; j++)
1431 surfaceVectorField BC3 = fvc::interpolate(fvc::curl(
L_U_SUPmodes[j])).ref();
1432 surfaceVectorField BC4 = (n^ fvc::interpolate(fvc::grad(
Pmodes[
i]))).ref();
1433 surfaceScalarField BC5 = ((BC3& BC4) *
mesh.magSf()).ref();
1435 for (label k = 0; k < BC5.boundaryField().size(); k++)
1437 s += gSum(BC5.boundaryField()[k]);
1444 if (Pstream::master())
1456 Eigen::MatrixXd
BC4_matrix(P4_BC1size, P4_BC2size);
1458 surfaceVectorField n(
mesh.Sf() /
mesh.magSf());
1460 for (label
i = 0;
i < P4_BC1size;
i++)
1462 for (label j = 0; j < P4_BC2size; j++)
1464 surfaceScalarField BC3 = fvc::interpolate(
Pmodes[
i]).ref();
1465 surfaceScalarField BC4 = (n & fvc::interpolate(
L_U_SUPmodes[j])).ref();
1466 surfaceScalarField BC5 = ((BC3 * BC4) *
mesh.magSf()).ref();
1469 for (label k = 0; k < BC5.boundaryField().size(); k++)
1471 s += gSum(BC5.boundaryField()[k]);
1478 if (Pstream::master())
1493 for (label j = 0; j <
inletIndex.rows(); j++)
1498 for (label k = 0; k <
inletIndex.rows(); k++)
1503 for (label
i = 0;
i < BCsize;
i++)
1510 if (Pstream::master())
1513 "./ITHACAoutput/Matrices/bcVelVec");
1524 List <Eigen::MatrixXd>
bcVelMat(BCUsize);
1526 for (label j = 0; j <
inletIndex.rows(); j++)
1528 bcVelMat[j].resize(BCsize, BCsize);
1531 for (label k = 0; k <
inletIndex.rows(); k++)
1536 for (label
i = 0;
i < BCsize;
i++)
1538 for (label j = 0; j < BCsize; j++)
1542 L_U_SUPmodes[j].boundaryField()[BCind].component(BCcomp));
1547 if (Pstream::master())
1550 "./ITHACAoutput/Matrices/bcVelMat");
1561 Eigen::MatrixXd
BP_matrix(BPsize1, BPsize2);
1564 for (label
i = 0;
i < BPsize1;
i++)
1566 for (label j = 0; j < BPsize2; j++)
1568 L_U_SUPmodesaux =
dt_dummy * fvc::laplacian(
1571 fvc::div(L_U_SUPmodesaux)).value();
1575 if (Pstream::master())
1587 Eigen::VectorXd ModeVector;
1590 List <Eigen::MatrixXd>
RD_matrix(BCsize);
1591 Eigen::SparseMatrix<double>
A;
1594 for (label
i = 0;
i < BCsize;
i++)
1597 Vector<double>
v(0, 0, 0);
1599 volVectorField Upara(
Uinl());
1609 for (label j = 0; j < RDsize; j++)
1612 RD_matrix[
i](j, 0) = ModeVector.dot(b.col(0));
1615 if (Pstream::parRun())
1617 reduce(
RD_matrix[
i], sumOp<Eigen::MatrixXd>());
1620 if (Pstream::master())
1633 Eigen::VectorXd ModeVector;
1636 List <Eigen::MatrixXd>
RC_matrix(BCsize);
1637 Eigen::SparseMatrix<double>
A;
1640 for (label
i = 0;
i < BCsize;
i++)
1643 Vector<double>
v(0, 0, 0);
1645 volVectorField Upara(
Uinl());
1650 fvm::div(fvc::flux(Upara), Upara)
1655 for (label j = 0; j < RCsize; j++)
1658 RC_matrix[
i](j, 0) = ModeVector.dot(b.col(0));
1661 if (Pstream::parRun())
1663 reduce(
RC_matrix[
i], sumOp<Eigen::MatrixXd>());
1666 if (Pstream::master())
1683 Cf_tensor.resize(Csize2, Csize1, Csize1);
1685 for (label
i = 0;
i < Csize2;
i++)
1687 for (label j = 0; j < Csize1; j++)
1689 for (label k = 0; k < Csize1; k++)
1693 L_U_SUPmodesaux =
dt_dummy * (fvc::div(
1699 L_U_SUPmodesaux =
dt_dummy * (fvc::div(
1705 * fvc::div(L_U_SUPmodesaux)).value();
1710 if (Pstream::master())
1723 List<Eigen::MatrixXd> LinSysDivDummy;
1725 volScalarField
p(
_p());
1727 for (label
i = 0;
i < BCsize;
i++)
1730 Vector<double>
v(0, 0, 0);
1732 volVectorField Upara(
Uinl());
1736 fvm::laplacian(
p) == (1.0 /
dt_dummy) * fvc::div(Upara)
1738 pEqn.setReference(0, 0);
1756 List<Eigen::MatrixXd> LinSysConvDummy;
1758 volScalarField
p(
_p());
1760 for (label
i = 0;
i < BCsize;
i++)
1763 Vector<double>
v(0, 0, 0);
1765 volVectorField Upara(
Uinl());
1768 Caux =
dt_dummy * (-fvc::div(fvc::flux(Upara), Upara));
1771 fvm::laplacian(
p) == (1.0 /
dt_dummy) * fvc::div(Caux)
1773 pEqn.setReference(0, 0);
1791 List<Eigen::MatrixXd> LinSysDiffDummy;
1793 volScalarField
p(
_p());
1795 for (label
i = 0;
i < BCsize;
i++)
1798 Vector<double>
v(0, 0, 0);
1800 volVectorField Upara(
Uinl());
1806 fvm::laplacian(
p) == (1.0 /
dt_dummy) * fvc::div(Daux)
1808 pEqn.setReference(0, 0);
1832 volVectorField CoeffA = (fvc::reconstruct(
L_PHImodes[
i])).ref();
1834 for (label j = 0; j < Isize; j++)
1836 surfaceScalarField B = fvc::flux(
L_U_SUPmodes[j]).ref();
1837 volVectorField CoeffB = fvc::reconstruct(B).ref();
1838 I_matrix(
i, j) = fvc::domainIntegrate(CoeffA & CoeffB).value();
1842 if (Pstream::master())
1858 surfaceScalarField phi_tmp(
"Phi_tmp",
_phi());
1862 for (label j = 0; j < DFsize; j++)
1865 dimensionedScalar(
"1", dimless, 1),
1867 volVectorField CoeffB = fvc::reconstruct(phi_tmp).ref();
1868 volVectorField CoeffA = fvc::reconstruct(
L_PHImodes[
i]).ref();
1869 DF_matrix(
i, j) = fvc::domainIntegrate(CoeffA & CoeffB).value();
1873 if (Pstream::master())
1876 "DF_" + name(
NUmodes) +
"_" + name(
1889 Eigen::MatrixXd
KF_matrix(KF1size, KF2size);
1891 for (label
i = 0;
i < KF1size;
i++)
1893 for (label j = 0; j < KF2size; j++)
1895 volVectorField CoeffA = (fvc::reconstruct(
dt_dummy * fvc::snGrad(
1897 volVectorField CoeffB = fvc::reconstruct(
L_PHImodes[
i]).ref();
1898 KF_matrix(
i, j) = fvc::domainIntegrate(CoeffA & CoeffB).value();
1902 if (Pstream::master())
1905 "KF_" + name(
NUmodes) +
"_" + name(
1920 surfaceScalarField phi_tmp(
"Phi_tmp",
_phi());
1924 for (label j = 0; j < Csize1; j++)
1926 for (label k = 0; k < Csize1; k++)
1929 volVectorField CoeffA = fvc::reconstruct(phi_tmp).ref();
1930 volVectorField CoeffB = fvc::reconstruct(
L_PHImodes[j]).ref();
1931 Ci_tensor(
i, j, k) = fvc::domainIntegrate(CoeffB & CoeffA).value();
1936 if (Pstream::master())
1952 List <Eigen::MatrixXd>
SD_matrix(BCsize);
1953 surfaceScalarField phi_tmp(
"Phi_tmp",
_phi());
1955 for (label
i = 0;
i < BCsize;
i++)
1958 Vector<double>
v(0, 0, 0);
1960 volVectorField Upara(
Uinl());
1965 for (label j = 0; j < SDsize; j++)
1967 volVectorField CoeffB = fvc::reconstruct(
L_PHImodes[j]).ref();
1969 volVectorField CoeffA = fvc::reconstruct(phi_tmp).ref();
1970 SD_matrix[
i](j, 0) = fvc::domainIntegrate(CoeffA & CoeffB).value();
1986 List <Eigen::MatrixXd>
SC_matrix(BCsize);
1987 surfaceScalarField phi_tmp(
"Phi_tmp",
_phi());
1989 for (label
i = 0;
i < BCsize;
i++)
1992 Vector<double>
v(0, 0, 0);
1994 volVectorField Upara(
Uinl());
1999 for (label j = 0; j < SCsize; j++)
2001 volVectorField CoeffB = fvc::reconstruct(
L_PHImodes[j]).ref();
2002 phi_tmp =
dt_dummy * fvc::flux(fvc::div(fvc::flux(Upara), Upara));
2003 volVectorField CoeffA = fvc::reconstruct(phi_tmp).ref();
2004 SC_matrix[
i](j, 0) = fvc::domainIntegrate(CoeffA & CoeffB).value();
2023 volVectorField
A = fvc::reconstruct(
L_PHImodes[
i]).ref();
2025 for (label j = 0; j <
NUmodes; j++)
2027 volVectorField B = fvc::reconstruct(
L_PHImodes[j]).ref();
2028 W_matrix(
i, j) = fvc::domainIntegrate(
A & B).value();
2041 volScalarField& ciao =
const_cast<volScalarField&
>(
nu);
2044 for (label
i = 0;
i < ciao.boundaryFieldRef().size();
i++)
2058 instantList Times =
runTime.times();
2060 volScalarField&
p =
_p();
2061 volVectorField&
U =
_U();
2063 IOdictionary FORCESdict
2070 IOobject::MUST_READ,
2078 "transportProperties",
2081 IOobject::MUST_READ,
2085 word pName(FORCESdict.lookup(
"pName"));
2086 word UName(FORCESdict.lookup(
"UName"));
2087 functionObjects::ITHACAforces f(
"Forces",
mesh, FORCESdict);
2095 f.calcForcesMoment();
2097 for (label j = 0; j < 3; j++)
2109 f.calcForcesMoment();
2111 for (label j = 0; j < 3; j++)
2113 nMatrix(
i, j) = f.forcePressure()[j];
2117 if (
para->exportPython)
2120 "./ITHACAoutput/Matrices/");
2124 if (
para->exportMatlab)
2127 "./ITHACAoutput/Matrices/");
2131 if (
para->exportTxt)
2134 "./ITHACAoutput/Matrices/");
2146 instantList Times =
runTime.times();
2148 volScalarField&
p =
_p();
2149 volVectorField&
U =
_U();
2151 IOdictionary FORCESdict
2158 IOobject::MUST_READ,
2166 "transportProperties",
2169 IOobject::MUST_READ,
2173 word pName(FORCESdict.lookup(
"pName"));
2174 word UName(FORCESdict.lookup(
"UName"));
2175 functionObjects::ITHACAforces f(
"Forces",
mesh, FORCESdict);
2177 for (label
i = 0;
i < nModes;
i++)
2183 f.calcForcesMoment();
2185 for (label j = 0; j < 3; j++)
2191 for (label
i = 0;
i < nModes;
i++)
2197 f.calcForcesMoment();
2199 for (label j = 0; j < 3; j++)
2201 nMatrix(
i, j) = f.forcePressure()[j];
2205 if (
para->exportPython)
2208 "./ITHACAoutput/Matrices/");
2212 if (
para->exportMatlab)
2215 "./ITHACAoutput/Matrices/");
2219 if (
para->exportTxt)
2222 "./ITHACAoutput/Matrices/");
2228 const Eigen::MatrixXd& pressureCoeffs, fileName folder)
2231 "The number of velocity modes in the coefficients matrix is not equal to the number of modes in the viscous forces matrix.");
2233 "The number of pressure modes in the coefficients matrix is not equal to the number of modes in the pressure forces matrix.");
2235 system(
"ln -s ../../constant " + folder +
"/constant");
2236 system(
"ln -s ../../0 " + folder +
"/0");
2237 system(
"ln -s ../../system " + folder +
"/system");
2239 IOdictionary FORCESdict
2246 IOobject::MUST_READ,
2250 Eigen::MatrixXd fTau;
2252 fTau.setZero(velCoeffs.rows(), 3);
2253 fN.setZero(pressureCoeffs.rows(), 3);
2255 fN = pressureCoeffs *
nMatrix;
2258 if (
para->exportPython)
2264 if (
para->exportMatlab)
2270 if (
para->exportTxt)
2289 argList& args =
_args();
2301 Info <<
"ReReading field p\n" << endl;
2302 _p = autoPtr<volScalarField>
2311 IOobject::MUST_READ,
2312 IOobject::AUTO_WRITE
2317 volScalarField&
p =
_p();
2318 Info <<
"ReReading field U\n" << endl;
2319 _U = autoPtr<volVectorField>
2328 IOobject::MUST_READ,
2329 IOobject::AUTO_WRITE
2334 volVectorField&
U =
_U();
2335 Info <<
"ReReading/calculating face flux field phi\n" << endl;
2336 _phi = autoPtr<surfaceScalarField>
2338 new surfaceScalarField
2345 IOobject::READ_IF_PRESENT,
2346 IOobject::AUTO_WRITE
2348 linearInterpolate(
U) &
mesh.Sf()
2351 surfaceScalarField&
phi =
_phi();
2357 new singlePhaseTransportModel(
U,
phi )
2360 turbulence = autoPtr<incompressible::turbulenceModel>
2364 _MRF = autoPtr<IOMRFZoneList>
2366 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.
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.
Eigen::Tensor< double, 3 > convective_term_tens_cache(label NUmodes, label NPmodes, label NSUPmodes)
Export convective term as a tensor using the cached procedure.
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.
Eigen::Tensor< double, 3 > divMomentum_cache(label NUmodes, label NPmodes)
Divergence of convective term (PPE approach) using the cached procedure.
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.
Eigen::MatrixXd L_matrix
Convective background / Large scale advection term.
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.
Eigen::MatrixXd divergent_convective_background(label NPmodes, label NUmodes, volVectorField vls)
Divergent of Large Scale / Background Advection.
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 L_D_matrix
Divergent convective background / Large scale advection term.
Eigen::MatrixXd M_matrix
Mass Matrix.
List< Eigen::MatrixXd > BC2_matrix
PPE BC2.
autoPtr< volVectorField > Uinl
Initial dummy field with all Dirichlet boundary conditions.
Eigen::MatrixXd convective_background(label NUmodes, volVectorField vls)
Large Scale / Background Advection.
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.
PtrList< volScalarField > liftfieldP
List of pointer used to form the list of lifting functions for the pressure.
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.
void save(const Eigen::Matrix< T, -1, dim > &mat, const std::string fname)
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.