Loading...
Searching...
No Matches
ReducedUnsteadyNSTurbIntrusive.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
33
34
36
37
38// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * //
39
40// Constructor
44
46 UnsteadyNSTurbIntrusive& fomProblem)
47{
48 problem = &fomProblem;
49 N_BC = problem->inletIndex.rows();
50 Nphi_u = problem->bMatrix.rows();
51 Nphi_p = problem->kMatrix.cols();
52
53 // Create locally the velocity modes
54 for (int k = 0; k < Nphi_u; k++)
55 {
56 Umodes.append((problem->Umodes[k]).clone());
57 }
58
59 // Create locally the pressure modes
60 for (int k = 0; k < Nphi_p; k++)
61 {
62 Pmodes.append((problem->Pmodes[k]).clone());
63 }
64
65 // Create locally the eddy viscosity modes
66 for (int k = 0; k < Nphi_u; k++)
67 {
68 nutModes.append((problem->nutModes[k]).clone());
69 }
70
71 // Store locally the snapshots for projections
72 for (int k = 0; k < problem->Ufield.size(); k++)
73 {
74 Usnapshots.append((problem->Ufield[k]).clone());
75 Psnapshots.append((problem->Pfield[k]).clone());
76 }
77
80 Nphi_u + Nphi_p, fomProblem);
81}
82
83
84// * * * * * * * * * * * * * * * Operators supremizer * * * * * * * * * * * * * //
85
86// Operator to evaluate the residual for the supremizer approach
87int newtonUnsteadyNSTurbIntrusive::operator()(const Eigen::VectorXd& x,
88 Eigen::VectorXd& fvec) const
89{
90 Eigen::VectorXd a_dot(Nphi_u);
91 Eigen::VectorXd aTmp(Nphi_u);
92 aTmp = x;
93
94 // Choose the order of the numerical difference scheme for approximating the time derivative
95 if (problem->timeDerivativeSchemeOrder == "first")
96 {
97 a_dot = (x - y_old) / dt;
98 }
99 else
100 {
101 a_dot = (1.5 * x - 2 * y_old + 0.5 * yOldOld) / dt;
102 }
103
104 // Convective term
105 Eigen::MatrixXd cc(1, 1);
106 // Mom Term
107 Eigen::VectorXd m1 = problem->bTotalMatrix * aTmp * nu;
108 // Gradient of pressure
109 Eigen::VectorXd m2 = problem->kMatrix * aTmp;
110 // Penalty term
111 Eigen::MatrixXd penaltyU = Eigen::MatrixXd::Zero(Nphi_u, N_BC);
112
113 // Term for penalty method
114 if (problem->bcMethod == "penalty")
115 {
116 for (int l = 0; l < N_BC; l++)
117 {
118 penaltyU.col(l) = bc(l) * problem->bcVelVec[l] - problem->bcVelMat[l] *
119 aTmp;
120 }
121 }
122
123 for (int i = 0; i < Nphi_u; i++)
124 {
125 cc = aTmp.transpose() * Eigen::SliceFromTensor(problem->cTotalTensor, 0,
126 i) * aTmp;
127 fvec(i) = - a_dot(i) + m1(i) - cc(0, 0) - m2(i);
128
129 if (problem->bcMethod == "penalty")
130 {
131 fvec(i) += ((penaltyU * tauU)(i, 0));
132 }
133 }
134
135 if (problem->bcMethod == "lift")
136 {
137 for (int j = 0; j < N_BC; j++)
138 {
139 fvec(j) = x(j) - bc(j);
140 }
141 }
142
143 return 0;
144}
145
146// Operator to evaluate the Jacobian for the supremizer approach
147int newtonUnsteadyNSTurbIntrusive::df(const Eigen::VectorXd& x,
148 Eigen::MatrixXd& fjac) const
149{
150 Eigen::NumericalDiff<newtonUnsteadyNSTurbIntrusive> numDiff(*this);
151 numDiff.df(x, fjac);
152 return 0;
153}
154
155// * * * * * * * * * * * * * * * Operators PPE * * * * * * * * * * * * * * * //
156
157// Operator to evaluate the residual for the supremizer approach
159 Eigen::VectorXd& fvec) const
160{
161 Eigen::VectorXd a_dot(Nphi_u);
162 Eigen::VectorXd aTmp(Nphi_u);
163 Eigen::VectorXd bTmp(Nphi_p);
164 aTmp = x.head(Nphi_u);
165 bTmp = x.tail(Nphi_p);
166
167 // Choose the order of the numerical difference scheme for approximating the time derivative
168 if (problem->timeDerivativeSchemeOrder == "first")
169 {
170 a_dot = (x.head(Nphi_u) - y_old.head(Nphi_u)) / dt;
171 }
172 else
173 {
174 a_dot = (1.5 * x.head(Nphi_u) - 2 * y_old.head(Nphi_u) + 0.5 * yOldOld.head(
175 Nphi_u)) / dt;
176 }
177
178 // Convective terms
179 Eigen::MatrixXd cc(1, 1);
180 Eigen::MatrixXd gg(1, 1);
181 Eigen::MatrixXd bb(1, 1);
182 Eigen::MatrixXd nn(1, 1);
183 // Mom Term
184 Eigen::VectorXd m1 = problem->bTotalMatrix * aTmp * nu;
185 // Gradient of pressure
186 Eigen::VectorXd m2 = problem->kMatrix * bTmp;
187 // Pressure Term
188 Eigen::VectorXd m3 = problem->D_matrix * bTmp;
189 // BC PPE
190 Eigen::VectorXd m6 = problem->BC1_matrix * aTmp * nu;
191 // BC PPE
192 Eigen::VectorXd m7 = problem->BC3_matrix * aTmp * nu;
193 // Penalty term
194 Eigen::MatrixXd penaltyU = Eigen::MatrixXd::Zero(Nphi_u, N_BC);
195
196 // Term for penalty method
197 if (problem->bcMethod == "penalty")
198 {
199 for (int l = 0; l < N_BC; l++)
200 {
201 penaltyU.col(l) = bc(l) * problem->bcVelVec[l] - problem->bcVelMat[l] *
202 aTmp;
203 }
204 }
205
206 for (int i = 0; i < Nphi_u; i++)
207 {
208 cc = aTmp.transpose() * Eigen::SliceFromTensor(problem->cTotalTensor, 0,
209 i) * aTmp;
210 fvec(i) = - a_dot(i) + m1(i) - cc(0, 0) - m2(i);
211
212 if (problem->bcMethod == "penalty")
213 {
214 fvec(i) += ((penaltyU * tauU)(i, 0));
215 }
216 }
217
218 for (int j = 0; j < Nphi_p; j++)
219 {
220 int k = j + Nphi_u;
221 gg = aTmp.transpose() * Eigen::SliceFromTensor(problem->gTensor, 0,
222 j) * aTmp;
223 bb = aTmp.transpose() * Eigen::SliceFromTensor(problem->bc2Tensor, 0,
224 j) * aTmp;
225 nn = aTmp.transpose() * Eigen::SliceFromTensor(problem->cTotalPPETensor, 0,
226 j) * aTmp;
227 fvec(k) = m3(j, 0) + gg(0, 0) - m7(j, 0) - nn(0, 0);
228 }
229
230 if (problem->bcMethod == "lift")
231 {
232 for (int j = 0; j < N_BC; j++)
233 {
234 fvec(j) = x(j) - bc(j);
235 }
236 }
237
238 return 0;
239}
240
241// Operator to evaluate the Jacobian for the supremizer approach
242int newtonUnsteadyNSTurbIntrusivePPE::df(const Eigen::VectorXd& x,
243 Eigen::MatrixXd& fjac) const
244{
245 Eigen::NumericalDiff<newtonUnsteadyNSTurbIntrusivePPE> numDiff(*this);
246 numDiff.df(x, fjac);
247 return 0;
248}
249
250
251
252// * * * * * * * * * * * * * * * Solve Functions * * * * * * * * * * * * * //
254{
256 "The time step dt must be smaller than exportEvery.");
258 "The time step dt must be smaller than storeEvery.");
260 "The variable storeEvery must be an integer multiple of the time step dt.");
262 "The variable exportEvery must be an integer multiple of the time step dt.");
264 "The variable exportEvery must be an integer multiple of the variable storeEvery.");
265 int numberOfStores = round(storeEvery / dt);
266
267 if (problem->bcMethod == "lift")
268 {
270 }
271 else if (problem->bcMethod == "penalty")
272 {
273 vel_now = vel;
274 }
275
276 // Create and resize the solution vector
277 y.resize(Nphi_u, 1);
278 y.setZero();
279 y = initCond.col(0);
280 int nextStore = 0;
281 int counter2 = 0;
282
283 // Change initial condition for the lifting function
284 if (problem->bcMethod == "lift")
285 {
286 for (int j = 0; j < N_BC; j++)
287 {
288 y(j) = vel_now(j, 0);
289 }
290 }
291
292 // Set some properties of the newton object
297 newtonObject.bc.resize(N_BC);
299
300 for (int j = 0; j < N_BC; j++)
301 {
302 newtonObject.bc(j) = vel_now(j, 0);
303 }
304
305 // Set number of online solutions
306 int Ntsteps = static_cast<int>((finalTime - tstart) / dt);
307 int onlineSize = static_cast<int>(Ntsteps / numberOfStores);
308 online_solution.resize(onlineSize);
309 // Set the initial time
310 time = tstart;
311 // Counting variable
312 int counter = 0;
313 // Create vector to store temporal solution and save initial condition as first solution
314 Eigen::MatrixXd tmp_sol(Nphi_u + 1, 1);
315 tmp_sol(0) = time;
316 tmp_sol.col(0).tail(y.rows()) = y;
317
318 if ((time != 0) || (startFromZero == true))
319 {
320 online_solution[counter] = tmp_sol;
321 counter ++;
322 counter2++;
323 nextStore += numberOfStores;
324 }
325
326 // Create nonlinear solver object
327 Eigen::HybridNonLinearSolver<newtonUnsteadyNSTurbIntrusive> hnls(
329 // Set output colors for fancy output
333
334 // Start the time loop
335 while (time < finalTime)
336 {
337 time = time + dt;
338 Eigen::VectorXd res(y);
339 res.setZero();
340 hnls.solve(y);
341
342 // Change initial condition for the lifting function
343 if (problem->bcMethod == "lift")
344 {
345 for (int j = 0; j < N_BC; j++)
346 {
347 y(j) = vel_now(j, 0);
348 }
349 }
350
351 newtonObject.operator()(y, res);
354 std::cout << "################## Online solve N° " << count_online_solve <<
355 " ##################" << std::endl;
356 Info << "Time = " << time << endl;
357 std::cout << "Solving for the parameter: " << vel_now << std::endl;
358
359 if (res.norm() < 1e-5)
360 {
361 std::cout << green << "|F(x)| = " << res.norm() << " - Minimun reached in " <<
362 hnls.iter << " iterations " << def << std::endl << std::endl;
363 }
364 else
365 {
366 std::cout << red << "|F(x)| = " << res.norm() << " - Minimun reached in " <<
367 hnls.iter << " iterations " << def << std::endl << std::endl;
368 }
369
371 tmp_sol(0) = time;
372 tmp_sol.col(0).tail(y.rows()) = y;
373
374 if (counter == nextStore)
375 {
376 if (counter2 >= online_solution.size())
377 {
378 online_solution.append(tmp_sol);
379 }
380 else
381 {
382 online_solution[counter2] = tmp_sol;
383 }
384
385 nextStore += numberOfStores;
386 counter2 ++;
387 }
388
389 counter ++;
390 }
391
392 // Save the solution
393 ITHACAstream::exportMatrix(online_solution, "red_coeff", "python",
394 "./ITHACAoutput/red_coeff");
395 ITHACAstream::exportMatrix(online_solution, "red_coeff", "matlab",
396 "./ITHACAoutput/red_coeff");
398}
399
401{
403 "The time step dt must be smaller than exportEvery.");
405 "The time step dt must be smaller than storeEvery.");
407 "The variable storeEvery must be an integer multiple of the time step dt.");
409 "The variable exportEvery must be an integer multiple of the time step dt.");
411 "The variable exportEvery must be an integer multiple of the variable storeEvery.");
412 int numberOfStores = round(storeEvery / dt);
413
414 if (problem->bcMethod == "lift")
415 {
417 }
418 else if (problem->bcMethod == "penalty")
419 {
420 vel_now = vel;
421 }
422
423 // Create and resize the solution vector
424 y.resize(Nphi_u + Nphi_p, 1);
425 y.setZero();
426 y.head(Nphi_u) = initCond.col(0).head(Nphi_u);
427 y.tail(Nphi_p) = initCond.col(0).tail(Nphi_p);
428 int nextStore = 0;
429 int counter2 = 0;
430
431 // Change initial condition for the lifting function
432 if (problem->bcMethod == "lift")
433 {
434 for (int j = 0; j < N_BC; j++)
435 {
436 y(j) = vel_now(j, 0);
437 }
438 }
439
440 // Set some properties of the newton object
445 newtonObjectPPE.bc.resize(N_BC);
447
448 for (int j = 0; j < N_BC; j++)
449 {
450 newtonObjectPPE.bc(j) = vel_now(j, 0);
451 }
452
453 // Set number of online solutions
454 int Ntsteps = static_cast<int>((finalTime - tstart) / dt);
455 int onlineSize = static_cast<int>(Ntsteps / numberOfStores);
456 online_solution.resize(onlineSize);
457 // Set the initial time
458 time = tstart;
459 // Counting variable
460 int counter = 0;
461 // Create vector to store temporal solution and save initial condition as first solution
462 Eigen::MatrixXd tmp_sol(Nphi_u + Nphi_p + 1, 1);
463 tmp_sol(0) = time;
464 tmp_sol.col(0).tail(y.rows()) = y;
465
466 if ((time != 0) || (startFromZero == true))
467 {
468 online_solution[counter] = tmp_sol;
469 counter ++;
470 counter2++;
471 nextStore += numberOfStores;
472 }
473
474 // Create nonlinear solver object
475 Eigen::HybridNonLinearSolver<newtonUnsteadyNSTurbIntrusivePPE> hnls(
477 // Set output colors for fancy output
481
482 // Start the time loop
483 while (time < finalTime)
484 {
485 time = time + dt;
486 Eigen::VectorXd res(y);
487 res.setZero();
488 hnls.solve(y);
489
490 // Change initial condition for the lifting function
491 if (problem->bcMethod == "lift")
492 {
493 for (int j = 0; j < N_BC; j++)
494 {
495 y(j) = vel_now(j, 0);
496 }
497 }
498
499 newtonObjectPPE.operator()(y, res);
502 std::cout << "################## Online solve N° " << count_online_solve <<
503 " ##################" << std::endl;
504 Info << "Time = " << time << endl;
505 std::cout << "Solving for the parameter: " << vel_now << std::endl;
506
507 if (res.norm() < 1e-5)
508 {
509 std::cout << green << "|F(x)| = " << res.norm() << " - Minimun reached in " <<
510 hnls.iter << " iterations " << def << std::endl << std::endl;
511 }
512 else
513 {
514 std::cout << red << "|F(x)| = " << res.norm() << " - Minimun reached in " <<
515 hnls.iter << " iterations " << def << std::endl << std::endl;
516 }
517
519 tmp_sol(0) = time;
520 tmp_sol.col(0).tail(y.rows()) = y;
521
522 if (counter == nextStore)
523 {
524 if (counter2 >= online_solution.size())
525 {
526 online_solution.append(tmp_sol);
527 }
528 else
529 {
530 online_solution[counter2] = tmp_sol;
531 }
532
533 nextStore += numberOfStores;
534 counter2 ++;
535 }
536
537 counter ++;
538 }
539
540 // Save the solution
541 ITHACAstream::exportMatrix(online_solution, "red_coeff", "python",
542 "./ITHACAoutput/red_coeff");
543 ITHACAstream::exportMatrix(online_solution, "red_coeff", "matlab",
544 "./ITHACAoutput/red_coeff");
546}
547
549 fileName folder)
550{
551 if (exportFields)
552 {
553 mkDir(folder);
555 }
556
557 int counter = 0;
558 int nextWrite = 0;
559 int counter2 = 1;
560 int exportEveryIndex = round(exportEvery / storeEvery);
561 volScalarField nutAveNow("nutAveNow", nutModes[0] * 0);
562 List < Eigen::MatrixXd> CoeffU;
563 List < Eigen::MatrixXd> CoeffP;
564 List < Eigen::MatrixXd> CoeffNut;
565 CoeffU.resize(0);
566 CoeffP.resize(0);
567 CoeffNut.resize(0);
568
569 for (int i = 0; i < online_solution.size(); i++)
570 {
571 if (counter == nextWrite)
572 {
573 Eigen::MatrixXd currentUCoeff;
574 Eigen::MatrixXd currentPCoeff;
575 Eigen::MatrixXd currentNutCoeff;
576 currentUCoeff = online_solution[i].bottomRows(Nphi_u);
577 currentPCoeff = online_solution[i].bottomRows(Nphi_u);
578 currentNutCoeff = online_solution[i].bottomRows(Nphi_u);
579 CoeffU.append(currentUCoeff);
580 CoeffP.append(currentPCoeff);
581 CoeffNut.append(currentNutCoeff);
582 nextWrite += exportEveryIndex;
583 }
584
585 counter++;
586 }
587
588 volVectorField uRec("uRec", Umodes[0]);
589 volScalarField pRec("pRec", problem->Pmodes[0]);
590 volScalarField nutRec("nutRec", problem->nutModes[0]);
591 uRecFields = problem->L_U_SUPmodes.reconstruct(uRec, CoeffU, "uRec");
592 pRecFields = problem->Pmodes.reconstruct(pRec, CoeffP, "pRec");
593 nutRecFields = problem->nutModes.reconstruct(nutRec, CoeffNut, "nutRec");
594
595 if (exportFields)
596 {
598 "uRec");
600 "pRec");
602 "nutRec");
603 }
604}
605
607 fileName folder)
608{
609 if (exportFields)
610 {
611 mkDir(folder);
613 }
614
615 int counter = 0;
616 int nextWrite = 0;
617 int counter2 = 1;
618 int exportEveryIndex = round(exportEvery / storeEvery);
619 volScalarField nutAveNow("nutAveNow", nutModes[0] * 0);
620 List < Eigen::MatrixXd> CoeffU;
621 List < Eigen::MatrixXd> CoeffP;
622 List < Eigen::MatrixXd> CoeffNut;
623 CoeffU.resize(0);
624 CoeffP.resize(0);
625 CoeffNut.resize(0);
626
627 for (int i = 0; i < online_solution.size(); i++)
628 {
629 if (counter == nextWrite)
630 {
631 Eigen::MatrixXd currentUCoeff;
632 Eigen::MatrixXd currentPCoeff;
633 Eigen::MatrixXd currentNutCoeff;
634 currentUCoeff = online_solution[i].block(1, 0, Nphi_u, 1);
635 currentPCoeff = online_solution[i].bottomRows(Nphi_p);
636 currentNutCoeff = online_solution[i].block(1, 0, Nphi_u, 1);
637 CoeffU.append(currentUCoeff);
638 CoeffP.append(currentPCoeff);
639 CoeffNut.append(currentNutCoeff);
640 nextWrite += exportEveryIndex;
641 }
642
643 counter++;
644 }
645
646 volVectorField uRec("uRec", Umodes[0]);
647 volScalarField pRec("pRec", problem->Pmodes[0]);
648 volScalarField nutRec("nutRec", problem->nutModes[0]);
649 uRecFields = problem->L_U_SUPmodes.reconstruct(uRec, CoeffU, "uRec");
650 pRecFields = problem->Pmodes.reconstruct(pRec, CoeffP, "pRec");
651 nutRecFields = problem->nutModes.reconstruct(nutRec, CoeffNut, "nutRec");
652
653 if (exportFields)
654 {
656 "uRec");
658 "pRec");
660 "nutRec");
661 }
662}
663
665 Eigen::MatrixXd vel)
666{
667 assert(problem->inletIndex.rows() == vel.rows()
668 && "Imposed boundary conditions dimensions do not match given values matrix dimensions");
669 Eigen::MatrixXd vel_scal;
670 vel_scal.resize(vel.rows(), vel.cols());
671
672 for (int k = 0; k < problem->inletIndex.rows(); k++)
673 {
674 int p = problem->inletIndex(k, 0);
675 int l = problem->inletIndex(k, 1);
676 scalar area = gSum(problem->liftfield[0].mesh().magSf().boundaryField()[p]);
677 scalar u_lf = gSum(problem->liftfield[k].mesh().magSf().boundaryField()[p] *
678 problem->liftfield[k].boundaryField()[p]).component(l) / area;
679 vel_scal(k, 0) = vel(k, 0) / u_lf;
680 }
681
682 return vel_scal;
683}
684
687 fileName folder)
688{
689 mkDir(folder);
690 system("ln -s ../../constant " + folder + "/constant");
691 system("ln -s ../../0 " + folder + "/0");
692 system("ln -s ../../system " + folder + "/system");
693 //Read FORCESdict
694 IOdictionary FORCESdict
695 (
696 IOobject
697 (
698 "FORCESdict",
699 "./system",
700 Umodes[0].mesh(),
701 IOobject::MUST_READ,
702 IOobject::NO_WRITE
703 )
704 );
705 fTau.setZero(online_solution.size(), 3);
706 fN.setZero(online_solution.size(), 3);
707
708 for (int i = 0; i < online_solution.size(); i++)
709 {
710 for (int j = 0; j < Nphi_u; j++)
711 {
712 fTau.row(i) += problem.tauMatrix.row(j) * online_solution[i](j + 1, 0);
713 }
714
715 if (online_solution[0].rows() == Nphi_u + 1)
716 {
717 for (int j = 0; j < Nphi_u; j++)
718 {
719 fN.row(i) += problem.nMatrix.row(j) * online_solution[i](j + 1, 0);
720 }
721 }
722 else if ((online_solution[0].rows() == Nphi_u + Nphi_p + 1))
723 {
724 for (int j = 0; j < Nphi_p; j++)
725 {
726 fN.row(i) += problem.nMatrix.row(j) * online_solution[i](j + Nphi_u + 1, 0);
727 }
728 }
729 }
730
731 // Export the matrices
732 if (para->exportPython)
733 {
734 ITHACAstream::exportMatrix(fTau, "fTau", "python", folder);
735 ITHACAstream::exportMatrix(fN, "fN", "python", folder);
736 }
737
738 if (para->exportMatlab)
739 {
740 ITHACAstream::exportMatrix(fTau, "fTau", "matlab", folder);
741 ITHACAstream::exportMatrix(fN, "fN", "matlab", folder);
742 }
743
744 if (para->exportTxt)
745 {
746 ITHACAstream::exportMatrix(fTau, "fTau", "eigen", folder);
747 ITHACAstream::exportMatrix(fN, "fN", "eigen", folder);
748 }
749}
750
751// ************************************************************************* //
Foam::fvMesh & mesh
Definition createMesh.H:47
#define M_Assert(Expr, Msg)
Header file of the ReducedUnsteadyNSTurbIntrusive 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
void reconstructLiftAndDrag(UnsteadyNSTurbIntrusive &problem, fileName folder)
Method to compute the reduced order forces for same number of modes of velocity and pressure.
Eigen::MatrixXd initCond
Tha matrix containing the initial conditions for the reduced variables, in case of PPE approach it mu...
PtrList< volScalarField > nutRecFields
Reconstructed eddy viscosity fields list.
newtonUnsteadyNSTurbIntrusive newtonObject
Function object to call the non linear solver sup approach.
PtrList< volScalarField > nutModes
List of pointers to store the modes for the eddy viscosity.
UnsteadyNSTurbIntrusive * problem
Pointer to the FOM problem.
Eigen::MatrixXd setOnlineVelocity(Eigen::MatrixXd vel)
Sets the online velocity.
void solveOnlinePPE(Eigen::MatrixXd vel)
Method to perform an online solve using an intrusive approach with the usage of PPE.
void reconstructPPE(bool exportFields=false, fileName folder="./online_rec")
Method to reconstruct the solutions from an online solve with a PPE semi-uniform approach.
void reconstruct(bool exportFields=false, fileName folder="./online_rec")
Method to reconstruct the solutions from an online solve with a fully uniform approach.
newtonUnsteadyNSTurbIntrusivePPE newtonObjectPPE
Function object to call the non linear solver sup approach.
Implementation of a parametrized full order unsteady NS problem and preparation of the the reduced ...
Eigen::MatrixXd kMatrix
Pressure Gradient matrix.
Eigen::Tensor< double, 3 > cTotalTensor
Total Turbulent tensor.
Eigen::Tensor< double, 3 > cTotalPPETensor
Total Turbulent tensor PPE approach.
Eigen::MatrixXd bTotalMatrix
Total B Matrix.
Eigen::MatrixXd bMatrix
Diffusive matrix.
volScalarModes nutModes
List of POD modes for eddy viscosity.
virtual void solveOnline()
Virtual Method to perform and online Solve.
Eigen::VectorXd y
Vector to store the solution during the Newton procedure.
ITHACAparameters * para
parameters to be read from the ITHACAdict file
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.
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.
Eigen::MatrixXd fN
Reduced matrix for normal forces.
PtrList< volScalarField > Psnapshots
List of pointers to store the snapshots for pressure.
PtrList< volVectorField > Usnapshots
List of pointers to store the snapshots for velocity.
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.
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 nMatrix
Pressure forces.
Definition steadyNS.H:215
Eigen::MatrixXd BC1_matrix
PPE BC1.
Definition steadyNS.H:182
Eigen::MatrixXd tauMatrix
Viscous forces.
Definition steadyNS.H:212
Eigen::MatrixXd BC3_matrix
PPE BC3.
Definition steadyNS.H:191
PtrList< volScalarField > Pfield
List of pointers used to form the pressure snapshots matrix.
Definition steadyNS.H:86
volVectorModes Umodes
List of pointers used to form the velocity modes.
Definition steadyNS.H:101
PtrList< volVectorField > Ufield
List of pointers used to form the velocity snapshots matrix.
Definition steadyNS.H:89
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 D_matrix
Laplacian term PPE.
Definition steadyNS.H:173
Eigen::Tensor< double, 3 > gTensor
Divergence of momentum PPE.
Definition steadyNS.H:179
List< Eigen::MatrixXd > bcVelMat
Boundary term for penalty method - matrix.
Definition steadyNS.H:221
Eigen::Tensor< double, 3 > bc2Tensor
PPE BC2.
Definition steadyNS.H:188
volScalarModes Pmodes
List of pointers used to form the pressure modes.
Definition steadyNS.H:98
word bcMethod
Boundary Method.
Definition steadyNS.H:317
word timeDerivativeSchemeOrder
Definition unsteadyNS.H:99
@ 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 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 ...
bool isInteger(double ratio)
This function checks if ratio is an integer.
void createSymLink(word folder)
Creates symbolic links to 0, system and constant.
volScalarField & p
label i
Definition pEqn.H:46
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