52 for (
int k = 0; k <
problem->liftfield.size(); k++)
57 for (
int k = 0; k <
problem->NUmodes; k++)
62 for (
int k = 0; k <
problem->NSUPmodes; k++)
71 Eigen::VectorXd& fvec)
const
73 Eigen::VectorXd a_tmp(
Nphi_u);
74 Eigen::VectorXd b_tmp(
Nphi_p);
78 Eigen::MatrixXd cc(1, 1);
80 Eigen::VectorXd M1 =
problem->B_matrix * a_tmp *
nu;
82 Eigen::VectorXd M2 =
problem->K_matrix * b_tmp;
84 Eigen::VectorXd M3 =
problem->P_matrix * a_tmp;
86 Eigen::MatrixXd penaltyU = Eigen::MatrixXd::Zero(
Nphi_u,
N_BC);
89 if (
problem->bcMethod ==
"penalty")
91 for (
int l = 0; l <
N_BC; l++)
102 fvec(
i) = M1(
i) - cc(0, 0) - M2(
i);
104 if (
problem->bcMethod ==
"penalty")
106 fvec(
i) += (penaltyU.row(
i) *
tauU)(0, 0);
110 for (
int j = 0; j <
Nphi_p; j++)
116 if (
problem->bcMethod ==
"lift")
118 for (
int j = 0; j <
N_BC; j++)
120 fvec(j) = x(j) -
BC(j);
129 Eigen::MatrixXd& fjac)
const
131 Eigen::NumericalDiff<newton_steadyNS> numDiff(*
this);
141 Info <<
"This function is still not implemented for the stationary case" <<
148 if (
problem->bcMethod ==
"lift")
152 else if (
problem->bcMethod ==
"penalty")
159 "The BC method must be set to lift or penalty in ITHACAdict");
166 if (
problem->bcMethod ==
"lift")
168 for (
int j = 0; j <
N_BC; j++)
177 Eigen::HybridNonLinearSolver<newton_steadyNS> hnls(
newton_object);
181 for (
int j = 0; j <
N_BC; j++)
188 Eigen::VectorXd res(
y);
191 " ##################" << endl;
193 if (Pstream::master())
195 std::cout <<
"Solving for the parameter: " <<
vel_now << std::endl;
198 if (res.norm() < 1e-5 && Pstream::master())
200 std::cout << green <<
"|F(x)| = " << res.norm() <<
" - Minimun reached in " <<
201 hnls.iter <<
" iterations " << def << std::endl << std::endl;
203 else if (Pstream::master())
205 std::cout << red <<
"|F(x)| = " << res.norm() <<
" - Minimun reached in " <<
206 hnls.iter <<
" iterations " << def << std::endl << std::endl;
224 if (counter == nextwrite)
226 volVectorField U_rec(
"U_rec",
Umodes[0] * 0);
228 for (
int j = 0; j <
Nphi_u; j++)
234 volScalarField P_rec(
"P_rec",
problem->Pmodes[0] * 0);
236 for (
int j = 0; j <
Nphi_p; j++)
242 nextwrite += printevery;
260 List <Eigen::MatrixXd> CoeffU;
261 List <Eigen::MatrixXd> CoeffP;
267 if (counter == nextwrite)
269 Eigen::MatrixXd currentUCoeff;
270 Eigen::MatrixXd currentPCoeff;
273 CoeffU.append(currentUCoeff);
274 CoeffP.append(currentPCoeff);
275 nextwrite += printevery;
281 volVectorField uRec(
"uRec",
Umodes[0]);
282 volScalarField pRec(
"pRec",
problem->Pmodes[0]);
298 Eigen::VectorXd sup(
Nphi_u);
299 Eigen::VectorXd inf(
Nphi_p);
303 for (
int j = 0; j <
Nphi_u; j++)
305 sup(j) = fvc::domainIntegrate(fvc::div(
Umodes[j]) *
Pmodes[
i]).value() /
309 inf(
i) = sup.maxCoeff();
321 system(
"ln -s ../../constant " + folder +
"/constant");
322 system(
"ln -s ../../0 " + folder +
"/0");
323 system(
"ln -s ../../system " + folder +
"/system");
325 int NSUPmodes =
problem.NSUPmodes;
327 int liftfieldSize =
problem.liftfield.size();
328 int totalSize = NUmodes + NSUPmodes + liftfieldSize;
332 IOdictionary FORCESdict
348 for (
int j = 0; j < totalSize; j++)
353 for (
int j = 0; j < NPmodes; j++)
360 if (
para->exportPython)
366 if (
para->exportMatlab)
381 assert(
problem->inletIndex.rows() == vel.rows()
382 &&
"Imposed boundary conditions dimensions do not match given values matrix dimensions");
383 Eigen::MatrixXd vel_scal;
384 vel_scal.resize(vel.rows(), vel.cols());
386 for (
int k = 0; k <
problem->inletIndex.rows(); k++)
389 int l =
problem->inletIndex(k, 1);
390 scalar area = gSum(
problem->liftfield[0].mesh().magSf().boundaryField()[
p]);
391 scalar u_lf = gSum(
problem->liftfield[k].mesh().magSf().boundaryField()[
p] *
392 problem->liftfield[k].boundaryField()[
p]).component(l) / area;
393 vel_scal(k, 0) = vel(k, 0) / u_lf;
#define M_Assert(Expr, Msg)
Header file of the reducedSteadyNS class.
Class to change color to the output stream.
static ITHACAparameters * getInstance()
Gets an instance of ITHACAparameters, to be used if the instance is already existing.
Eigen::VectorXd y
Vector to store the solution during the Newton procedure.
ITHACAparameters * para
parameters to be read from the ITHACAdict file
Eigen::MatrixXd setOnlineVelocity(Eigen::MatrixXd vel)
Sets the online velocity.
void solveOnline_sup(Eigen::MatrixXd vel_now)
Method to perform an online solve using a supremizer stabilisation method.
Eigen::MatrixXd fTau
Reduced matrix for tangent forces.
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.
void reconstructLiftAndDrag(steadyNS &problem, fileName folder)
Method to compute the reduced order forces.
void solveOnline_PPE(Eigen::MatrixXd vel_now)
Method to perform an online solve using a PPE stabilisation method.
PtrList< volScalarField > pRecFields
Reconstructed pressure fields list.
steadyNS * problem
Pointer to the FOM problem.
int count_online_solve
Counter to count the online solutions.
reducedSteadyNS()
Construct Null.
Eigen::MatrixXd vel_now
Online inlet velocity vector.
Eigen::MatrixXd fN
Reduced matrix for normal forces.
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.
void reconstruct_PPE(fileName folder="./ITHACAoutput/online_rec", int printevery=1)
Method to reconstruct a solution from an online solve with a PPE stabilisation technique.
double inf_sup_constant()
Method to evaluate the online inf-sup constant.
int Nphi_u
Number of velocity modes.
void reconstruct(bool exportFields=false, fileName folder="./ITHACAoutput/online_rec", int printevery=1)
Method to reconstruct the solutions from an online solve.
newton_steadyNS newton_object
Newton object used to solve the non linear problem.
Implementation of a parametrized full order steady NS problem and preparation of the the reduced ma...
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 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 ...
double H1Seminorm(GeometricField< scalar, fvPatchField, volMesh > &field)
double L2Norm(GeometricField< scalar, fvPatchField, volMesh > &field)
void createSymLink(word folder)
Creates symbolic links to 0, system and constant.
Structure to implement a newton object for a stationary NS problem.
int operator()(const Eigen::VectorXd &x, Eigen::VectorXd &fvec) const
int df(const Eigen::VectorXd &x, Eigen::MatrixXd &fjac) const