Loading...
Searching...
No Matches
ReducedSteadyNSTurb.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ██╗████████╗██╗ ██╗ █████╗ ██████╗ █████╗ ███████╗██╗ ██╗
3 ██║╚══██╔══╝██║ ██║██╔══██╗██╔════╝██╔══██╗ ██╔════╝██║ ██║
4 ██║ ██║ ███████║███████║██║ ███████║█████╗█████╗ ██║ ██║
5 ██║ ██║ ██╔══██║██╔══██║██║ ██╔══██║╚════╝██╔══╝ ╚██╗ ██╔╝
6 ██║ ██║ ██║ ██║██║ ██║╚██████╗██║ ██║ ██║ ╚████╔╝
7 ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚═══╝
8
9 * In real Time Highly Advanced Computational Applications for Finite Volumes
10 * Copyright (C) 2017 by the ITHACA-FV authors
11-------------------------------------------------------------------------------
12
13License
14 This file is part of ITHACA-FV
15
16 ITHACA-FV is free software: you can redistribute it and/or modify
17 it under the terms of the GNU Lesser General Public License as published by
18 the Free Software Foundation, either version 3 of the License, or
19 (at your option) any later version.
20
21 ITHACA-FV is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU Lesser General Public License for more details.
25
26 You should have received a copy of the GNU Lesser General Public License
27 along with ITHACA-FV. If not, see <http://www.gnu.org/licenses/>.
28
29\*---------------------------------------------------------------------------*/
30
31#include "ReducedSteadyNSTurb.H"
32
33// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * //
34
35// Constructor
39
41 :
42 problem(&fomProblem)
43{
44 N_BC = problem->inletIndex.rows();
45 Nphi_u = problem->B_matrix.rows();
46 Nphi_p = problem->K_matrix.cols();
47 nphiNut = problem->cTotalTensor.dimension(1);
48
49 for (int k = 0; k < problem->liftfield.size(); k++)
50 {
51 Umodes.append((problem->liftfield[k]).clone());
52 }
53
54 for (int k = 0; k < problem->NUmodes; k++)
55 {
56 Umodes.append((problem->Umodes[k]).clone());
57 }
58
59 for (int k = 0; k < problem->NSUPmodes; k++)
60 {
61 Umodes.append((problem->supmodes[k]).clone());
62 }
63
65 fomProblem);
67 fomProblem);
68}
69
70int newtonSteadyNSTurbSUP::operator()(const Eigen::VectorXd& x,
71 Eigen::VectorXd& fvec) const
72{
73 Eigen::VectorXd aTmp(Nphi_u);
74 Eigen::VectorXd bTmp(Nphi_p);
75 aTmp = x.head(Nphi_u);
76 bTmp = x.tail(Nphi_p);
77 // Convective term
78 Eigen::MatrixXd cc(1, 1);
79 // Mom Term
80 Eigen::VectorXd m1 = problem->bTotalMatrix * aTmp * nu;
81 // Gradient of pressure
82 Eigen::VectorXd m2 = problem->K_matrix * bTmp;
83 // Pressure Term
84 Eigen::VectorXd m3 = problem->P_matrix * aTmp;
85 // Penalty term
86 Eigen::MatrixXd penaltyU = Eigen::MatrixXd::Zero(Nphi_u, N_BC);
87
88 // Term for penalty method
89 if (problem->bcMethod == "penalty")
90 {
91 for (int l = 0; l < N_BC; l++)
92 {
93 penaltyU.col(l) = bc(l) * problem->bcVelVec[l] - problem->bcVelMat[l] *
94 aTmp;
95 }
96 }
97
98 for (int i = 0; i < Nphi_u; i++)
99 {
100 cc = aTmp.transpose() * Eigen::SliceFromTensor(problem->C_tensor, 0,
101 i) * aTmp - gNut.transpose() *
103 fvec(i) = m1(i) - cc(0, 0) - m2(i);
104
105 if (problem->bcMethod == "penalty")
106 {
107 fvec(i) += ((penaltyU * tauU)(i, 0));
108 }
109 }
110
111 for (int j = 0; j < Nphi_p; j++)
112 {
113 int k = j + Nphi_u;
114 fvec(k) = m3(j);
115 }
116
117 if (problem->bcMethod == "lift")
118 {
119 for (int j = 0; j < N_BC; j++)
120 {
121 fvec(j) = x(j) - bc(j);
122 }
123 }
124
125 return 0;
126}
127
128int newtonSteadyNSTurbPPE::operator()(const Eigen::VectorXd& x,
129 Eigen::VectorXd& fvec) const
130{
131 Eigen::VectorXd aTmp(Nphi_u);
132 Eigen::VectorXd bTmp(Nphi_p);
133 aTmp = x.head(Nphi_u);
134 bTmp = x.tail(Nphi_p);
135 // Convective term
136 Eigen::MatrixXd cc(1, 1);
137 Eigen::MatrixXd gg(1, 1);
138 Eigen::MatrixXd bb(1, 1);
139 // Mom Term
140 Eigen::VectorXd m1 = problem->bTotalMatrix * aTmp * nu;
141 // Gradient of pressure
142 Eigen::VectorXd m2 = problem->K_matrix * bTmp;
143 // Pressure Term
144 Eigen::VectorXd m3 = problem->D_matrix * bTmp;
145 // BC PPE
146 Eigen::VectorXd m7 = problem->BC3_matrix * aTmp * nu;
147 // Penalty term
148 Eigen::MatrixXd penaltyU = Eigen::MatrixXd::Zero(Nphi_u, N_BC);
149
150 // Term for penalty method
151 if (problem->bcMethod == "penalty")
152 {
153 for (int l = 0; l < N_BC; l++)
154 {
155 penaltyU.col(l) = bc(l) * problem->bcVelVec[l] - problem->bcVelMat[l] *
156 aTmp;
157 }
158 }
159
160 for (int i = 0; i < Nphi_u; i++)
161 {
162 cc = aTmp.transpose() * Eigen::SliceFromTensor(problem->C_tensor, 0,
163 i) * aTmp - gNut.transpose() *
165 fvec(i) = m1(i) - cc(0, 0) - m2(i);
166
167 if (problem->bcMethod == "penalty")
168 {
169 fvec(i) += ((penaltyU * tauU)(i, 0));
170 }
171 }
172
173 for (int j = 0; j < Nphi_p; j++)
174 {
175 int k = j + Nphi_u;
176 gg = aTmp.transpose() * Eigen::SliceFromTensor(problem->gTensor, 0,
177 j) * aTmp;
178 //fvec(k) = m3(j, 0) - gg(0, 0) - m6(j, 0) + bb(0, 0);
179 fvec(k) = m3(j, 0) + gg(0, 0) - m7(j, 0);
180 }
181
182 if (problem->bcMethod == "lift")
183 {
184 for (int j = 0; j < N_BC; j++)
185 {
186 fvec(j) = x(j) - bc(j);
187 }
188 }
189
190 return 0;
191}
192
193
194int newtonSteadyNSTurbSUP::df(const Eigen::VectorXd& x,
195 Eigen::MatrixXd& fjac) const
196{
197 Eigen::NumericalDiff<newtonSteadyNSTurbSUP> numDiff(*this);
198 numDiff.df(x, fjac);
199 return 0;
200}
201
202int newtonSteadyNSTurbPPE::df(const Eigen::VectorXd& x,
203 Eigen::MatrixXd& fjac) const
204{
205 Eigen::NumericalDiff<newtonSteadyNSTurbPPE> numDiff(*this);
206 numDiff.df(x, fjac);
207 return 0;
208}
209
210// * * * * * * * * * * * * * * * Solve Functions * * * * * * * * * * * * * //
211
212void ReducedSteadyNSTurb::solveOnlineSUP(Eigen::MatrixXd vel)
213{
214 if (problem->bcMethod == "lift")
215 {
217 }
218 else if (problem->bcMethod == "penalty")
219 {
220 vel_now = vel;
221 }
222
223 y.resize(Nphi_u + Nphi_p, 1);
224 y.setZero();
225
226 // Change initial condition for the lifting function
227 if (problem->bcMethod == "lift")
228 {
229 for (int j = 0; j < N_BC; j++)
230 {
231 y(j) = vel_now(j, 0);
232 }
233 }
234
238 Eigen::HybridNonLinearSolver<newtonSteadyNSTurbSUP> hnls(newtonObjectSUP);
239 newtonObjectSUP.bc.resize(N_BC);
241
242 for (int j = 0; j < N_BC; j++)
243 {
244 newtonObjectSUP.bc(j) = vel_now(j, 0);
245 }
246
247 if (problem->viscCoeff == "L2")
248 {
249 for (int i = 0; i < nphiNut; i++)
250 {
252 }
253 }
254 else if (problem->viscCoeff == "RBF")
255 {
256 for (int i = 0; i < nphiNut; i++)
257 {
260 }
261 }
262 else
263 {
264 Info << "The way to compute the eddy viscosity coefficients has to be either L2 or RBF"
265 << endl;
266 exit(0);
267 }
268
270 hnls.solve(y);
271 Eigen::VectorXd res(y);
272 newtonObjectSUP.operator()(y, res);
273 std::cout << "################## Online solve N° " << count_online_solve <<
274 " ##################" << std::endl;
275 std::cout << "Solving for the parameter: " << vel_now << std::endl;
276
277 if (res.norm() < 1e-5)
278 {
279 std::cout << green << "|F(x)| = " << res.norm() << " - Minimun reached in " <<
280 hnls.iter << " iterations " << def << std::endl << std::endl;
281 }
282 else
283 {
284 std::cout << red << "|F(x)| = " << res.norm() << " - Minimun reached in " <<
285 hnls.iter << " iterations " << def << std::endl << std::endl;
286 }
287
289}
290
291void ReducedSteadyNSTurb::solveOnlinePPE(Eigen::MatrixXd vel)
292{
293 if (problem->bcMethod == "lift")
294 {
296 }
297 else if (problem->bcMethod == "penalty")
298 {
299 vel_now = vel;
300 }
301
302 y.resize(Nphi_u + Nphi_p, 1);
303 y.setZero();
304
305 // Change initial condition for the lifting function
306 if (problem->bcMethod == "lift")
307 {
308 for (int j = 0; j < N_BC; j++)
309 {
310 y(j) = vel_now(j, 0);
311 }
312 }
313
317 Eigen::HybridNonLinearSolver<newtonSteadyNSTurbPPE> hnls(newtonObjectPPE);
318 newtonObjectPPE.bc.resize(N_BC);
320
321 for (int j = 0; j < N_BC; j++)
322 {
323 newtonObjectPPE.bc(j) = vel_now(j, 0);
324 }
325
326 if (problem->viscCoeff == "L2")
327 {
328 for (int i = 0; i < nphiNut; i++)
329 {
331 }
332 }
333 else if (problem->viscCoeff == "RBF")
334 {
335 for (int i = 0; i < nphiNut; i++)
336 {
339 }
340 }
341 else
342 {
343 Info << "The way to compute the eddy viscosity coefficients has to be either L2 or RBF"
344 << endl;
345 exit(0);
346 }
347
349 hnls.solve(y);
350 Eigen::VectorXd res(y);
351 newtonObjectPPE.operator()(y, res);
352 std::cout << "################## Online solve N° " << count_online_solve <<
353 " ##################" << std::endl;
354 std::cout << "Solving for the parameter: " << vel_now << std::endl;
355
356 if (res.norm() < 1e-5)
357 {
358 std::cout << green << "|F(x)| = " << res.norm() << " - Minimun reached in " <<
359 hnls.iter << " iterations " << def << std::endl << std::endl;
360 }
361 else
362 {
363 std::cout << red << "|F(x)| = " << res.norm() << " - Minimun reached in " <<
364 hnls.iter << " iterations " << def << std::endl << std::endl;
365 }
366
368}
369
370void ReducedSteadyNSTurb::reconstruct(bool exportFields, fileName folder,
371 int printevery)
372{
373 if (exportFields)
374 {
375 mkDir(folder);
377 }
378
379 int counter = 0;
380 int nextWrite = 0;
381 List <Eigen::MatrixXd> CoeffU;
382 List <Eigen::MatrixXd> CoeffP;
383 List <Eigen::MatrixXd> CoeffNut;
384 CoeffU.resize(0);
385 CoeffP.resize(0);
386 CoeffNut.resize(0);
387
388 for (int i = 0; i < online_solution.size(); i++)
389 {
390 if (counter == nextWrite)
391 {
392 Eigen::MatrixXd currentUCoeff;
393 Eigen::MatrixXd currentPCoeff;
394 Eigen::MatrixXd currentNutCoeff;
395 currentUCoeff = online_solution[i].block(1, 0, Nphi_u, 1);
396 currentPCoeff = online_solution[i].bottomRows(Nphi_p);
397 currentNutCoeff = rbfCoeffMat.block(0, i, nphiNut, 1);
398 CoeffU.append(currentUCoeff);
399 CoeffP.append(currentPCoeff);
400 CoeffNut.append(currentNutCoeff);
401 nextWrite += printevery;
402 }
403
404 counter++;
405 }
406
407 volVectorField uRec("uRec", Umodes[0]);
408 volScalarField pRec("pRec", problem->Pmodes[0]);
409 volScalarField nutRec("nutRec", problem->nutModes[0]);
410 uRecFields = problem->L_U_SUPmodes.reconstruct(uRec, CoeffU, "uRec");
411 pRecFields = problem->Pmodes.reconstruct(pRec, CoeffP, "pRec");
412 nutRecFields = problem->nutModes.reconstruct(nutRec, CoeffNut, "nutRec");
413
414 if (exportFields)
415 {
417 "uRec");
419 "pRec");
421 "nutRec");
422 }
423}
424
425Eigen::MatrixXd ReducedSteadyNSTurb::setOnlineVelocity(Eigen::MatrixXd vel)
426{
427 assert(problem->inletIndex.rows() == vel.rows()
428 && "Imposed boundary conditions dimensions do not match given values matrix dimensions");
429 Eigen::MatrixXd vel_scal;
430 vel_scal.resize(vel.rows(), vel.cols());
431
432 for (int k = 0; k < problem->inletIndex.rows(); k++)
433 {
434 int p = problem->inletIndex(k, 0);
435 int l = problem->inletIndex(k, 1);
436 scalar area = gSum(problem->liftfield[0].mesh().magSf().boundaryField()[p]);
437 scalar u_lf = gSum(problem->liftfield[k].mesh().magSf().boundaryField()[p] *
438 problem->liftfield[k].boundaryField()[p]).component(l) / area;
439 vel_scal(k, 0) = vel(k, 0) / u_lf;
440 }
441
442 return vel_scal;
443}
444// ************************************************************************* //
445
Header file of the ReducedSteadyNSTurb class.
Class to change color to the output stream.
Definition colormod.H:24
GeometricField< Type, PatchField, GeoMesh > reconstruct(GeometricField< Type, PatchField, GeoMesh > &inputField, Eigen::MatrixXd Coeff, word Name)
Function to reconstruct the solution starting from the coefficients, in this case the field is passed...
Definition Modes.C:275
PtrList< volScalarField > nutRecFields
Reconstructed eddy viscosity fields list.
newtonSteadyNSTurbSUP newtonObjectSUP
Newton Object to solve the nonlinear problem sup approach.
newtonSteadyNSTurbPPE newtonObjectPPE
Newton Object to solve the nonlinear problem PPE approach.
void solveOnlinePPE(Eigen::MatrixXd velNow)
Method to perform an online solve using a PPE stabilisation method.
ReducedSteadyNSTurb()
Construct Null.
int nphiNut
Number of viscosity modes.
Eigen::MatrixXd rbfCoeffMat
The matrix of the eddy viscosity RBF interoplated coefficients.
void solveOnlineSUP(Eigen::MatrixXd velNow)
Method to perform an online solve using a supremizer stabilisation method.
SteadyNSTurb * problem
Pointer to the FOM problem.
void reconstruct(bool exportFields=false, fileName folder="./ITHACAoutput/online_rec", int printevery=1)
Method to reconstruct the solutions from an online solve.
Eigen::VectorXd rbfCoeff
Vector of eddy viscosity RBF interoplated coefficients.
Eigen::MatrixXd setOnlineVelocity(Eigen::MatrixXd vel)
Sets the online velocity.
Implementation of a parametrized full order steady turbulent Navier Stokes problem and preparation ...
Eigen::MatrixXd bTotalMatrix
Total B Matrix.
std::vector< SPLINTER::RBFSpline * > rbfSplines
Create a RBF splines for interpolation.
Eigen::Tensor< double, 3 > cTotalTensor
word viscCoeff
The way to compute the eddy viscosity snapshots.
Eigen::VectorXd nutCoeff
The vector of L2 projection coefficients for the eddy viscosity snapshot.
volScalarModes nutModes
List of POD modes for eddy viscosity.
Eigen::VectorXd y
Vector to store the solution during the Newton procedure.
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.
Eigen::MatrixXi inletIndex
Matrix that contains informations about the inlet boundaries.
List< Eigen::MatrixXd > bcVelVec
Boundary term for penalty method - vector.
Definition steadyNS.H:218
Eigen::MatrixXd BC3_matrix
PPE BC3.
Definition steadyNS.H:191
Eigen::Tensor< double, 3 > C_tensor
Diffusion term.
Definition steadyNS.H:167
volVectorModes supmodes
List of pointers used to form the supremizer modes.
Definition steadyNS.H:104
volVectorModes Umodes
List of pointers used to form the velocity modes.
Definition steadyNS.H:101
label NUmodes
Number of velocity modes used for the projection.
Definition steadyNS.H:140
PtrList< volVectorField > liftfield
List of pointers used to form the list of lifting functions.
Definition steadyNS.H:110
volVectorModes L_U_SUPmodes
List of pointers containing the total number of lift, supremizer and velocity modes.
Definition steadyNS.H:116
Eigen::MatrixXd B_matrix
Diffusion term.
Definition steadyNS.H:157
Eigen::MatrixXd D_matrix
Laplacian term PPE.
Definition steadyNS.H:173
label NSUPmodes
Number of supremizer modes used for the projection.
Definition steadyNS.H:146
Eigen::Tensor< double, 3 > gTensor
Divergence of momentum PPE.
Definition steadyNS.H:179
Eigen::MatrixXd K_matrix
Gradient of pressure matrix.
Definition steadyNS.H:163
List< Eigen::MatrixXd > bcVelMat
Boundary term for penalty method - matrix.
Definition steadyNS.H:221
Eigen::MatrixXd P_matrix
Div of velocity.
Definition steadyNS.H:170
volScalarModes Pmodes
List of pointers used to form the pressure modes.
Definition steadyNS.H:98
word bcMethod
Boundary Method.
Definition steadyNS.H:317
@ FG_GREEN
Definition colormod.H:14
@ FG_DEFAULT
Definition colormod.H:16
@ FG_RED
Definition colormod.H:13
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 createSymLink(word folder)
Creates symbolic links to 0, system and constant.
volScalarField & p
label i
Definition pEqn.H:46
int operator()(const Eigen::VectorXd &x, Eigen::VectorXd &fvec) const
int df(const Eigen::VectorXd &x, Eigen::MatrixXd &fjac) const
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