56 for (
int k = 0; k <
problem->liftfield.size(); k++)
61 for (
int k = 0; k <
problem->NUmodes; k++)
66 for (
int k = 0; k <
problem->NSUPmodes; k++)
72 for (
int k = 0; k <
problem->NPmodes; k++)
78 for (
int k = 0; k <
problem->nNutModes; k++)
100 Eigen::VectorXd& fvec)
const
102 Eigen::VectorXd a_dot(
Nphi_u);
103 Eigen::VectorXd aTmp(
Nphi_u);
104 Eigen::VectorXd bTmp(
Nphi_p);
109 if (
problem->timeDerivativeSchemeOrder ==
"first")
120 Eigen::MatrixXd cc(1, 1);
122 Eigen::VectorXd m1 =
problem->bTotalMatrix * aTmp *
nu;
124 Eigen::VectorXd m2 =
problem->K_matrix * bTmp;
126 Eigen::VectorXd m5 =
problem->M_matrix * a_dot;
128 Eigen::VectorXd m3 =
problem->P_matrix * aTmp;
130 Eigen::MatrixXd penaltyU = Eigen::MatrixXd::Zero(
Nphi_u,
N_BC);
133 if (
problem->bcMethod ==
"penalty")
135 for (
int l = 0; l <
N_BC; l++)
145 i) * aTmp -
gNut.transpose() *
147 fvec(
i) = - m5(
i) + m1(
i) - cc(0, 0) - m2(
i);
149 if (
problem->bcMethod ==
"penalty")
151 fvec(
i) += ((penaltyU *
tauU)(
i, 0));
155 for (
int j = 0; j <
Nphi_p; j++)
161 if (
problem->bcMethod ==
"lift")
163 for (
int j = 0; j <
N_BC; j++)
165 fvec(j) = x(j) -
bc(j);
174 Eigen::MatrixXd& fjac)
const
176 Eigen::NumericalDiff<newtonUnsteadyNSTurbSUP> numDiff(*
this);
183 Eigen::VectorXd& fvec)
const
185 Eigen::VectorXd a_dot(
Nphi_u);
186 Eigen::VectorXd aTmp(
Nphi_u);
187 Eigen::VectorXd bTmp(
Nphi_p);
192 if (
problem->timeDerivativeSchemeOrder ==
"first")
203 Eigen::MatrixXd cc(1, 1);
205 Eigen::VectorXd m1 =
problem->bTotalMatrix * aTmp *
nu;
207 Eigen::VectorXd m2 =
problem->K_matrix * bTmp;
209 Eigen::VectorXd m5 =
problem->M_matrix * a_dot;
211 Eigen::VectorXd m3 =
problem->P_matrix * aTmp;
213 Eigen::MatrixXd penaltyU = Eigen::MatrixXd::Zero(
Nphi_u,
N_BC);
216 if (
problem->bcMethod ==
"penalty")
218 for (
int l = 0; l <
N_BC; l++)
228 i) * aTmp -
gNut.transpose() *
232 fvec(
i) = - m5(
i) + m1(
i) - cc(0, 0) - m2(
i);
234 if (
problem->bcMethod ==
"penalty")
236 fvec(
i) += ((penaltyU *
tauU)(
i, 0));
240 for (
int j = 0; j <
Nphi_p; j++)
246 if (
problem->bcMethod ==
"lift")
248 for (
int j = 0; j <
N_BC; j++)
250 fvec(j) = x(j) -
bc(j);
259 Eigen::MatrixXd& fjac)
const
261 Eigen::NumericalDiff<newtonUnsteadyNSTurbSUPAve> numDiff(*
this);
270 Eigen::VectorXd& fvec)
const
272 Eigen::VectorXd a_dot(
Nphi_u);
273 Eigen::VectorXd aTmp(
Nphi_u);
274 Eigen::VectorXd bTmp(
Nphi_p);
279 if (
problem->timeDerivativeSchemeOrder ==
"first")
290 Eigen::MatrixXd cc(1, 1);
291 Eigen::MatrixXd gg(1, 1);
292 Eigen::MatrixXd bb(1, 1);
294 Eigen::VectorXd m1 =
problem->bTotalMatrix * aTmp *
nu;
296 Eigen::VectorXd m2 =
problem->K_matrix * bTmp;
298 Eigen::VectorXd m5 =
problem->M_matrix * a_dot;
300 Eigen::VectorXd m3 =
problem->D_matrix * bTmp;
302 Eigen::VectorXd m6 =
problem->BC1_matrix * aTmp *
nu;
304 Eigen::VectorXd m7 =
problem->BC3_matrix * aTmp *
nu;
306 Eigen::MatrixXd penaltyU = Eigen::MatrixXd::Zero(
Nphi_u,
N_BC);
309 if (
problem->bcMethod ==
"penalty")
311 for (
int l = 0; l <
N_BC; l++)
321 i) * aTmp -
gNut.transpose() *
323 fvec(
i) = - m5(
i) + m1(
i) - cc(0, 0) - m2(
i);
325 if (
problem->bcMethod ==
"penalty")
327 fvec(
i) += ((penaltyU *
tauU)(
i, 0));
331 for (
int j = 0; j <
Nphi_p; j++)
339 fvec(k) = m3(j, 0) + gg(0, 0) - m7(j, 0);
342 if (
problem->bcMethod ==
"lift")
344 for (
int j = 0; j <
N_BC; j++)
346 fvec(j) = x(j) -
bc(j);
355 Eigen::MatrixXd& fjac)
const
357 Eigen::NumericalDiff<newtonUnsteadyNSTurbPPE> numDiff(*
this);
363 Eigen::VectorXd& fvec)
const
365 Eigen::VectorXd a_dot(
Nphi_u);
366 Eigen::VectorXd aTmp(
Nphi_u);
367 Eigen::VectorXd bTmp(
Nphi_p);
372 if (
problem->timeDerivativeSchemeOrder ==
"first")
383 Eigen::MatrixXd cc(1, 1);
384 Eigen::MatrixXd gg(1, 1);
385 Eigen::MatrixXd bb(1, 1);
386 Eigen::MatrixXd nn(1, 1);
388 Eigen::VectorXd m1 =
problem->bTotalMatrix * aTmp *
nu;
390 Eigen::VectorXd m2 =
problem->K_matrix * bTmp;
392 Eigen::VectorXd m5 =
problem->M_matrix * a_dot;
396 Eigen::VectorXd m3 =
problem->D_matrix * bTmp;
398 Eigen::VectorXd m6 =
problem->BC1_matrix * aTmp *
nu;
400 Eigen::VectorXd m7 =
problem->BC3_matrix * aTmp *
nu;
402 Eigen::MatrixXd penaltyU = Eigen::MatrixXd::Zero(
Nphi_u,
N_BC);
405 if (
problem->bcMethod ==
"penalty")
407 for (
int l = 0; l <
N_BC; l++)
417 i) * aTmp -
gNut.transpose() *
421 fvec(
i) = - m5(
i) + m1(
i) - cc(0, 0) - m2(
i);
423 if (
problem->bcMethod ==
"penalty")
425 fvec(
i) += ((penaltyU *
tauU)(
i, 0));
429 for (
int j = 0; j <
Nphi_p; j++)
436 nn =
gNut.transpose() *
438 j) * aTmp +
gNutAve.transpose() *
441 fvec(k) = m3(j, 0) + gg(0, 0) - m7(j, 0) - nn(0, 0);
445 if (
problem->bcMethod ==
"lift")
447 for (
int j = 0; j <
N_BC; j++)
449 fvec(j) = x(j) -
bc(j);
458 Eigen::MatrixXd& fjac)
const
460 Eigen::NumericalDiff<newtonUnsteadyNSTurbPPEAve> numDiff(*
this);
470 "The time step dt must be smaller than exportEvery.");
472 "The time step dt must be smaller than storeEvery.");
474 "The variable storeEvery must be an integer multiple of the time step dt.");
476 "The variable exportEvery must be an integer multiple of the time step dt.");
478 "The variable exportEvery must be an integer multiple of the variable storeEvery.");
481 if (
problem->bcMethod ==
"lift")
485 else if (
problem->bcMethod ==
"penalty")
506 if (
problem->bcMethod ==
"lift")
508 for (
int j = 0; j <
N_BC; j++)
534 for (
int j = 0; j <
N_BC; j++)
541 int onlineSize =
static_cast<int>(Ntsteps / numberOfStores);
551 tmp_sol.col(0).tail(
y.rows()) =
y;
561 nextStore += numberOfStores;
565 Eigen::HybridNonLinearSolver<newtonUnsteadyNSTurbSUP> hnls(
newtonObjectSUP);
575 Eigen::VectorXd res(
y);
580 Eigen::VectorXd aDer;
587 tv <<
y.segment(firstRBFInd,
dimA);
595 tv <<
y.segment(firstRBFInd,
dimA / 2), aDer.segment(firstRBFInd,
dimA / 2);
600 aDer.segment(firstRBFInd, (
dimA -
muStar.size()) / 2);
604 tv <<
y.segment(firstRBFInd,
dimA);
614 if (
problem->bcMethod ==
"lift")
616 for (
int j = 0; j <
N_BC; j++)
626 " ##################" << std::endl;
627 Info <<
"Time = " <<
time << endl;
628 std::cout <<
"Solving for the parameter: " <<
vel_now << std::endl;
630 if (res.norm() < 1e-5)
632 std::cout << green <<
"|F(x)| = " << res.norm() <<
" - Minimun reached in " <<
633 hnls.iter <<
" iterations " << def << std::endl << std::endl;
637 std::cout << red <<
"|F(x)| = " << res.norm() <<
" - Minimun reached in " <<
638 hnls.iter <<
" iterations " << def << std::endl << std::endl;
643 tmp_sol.col(0).tail(
y.rows()) =
y;
645 if (counter == nextStore)
658 nextStore += numberOfStores;
667 "./ITHACAoutput/red_coeff");
669 "./ITHACAoutput/red_coeff");
676 "The time step dt must be smaller than exportEvery.");
678 "The time step dt must be smaller than storeEvery.");
680 "The variable storeEvery must be an integer multiple of the time step dt.");
682 "The variable exportEvery must be an integer multiple of the time step dt.");
684 "The variable exportEvery must be an integer multiple of the variable storeEvery.");
687 if (
problem->bcMethod ==
"lift")
691 else if (
problem->bcMethod ==
"penalty")
706 if (
problem->bcMethod ==
"lift")
708 for (
int j = 0; j <
N_BC; j++)
735 for (
int j = 0; j <
N_BC; j++)
742 int onlineSize =
static_cast<int>(Ntsteps / numberOfStores);
752 tmp_sol.col(0).tail(
y.rows()) =
y;
762 nextStore += numberOfStores;
766 Eigen::HybridNonLinearSolver<newtonUnsteadyNSTurbSUPAve> hnls(
777 Eigen::VectorXd res(
y);
782 Eigen::VectorXd aDer;
789 tv <<
y.segment(firstRBFInd,
dimA);
797 tv <<
y.segment(firstRBFInd,
dimA / 2), aDer.segment(firstRBFInd,
dimA / 2);
802 aDer.segment(firstRBFInd, (
dimA -
muStar.size()) / 2);
806 tv <<
y.segment(firstRBFInd,
dimA);
816 if (
problem->bcMethod ==
"lift")
818 for (
int j = 0; j <
N_BC; j++)
827 " ##################" << std::endl;
828 Info <<
"Time = " <<
time << endl;
829 std::cout <<
"Solving for the parameter: " <<
vel_now << std::endl;
831 if (res.norm() < 1e-5)
833 std::cout << green <<
"|F(x)| = " << res.norm() <<
" - Minimun reached in " <<
834 hnls.iter <<
" iterations " << def << std::endl << std::endl;
838 std::cout << red <<
"|F(x)| = " << res.norm() <<
" - Minimun reached in " <<
839 hnls.iter <<
" iterations " << def << std::endl << std::endl;
844 tmp_sol.col(0).tail(
y.rows()) =
y;
846 if (counter == nextStore)
859 nextStore += numberOfStores;
868 "./ITHACAoutput/red_coeff");
870 "./ITHACAoutput/red_coeff");
878 "The time step dt must be smaller than exportEvery.");
880 "The time step dt must be smaller than storeEvery.");
882 "The variable storeEvery must be an integer multiple of the time step dt.");
884 "The variable exportEvery must be an integer multiple of the time step dt.");
886 "The variable exportEvery must be an integer multiple of the variable storeEvery.");
889 if (
problem->bcMethod ==
"lift")
893 else if (
problem->bcMethod ==
"penalty")
908 if (
problem->bcMethod ==
"lift")
910 for (
int j = 0; j <
N_BC; j++)
936 for (
int j = 0; j <
N_BC; j++)
943 int onlineSize =
static_cast<int>(Ntsteps / numberOfStores);
953 tmp_sol.col(0).tail(
y.rows()) =
y;
963 nextStore += numberOfStores;
967 Eigen::HybridNonLinearSolver<newtonUnsteadyNSTurbPPE> hnls(
newtonObjectPPE);
977 Eigen::VectorXd res(
y);
982 Eigen::VectorXd aDer;
989 tv <<
y.segment(firstRBFInd,
dimA);
997 tv <<
y.segment(firstRBFInd,
dimA / 2), aDer.segment(firstRBFInd,
dimA / 2);
1002 aDer.segment(firstRBFInd, (
dimA -
muStar.size()) / 2);
1006 tv <<
y.segment(firstRBFInd,
dimA);
1019 " ##################" << std::endl;
1020 Info <<
"Time = " <<
time << endl;
1021 std::cout <<
"Solving for the parameter: " <<
vel_now << std::endl;
1023 if (res.norm() < 1e-5)
1025 std::cout << green <<
"|F(x)| = " << res.norm() <<
" - Minimun reached in " <<
1026 hnls.iter <<
" iterations " << def << std::endl << std::endl;
1030 std::cout << red <<
"|F(x)| = " << res.norm() <<
" - Minimun reached in " <<
1031 hnls.iter <<
" iterations " << def << std::endl << std::endl;
1036 tmp_sol.col(0).tail(
y.rows()) =
y;
1038 if (counter == nextStore)
1051 nextStore += numberOfStores;
1060 "./ITHACAoutput/red_coeff");
1062 "./ITHACAoutput/red_coeff");
1069 "The time step dt must be smaller than exportEvery.");
1071 "The time step dt must be smaller than storeEvery.");
1073 "The variable storeEvery must be an integer multiple of the time step dt.");
1075 "The variable exportEvery must be an integer multiple of the time step dt.");
1077 "The variable exportEvery must be an integer multiple of the variable storeEvery.");
1080 if (
problem->bcMethod ==
"lift")
1084 else if (
problem->bcMethod ==
"penalty")
1099 if (
problem->bcMethod ==
"lift")
1101 for (
int j = 0; j <
N_BC; j++)
1128 for (
int j = 0; j <
N_BC; j++)
1135 int onlineSize =
static_cast<int>(Ntsteps / numberOfStores);
1145 tmp_sol.col(0).tail(
y.rows()) =
y;
1155 nextStore += numberOfStores;
1159 Eigen::HybridNonLinearSolver<newtonUnsteadyNSTurbPPEAve> hnls(
1170 Eigen::VectorXd res(
y);
1175 Eigen::VectorXd aDer;
1182 tv <<
y.segment(firstRBFInd,
dimA);
1190 tv <<
y.segment(firstRBFInd,
dimA / 2), aDer.segment(firstRBFInd,
dimA / 2);
1195 aDer.segment(firstRBFInd, (
dimA -
muStar.size()) / 2);
1199 tv <<
y.segment(firstRBFInd,
dimA);
1209 if (
problem->bcMethod ==
"lift")
1211 for (
int j = 0; j <
N_BC; j++)
1220 " ##################" << std::endl;
1221 Info <<
"Time = " <<
time << endl;
1222 std::cout <<
"Solving for the parameter: " <<
vel_now << std::endl;
1224 if (res.norm() < 1e-5)
1226 std::cout << green <<
"|F(x)| = " << res.norm() <<
" - Minimun reached in " <<
1227 hnls.iter <<
" iterations " << def << std::endl << std::endl;
1231 std::cout << red <<
"|F(x)| = " << res.norm() <<
" - Minimun reached in " <<
1232 hnls.iter <<
" iterations " << def << std::endl << std::endl;
1237 tmp_sol.col(0).tail(
y.rows()) =
y;
1239 if (counter == nextStore)
1252 nextStore += numberOfStores;
1261 "./ITHACAoutput/red_coeff");
1263 "./ITHACAoutput/red_coeff");
1279 volScalarField nutAveNow(
"nutAveNow",
nutModes[0] * 0);
1280 List < Eigen::MatrixXd> CoeffU;
1281 List < Eigen::MatrixXd> CoeffP;
1282 List < Eigen::MatrixXd> CoeffNut;
1287 for (
int k = 0; k <
problem->nutAve.size(); k++)
1294 if (counter == nextWrite)
1296 Eigen::MatrixXd currentUCoeff;
1297 Eigen::MatrixXd currentPCoeff;
1298 Eigen::MatrixXd currentNutCoeff;
1302 CoeffU.append(currentUCoeff);
1303 CoeffP.append(currentPCoeff);
1304 CoeffNut.append(currentNutCoeff);
1305 nextWrite += exportEveryIndex;
1311 volVectorField uRec(
"uRec",
Umodes[0]);
1312 volScalarField pRec(
"pRec",
problem->Pmodes[0]);
1313 volScalarField nutRec(
"nutRec",
problem->nutModes[0]);
1336 assert(
problem->inletIndex.rows() == vel.rows()
1337 &&
"Imposed boundary conditions dimensions do not match given values matrix dimensions");
1338 Eigen::MatrixXd vel_scal;
1339 vel_scal.resize(vel.rows(), vel.cols());
1341 for (
int k = 0; k <
problem->inletIndex.rows(); k++)
1344 int l =
problem->inletIndex(k, 1);
1345 scalar area = gSum(
problem->liftfield[0].mesh().magSf().boundaryField()[
p]);
1346 scalar u_lf = gSum(
problem->liftfield[k].mesh().magSf().boundaryField()[
p] *
1347 problem->liftfield[k].boundaryField()[
p]).component(l) / area;
1348 vel_scal(k, 0) = vel(k, 0) / u_lf;
#define M_Assert(Expr, Msg)
Header file of the ReducedUnsteadyNSTurb class.
Class to change color to the output stream.
void solveOnlinePPEAve(Eigen::MatrixXd velNow)
Method to perform an online solve using a PPE stabilisation method with the use of the average splitt...
ReducedUnsteadyNSTurb()
Construct Null.
int nphiNut
Number of viscosity modes.
newtonUnsteadyNSTurbSUP newtonObjectSUP
Function object to call the non linear solver sup approach.
newtonUnsteadyNSTurbSUPAve newtonObjectSUPAve
Function object to call the non linear solver sup approach with the splitting of the eddy viscosity.
PtrList< volScalarField > nutRecFields
Reconstructed eddy viscosity fields list.
void solveOnlineSUPAve(Eigen::MatrixXd velNow)
Method to perform an online solve using a supremizer stabilisation method with the use of the average...
Eigen::MatrixXd rbfCoeffMat
The matrix of the eddy viscosity RBF interoplated coefficients.
bool skipLift
Interpolation boolean variable to skip lifting functions.
int dimA
Dimension of the interpolation independent variable.
Eigen::VectorXd muStar
Online parameter value.
Eigen::MatrixXd initCond
The matrix of the initial velocity and pressure reduced coefficients.
Eigen::VectorXd gNutAve
The reduced average vector for viscosity coefficients.
void solveOnlineSUP(Eigen::MatrixXd velNow)
Method to perform an online solve using a supremizer stabilisation method.
int interChoice
Interpolation independent variable choice.
newtonUnsteadyNSTurbPPE newtonObjectPPE
Function object to call the non linear solver PPE approach.
void reconstruct(bool exportFields=false, fileName folder="./online_rec")
Method to reconstruct the solutions from an online solve with any of the two techniques SUP or the PP...
PtrList< volScalarField > nutModes
List of pointers to store the modes for the eddy viscosity.
void solveOnlinePPE(Eigen::MatrixXd velNow)
Method to perform an online solve using a PPE stabilisation method.
UnsteadyNSTurb * problem
Pointer to the FOM problem.
newtonUnsteadyNSTurbPPEAve newtonObjectPPEAve
Function object to call the non linear solver PPE approach with the splitting of the eddy viscosity.
Eigen::MatrixXd setOnlineVelocity(Eigen::MatrixXd vel)
Sets the online velocity.
Eigen::VectorXd nut0
The initial eddy viscosity reduced coefficients.
Implementation of a parametrized full order unsteady NS problem and preparation of the the reduced ...
Eigen::VectorXd y
Vector to store the solution during the Newton procedure.
PtrList< volScalarField > Pmodes
List of pointers to store the modes for pressure.
List< Eigen::MatrixXd > online_solution
List of Eigen matrices to store the online solution.
int Nphi_p
Number of pressure modes.
scalar nu
Reduced viscosity in case of parametrized viscosity.
Eigen::MatrixXd tauU
Penalty Factor.
PtrList< volScalarField > pRecFields
Reconstructed pressure fields list.
int count_online_solve
Counter to count the online solutions.
Eigen::MatrixXd vel_now
Online inlet velocity vector.
PtrList< volVectorField > Umodes
List of pointers to store the modes for velocity.
PtrList< volVectorField > uRecFields
Recontructed velocity fields list.
int N_BC
Number of parametrized boundary conditions.
int Nphi_u
Number of velocity modes.
bool startFromZero
A variable for starting solving the reduced system from zero or not.
double exportEvery
A variable for exporting the fields.
scalar finalTime
Scalar to store the final time if the online simulation.
scalar tstart
Scalar to store the initial time if the online simulation.
scalar time
Scalar to store the current time.
double dt
Scalar to store the time increment.
double storeEvery
A variable for storing the reduced coefficients.
Matrix< VectorType, Dynamic, Dynamic > SliceFromTensor(Eigen::Tensor< VectorType, 3 > &tensor, label dim, label index1)
void exportFields(PtrList< GeometricField< Type, PatchField, GeoMesh > > &field, word folder, word fieldname)
Function to export a scalar of vector field.
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 ...
Eigen::VectorXd getCoeffs(GeometricField< Type, PatchField, GeoMesh > &snapshot, PtrList< GeometricField< Type, PatchField, GeoMesh > > &modes, label Nmodes, bool consider_volumes)
Projects a snapshot on a basis function and gets the coefficients of the projection.
bool isInteger(double ratio)
This function checks if ratio is an integer.
void createSymLink(word folder)
Creates symbolic links to 0, system and constant.
int operator()(const Eigen::VectorXd &x, Eigen::VectorXd &fvec) const
int df(const Eigen::VectorXd &x, Eigen::MatrixXd &fjac) const
int operator()(const Eigen::VectorXd &x, Eigen::VectorXd &fvec) const
int df(const Eigen::VectorXd &x, Eigen::MatrixXd &fjac) const
int df(const Eigen::VectorXd &x, Eigen::MatrixXd &fjac) const
int operator()(const Eigen::VectorXd &x, Eigen::VectorXd &fvec) const
int df(const Eigen::VectorXd &x, Eigen::MatrixXd &fjac) const
int operator()(const Eigen::VectorXd &x, Eigen::VectorXd &fvec) const