54 for (
int k = 0; k <
problem->liftfield.size(); k++)
59 for (
int k = 0; k <
problem->NUmodes; k++)
64 for (
int k = 0; k <
problem->NSUPmodes; k++)
70 for (
int k = 0; k <
problem->NPmodes; k++)
85 Eigen::VectorXd& fvec)
const
87 Eigen::VectorXd a_dot(
Nphi_u);
88 Eigen::VectorXd a_tmp(
Nphi_u);
89 Eigen::VectorXd b_tmp(
Nphi_p);
94 if (
problem->timeDerivativeSchemeOrder ==
"first")
105 Eigen::MatrixXd cc(1, 1);
107 Eigen::VectorXd M1 =
problem->B_matrix * a_tmp *
nu;
109 Eigen::VectorXd M2 =
problem->K_matrix * b_tmp;
111 Eigen::VectorXd M5 =
problem->M_matrix * a_dot;
113 Eigen::VectorXd M3 =
problem->P_matrix * a_tmp;
115 Eigen::MatrixXd penaltyU = Eigen::MatrixXd::Zero(
Nphi_u,
N_BC);
118 if (
problem->bcMethod ==
"penalty")
120 for (
int l = 0; l <
N_BC; l++)
122 penaltyU.col(l) =
tauU(l,
132 fvec(
i) = - M5(
i) + M1(
i) - cc(0, 0) - M2(
i);
134 if (
problem->bcMethod ==
"penalty")
136 for (
int l = 0; l <
N_BC; l++)
138 fvec(
i) += penaltyU(
i, l);
143 for (
int j = 0; j <
Nphi_p; j++)
149 if (
problem->bcMethod ==
"lift")
151 for (
int j = 0; j <
N_BC; j++)
153 fvec(j) = x(j) -
BC(j);
162 Eigen::MatrixXd& fjac)
const
164 Eigen::NumericalDiff<newton_unsteadyNS_sup> numDiff(*
this);
173 Eigen::VectorXd& fvec)
const
175 Eigen::VectorXd a_dot(
Nphi_u);
176 Eigen::VectorXd a_tmp(
Nphi_u);
177 Eigen::VectorXd b_tmp(
Nphi_p);
182 if (
problem->timeDerivativeSchemeOrder ==
"first")
193 Eigen::MatrixXd cc(1, 1);
194 Eigen::MatrixXd gg(1, 1);
196 Eigen::VectorXd M1 =
problem->B_matrix * a_tmp *
nu;
198 Eigen::VectorXd M2 =
problem->K_matrix * b_tmp;
200 Eigen::VectorXd M5 =
problem->M_matrix * a_dot;
202 Eigen::VectorXd M3 =
problem->D_matrix * b_tmp;
204 Eigen::VectorXd M7 =
problem->BC3_matrix * a_tmp *
nu;
206 Eigen::VectorXd M8 =
problem->BC4_matrix * a_dot;
208 Eigen::MatrixXd penaltyU = Eigen::MatrixXd::Zero(
Nphi_u,
N_BC);
211 if (
problem->bcMethod ==
"penalty")
213 for (
int l = 0; l <
N_BC; l++)
215 penaltyU.col(l) =
tauU(l,
225 fvec(
i) = - M5(
i) + M1(
i) - cc(0, 0) - M2(
i);
227 if (
problem->bcMethod ==
"penalty")
229 for (
int l = 0; l <
N_BC; l++)
231 fvec(
i) += penaltyU(
i, l);
236 for (
int j = 0; j <
Nphi_p; j++)
241 fvec(k) = M3(j, 0) + gg(0, 0) - M7(j, 0);
243 if (
problem->timedepbcMethod ==
"yes")
249 if (
problem->bcMethod ==
"lift")
251 for (
int j = 0; j <
N_BC; j++)
253 fvec(j) = x(j) -
BC(j);
262 Eigen::MatrixXd& fjac)
const
264 Eigen::NumericalDiff<newton_unsteadyNS_PPE> numDiff(*
this);
276 "The time step dt must be smaller than exportEvery.");
278 "The time step dt must be smaller than storeEvery.");
280 "The variable storeEvery must be an integer multiple of the time step dt.");
282 "The variable exportEvery must be an integer multiple of the time step dt.");
284 "The variable exportEvery must be an integer multiple of the variable storeEvery.");
287 if (
problem->bcMethod ==
"lift")
291 else if (
problem->bcMethod ==
"penalty")
307 if (
problem->bcMethod ==
"lift")
309 for (
int j = 0; j <
N_BC; j++)
323 for (
int j = 0; j <
N_BC; j++)
330 int onlineSize =
static_cast<int>(Ntsteps / numberOfStores);
339 tmp_sol.col(0).tail(
y.rows()) =
y;
343 nextStore += numberOfStores;
356 if (
problem->timedepbcMethod ==
"yes" )
358 for (
int j = 0; j <
N_BC; j++)
364 Eigen::VectorXd res(
y);
368 if (
problem->bcMethod ==
"lift")
370 for (
int j = 0; j <
N_BC; j++)
372 if (
problem->timedepbcMethod ==
"no" )
376 else if (
problem->timedepbcMethod ==
"yes" )
386 std::cout <<
"################## Online solve N° " << counter <<
387 " ##################" << std::endl;
388 Info <<
"Time = " <<
time << endl;
390 if (res.norm() < 1e-5)
392 std::cout << green <<
"|F(x)| = " << res.norm() <<
" - Minimun reached in " <<
393 hnls.iter <<
" iterations " << def << std::endl << std::endl;
397 std::cout << red <<
"|F(x)| = " << res.norm() <<
" - Minimun reached in " <<
398 hnls.iter <<
" iterations " << def << std::endl << std::endl;
402 tmp_sol.col(0).tail(
y.rows()) =
y;
404 if (counter == nextStore)
415 nextStore += numberOfStores;
424 "./ITHACAoutput/red_coeff");
426 "./ITHACAoutput/red_coeff");
435 "The time step dt must be smaller than exportEvery.");
437 "The time step dt must be smaller than storeEvery.");
439 "The variable storeEvery must be an integer multiple of the time step dt.");
441 "The variable exportEvery must be an integer multiple of the time step dt.");
443 "The variable exportEvery must be an integer multiple of the variable storeEvery.");
446 if (
problem->bcMethod ==
"lift")
450 else if (
problem->bcMethod ==
"penalty")
467 if (
problem->bcMethod ==
"lift")
469 for (
int j = 0; j <
N_BC; j++)
483 for (
int j = 0; j <
N_BC; j++)
490 int onlineSize =
static_cast<int>(Ntsteps / numberOfStores);
499 tmp_sol.col(0).tail(
y.rows()) =
y;
503 nextStore += numberOfStores;
517 if (
problem->timedepbcMethod ==
"yes" )
519 for (
int j = 0; j <
N_BC; j++)
525 Eigen::VectorXd res(
y);
529 if (
problem->bcMethod ==
"lift")
531 for (
int j = 0; j <
N_BC; j++)
533 if (
problem->timedepbcMethod ==
"no" )
537 else if (
problem->timedepbcMethod ==
"yes" )
547 std::cout <<
"################## Online solve N° " << counter <<
548 " ##################" << std::endl;
549 Info <<
"Time = " <<
time << endl;
551 if (res.norm() < 1e-5)
553 std::cout << green <<
"|F(x)| = " << res.norm() <<
" - Minimun reached in " <<
554 hnls.iter <<
" iterations " << def << std::endl << std::endl;
558 std::cout << red <<
"|F(x)| = " << res.norm() <<
" - Minimun reached in " <<
559 hnls.iter <<
" iterations " << def << std::endl << std::endl;
563 tmp_sol.col(0).tail(
y.rows()) =
y;
565 if (counter == nextStore)
576 nextStore += numberOfStores;
585 "./ITHACAoutput/red_coeff");
587 "./ITHACAoutput/red_coeff");
601 diffvel = diffvel.cwiseAbs();
608 for (
int j = 0; j <
N_BC; j++)
614 std::cout <<
"Solving for penalty factor(s): " <<
tauIter << std::endl;
615 std::cout <<
"number of iterations: " << Iter << std::endl;
632 for (
int j = 0; j <
N_BC; j++)
644 Eigen::VectorXd res(
y);
651 for (
int j = 0; j <
N_BC; j++)
653 if (
problem->timedepbcMethod ==
"yes" )
663 Eigen::VectorXd res(
y);
669 if (res.norm() < 1e-5)
671 std::cout << green <<
"|F(x)| = " << res.norm() <<
" - Minimun reached in " <<
672 hnls.iter <<
" iterations " << def << std::endl << std::endl;
676 std::cout << red <<
"|F(x)| = " << res.norm() <<
" - Minimun reached in " <<
677 hnls.iter <<
" iterations " << def << std::endl << std::endl;
680 volVectorField U_rec(
"U_rec",
Umodes[0] * 0);
682 for (
int j = 0; j <
Nphi_u; j++)
687 for (
int k = 0; k <
problem->inletIndex.rows(); k++)
689 int BCind =
problem->inletIndex(k, 0);
690 int BCcomp =
problem->inletIndex(k, 1);
691 valBC(k,
i) = U_rec.boundaryFieldRef()[BCind][0].component(BCcomp);
695 for (
int j = 0; j <
N_BC; j++)
701 std::cout <<
"max error: " << diffvel.maxCoeff() << std::endl;
706 std::cout <<
"Final penalty factor(s): " <<
tauIter << std::endl;
707 std::cout <<
"Iterations: " << Iter - 1 << std::endl;
722 diffvel = diffvel.cwiseAbs();
729 for (
int j = 0; j <
N_BC; j++)
735 std::cout <<
"Solving for penalty factor(s): " <<
tauIter << std::endl;
736 std::cout <<
"number of iterations: " << Iter << std::endl;
754 for (
int j = 0; j <
N_BC; j++)
766 Eigen::VectorXd res(
y);
773 for (
int j = 0; j <
N_BC; j++)
775 if (
problem->timedepbcMethod ==
"yes" )
785 Eigen::VectorXd res(
y);
792 if (res.norm() < 1e-5)
794 std::cout << green <<
"|F(x)| = " << res.norm() <<
" - Minimun reached in " <<
795 hnls.iter <<
" iterations " << def << std::endl << std::endl;
799 std::cout << red <<
"|F(x)| = " << res.norm() <<
" - Minimun reached in " <<
800 hnls.iter <<
" iterations " << def << std::endl << std::endl;
803 volVectorField U_rec(
"U_rec",
Umodes[0] * 0);
805 for (
int j = 0; j <
Nphi_u; j++)
810 for (
int k = 0; k <
problem->inletIndex.rows(); k++)
812 int BCind =
problem->inletIndex(k, 0);
813 int BCcomp =
problem->inletIndex(k, 1);
814 valBC(k,
i) = U_rec.boundaryFieldRef()[BCind][0].component(BCcomp);
818 for (
int j = 0; j <
N_BC; j++)
824 std::cout <<
"max error: " << diffvel.maxCoeff() << std::endl;
829 std::cout <<
"Final penalty factor(s): " <<
tauIter << std::endl;
830 std::cout <<
"Iterations: " << Iter - 1 << std::endl;
844 List < Eigen::MatrixXd> CoeffU;
845 List < Eigen::MatrixXd> CoeffP;
846 List <double> tValues;
854 if (counter == nextwrite)
856 Eigen::MatrixXd currentUCoeff;
857 Eigen::MatrixXd currentPCoeff;
860 CoeffU.append(currentUCoeff);
861 CoeffP.append(currentPCoeff);
862 nextwrite += exportEveryIndex;
864 tValues.append(timeNow);
870 volVectorField uRec(
"uRec",
Umodes[0] * 0);
871 volScalarField pRec(
"pRec",
problem->Pmodes[0] * 0);
886 assert(
problem->inletIndex.rows() == vel.rows()
887 &&
"Imposed boundary conditions dimensions do not match given values matrix dimensions");
888 Eigen::MatrixXd vel_scal;
889 vel_scal.resize(vel.rows(), vel.cols());
891 for (
int k = 0; k <
problem->inletIndex.rows(); k++)
894 int l =
problem->inletIndex(k, 1);
895 scalar area = gSum(
problem->liftfield[0].mesh().magSf().boundaryField()[
p]);
896 scalar u_lf = gSum(
problem->liftfield[k].mesh().magSf().boundaryField()[
p] *
897 problem->liftfield[k].boundaryField()[
p]).component(l) / area;
899 for (
int i = 0;
i < vel.cols();
i++)
901 vel_scal(k,
i) = vel(k,
i) / u_lf;
#define M_Assert(Expr, Msg)
Header file of the reducedUnsteadyNS class.
Class to change color to the output stream.
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.
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.
newton_unsteadyNS_PPE newton_object_PPE
Function object to call the non linear solver PPE approach.
Eigen::MatrixXd setOnlineVelocity(Eigen::MatrixXd vel)
Sets the online velocity.
double exportEvery
A variable for exporting the fields.
reducedUnsteadyNS()
Construct Null.
scalar tolerancePenalty
Tolerance for the residual of the boundary values, there is the same tolerance for velocity and tempe...
scalar finalTime
Scalar to store the final time if the online simulation.
Eigen::MatrixXd penalty_sup(Eigen::MatrixXd &vel_now, Eigen::MatrixXd &tauIter, int startSnap=0)
Method to determine the penalty factors iteratively.
newton_unsteadyNS_sup newton_object_sup
Function object to call the non linear solver sup approach.
int timeStepPenalty
Number of timesteps calculated for the iterative penalty method.
void solveOnline_PPE(Eigen::MatrixXd vel_now, int startSnap=0)
Method to perform an online solve using a PPE stabilisation method.
void solveOnline_sup(Eigen::MatrixXd vel_now, int startSnap=0)
Method to perform an online solve using a supremizer stabilisation method.
scalar tstart
Scalar to store the initial time if the online simulation.
void reconstruct(bool exportFields=false, fileName folder="./online_rec")
Method to reconstruct the solutions from an online solve with a supremizer stabilisation technique.
unsteadyNS * problem
Pointer to the FOM problem.
Eigen::MatrixXd tauIter
Penalty Factor determined with iterative solver.
scalar time
Scalar to store the current time.
scalar maxIterPenalty
Maximum number of iterations to be done for the computation of the penalty factor.
double dt
Scalar to store the time increment.
Eigen::MatrixXd penalty_PPE(Eigen::MatrixXd &vel_now, Eigen::MatrixXd &tauIter, int startSnap=0)
Method to determine the penalty factors iteratively.
double storeEvery
A variable for storing the reduced coefficients.
Implementation of a parametrized full order unsteady NS problem and preparation of the the reduced ...
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.
Newton object for the resolution of the reduced problem using a PPE approach.
int df(const Eigen::VectorXd &x, Eigen::MatrixXd &fjac) const
int operator()(const Eigen::VectorXd &x, Eigen::VectorXd &fvec) const
Newton object for the resolution of the reduced problem using a supremizer approach.
int df(const Eigen::VectorXd &x, Eigen::MatrixXd &fjac) const
int operator()(const Eigen::VectorXd &x, Eigen::VectorXd &fvec) const