Loading...
Searching...
No Matches
steadyNS.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
13 License
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
34
35#include "steadyNS.H"
36#include "viscosityModel.H"
37
38// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * //
39// Constructor
41
42steadyNS::steadyNS(int argc, char* argv[])
43{
44 _args = autoPtr<argList>
45 (
46 new argList(argc, argv)
47 );
48
49 if (!_args->checkRootCase())
50 {
51 Foam::FatalError.exit();
52 }
53
54 argList& args = _args();
55#include "createTime.H"
56#include "createMesh.H"
57 _simple = autoPtr<simpleControl>
58 (
59 new simpleControl
60 (
61 mesh
62 )
63 );
64 simpleControl& simple = _simple();
65#include "createFields.H"
66#include "createFvOptions.H"
67 turbulence->validate();
68 ITHACAdict = new IOdictionary
69 (
70 IOobject
71 (
72 "ITHACAdict",
73 runTime.system(),
74 mesh,
75 IOobject::MUST_READ,
76 IOobject::NO_WRITE
77 )
78 );
79 tolerance = ITHACAdict->lookupOrDefault<scalar>("tolerance", 1e-5);
80 maxIter = ITHACAdict->lookupOrDefault<scalar>("maxIter", 1000);
81 bcMethod = ITHACAdict->lookupOrDefault<word>("bcMethod", "lift");
82 M_Assert(bcMethod == "lift" || bcMethod == "penalty" || bcMethod == "none",
83 "The BC method must be set to lift or penalty or none in ITHACAdict");
84 fluxMethod = ITHACAdict->lookupOrDefault<word>("fluxMethod", "inconsistent");
85 M_Assert(fluxMethod == "inconsistent" || bcMethod == "consistent",
86 "The flux method must be set to inconsistent or consistent in ITHACAdict");
91}
92
93
94// * * * * * * * * * * * * * * Full Order Methods * * * * * * * * * * * * * * //
95
96// Method to perform a truthSolve
97void steadyNS::truthSolve(List<scalar> mu_now)
98{
99 Time& runTime = _runTime();
100 fvMesh& mesh = _mesh();
101 volScalarField& p = _p();
102 volVectorField& U = _U();
103 surfaceScalarField& phi = _phi();
104 fv::options& fvOptions = _fvOptions();
105 simpleControl& simple = _simple();
106 IOMRFZoneList& MRF = _MRF();
107 singlePhaseTransportModel& laminarTransport = _laminarTransport();
108#include "NLsolvesteadyNS.H"
109 ITHACAstream::exportSolution(U, name(counter), "./ITHACAoutput/Offline/");
110 ITHACAstream::exportSolution(p, name(counter), "./ITHACAoutput/Offline/");
111 Ufield.append(U.clone());
112 Pfield.append(p.clone());
113 counter++;
114 writeMu(mu_now);
115 // --- Fill in the mu_samples with parameters (mu) to be used for the PODI sample points
116 mu_samples.conservativeResize(mu_samples.rows() + 1, mu_now.size());
117
118 for (label i = 0; i < mu_now.size(); i++)
119 {
120 mu_samples(mu_samples.rows() - 1, i) = mu_now[i];
121 }
122
123 // Resize to Unitary if not initialized by user (i.e. non-parametric problem)
124 if (mu.cols() == 0)
125 {
126 mu.resize(1, 1);
127 }
128
129 if (mu_samples.rows() == mu.cols())
130 {
131 ITHACAstream::exportMatrix(mu_samples, "mu_samples", "eigen",
132 "./ITHACAoutput/Offline");
133 }
134}
135
136// Method to solve the supremizer problem
138{
139 M_Assert(type == "modes"
140 || type == "snapshots",
141 "You must specify the variable type with either snapshots or modes");
142 PtrList<volScalarField> P_sup;
143
144 if (type == "snapshots")
145 {
146 P_sup = Pfield;
147 }
148 else
149 {
150 P_sup = Pmodes;
151 }
152
153 if (supex == 1)
154 {
155 volVectorField U = _U();
156 volVectorField Usup
157 (
158 IOobject
159 (
160 "Usup",
161 U.time().timeName(),
162 U.mesh(),
163 IOobject::NO_READ,
164 IOobject::AUTO_WRITE
165 ),
166 U.mesh(),
167 dimensionedVector("zero", U.dimensions(), vector::zero)
168 );
169
170 if (type == "snapshots")
171 {
172 ITHACAstream::read_fields(supfield, Usup, "./ITHACAoutput/supfield/");
173 }
174 else
175 {
176 ITHACAstream::read_fields(supmodes, Usup, "./ITHACAoutput/supremizer/");
177 }
178 }
179 else
180 {
181 volVectorField U = _U();
182 volVectorField Usup
183 (
184 IOobject
185 (
186 "Usup",
187 U.time().timeName(),
188 U.mesh(),
189 IOobject::NO_READ,
190 IOobject::AUTO_WRITE
191 ),
192 U.mesh(),
193 dimensionedVector("zero", U.dimensions(), vector::zero)
194 );
195 dimensionedScalar nu_fake
196 (
197 "nu_fake",
198 dimensionSet(0, 2, -1, 0, 0, 0, 0),
199 scalar(1)
200 );
201 Vector<double> v(0, 0, 0);
202
203 for (label i = 0; i < Usup.boundaryField().size(); i++)
204 {
205 if (Usup.boundaryField()[i].type() != "processor")
206 {
207 ITHACAutilities::changeBCtype(Usup, "fixedValue", i);
208 assignBC(Usup, i, v);
209 assignIF(Usup, v);
210 }
211 }
212
213 if (type == "snapshots")
214 {
215 for (label i = 0; i < P_sup.size(); i++)
216 {
217 fvVectorMatrix u_sup_eqn
218 (
219 - fvm::laplacian(nu_fake, Usup)
220 );
221 solve
222 (
223 u_sup_eqn == fvc::grad(P_sup[i])
224 );
225 supfield.append(Usup.clone());
226 ITHACAstream::exportSolution(Usup, name(i + 1), "./ITHACAoutput/supfield/");
227 }
228
229 ITHACAutilities::createSymLink("./ITHACAoutput/supfield");
230 }
231 else
232 {
233 for (label i = 0; i < P_sup.size(); i++)
234 {
235 fvVectorMatrix u_sup_eqn
236 (
237 - fvm::laplacian(nu_fake, Usup)
238 );
239 solve
240 (
241 u_sup_eqn == fvc::grad(P_sup[i])
242 );
243 supmodes.append(Usup.clone());
244 ITHACAstream::exportSolution(Usup, name(i + 1), "./ITHACAoutput/supremizer/");
245 }
246
247 ITHACAutilities::createSymLink("./ITHACAoutput/supremizer");
248 }
249 }
250}
251
252// Method to compute the lifting function
254{
255 for (label k = 0; k < inletIndex.rows(); k++)
256 {
257 Time& runTime = _runTime();
258 surfaceScalarField& phi = _phi();
259 fvMesh& mesh = _mesh();
260 volScalarField p = _p();
261 volVectorField U = _U();
262 IOMRFZoneList& MRF = _MRF();
263 label BCind = inletIndex(k, 0);
264 volVectorField Ulift("Ulift" + name(k), U);
265 instantList Times = runTime.times();
266 runTime.setTime(Times[1], 1);
267 pisoControl potentialFlow(mesh, "potentialFlow");
268 Info << "Solving a lifting Problem" << endl;
269 Vector<double> v1(0, 0, 0);
270 v1[inletIndex(k, 1)] = 1;
271 Vector<double> v0(0, 0, 0);
272
273 for (label j = 0; j < U.boundaryField().size(); j++)
274 {
275 if (j == BCind)
276 {
277 assignBC(Ulift, j, v1);
278 }
279 else if (U.boundaryField()[BCind].type() == "fixedValue")
280 {
281 assignBC(Ulift, j, v0);
282 }
283 else
284 {
285 }
286
287 assignIF(Ulift, v0);
288 phi = linearInterpolate(Ulift) & mesh.Sf();
289 }
290
291 Info << "Constructing velocity potential field Phi\n" << endl;
292 volScalarField Phi
293 (
294 IOobject
295 (
296 "Phi",
297 runTime.timeName(),
298 mesh,
299 IOobject::READ_IF_PRESENT,
300 IOobject::NO_WRITE
301 ),
302 mesh,
303 dimensionedScalar("Phi", dimLength * dimVelocity, 0),
304 p.boundaryField().types()
305 );
306 label PhiRefCell = 0;
307 scalar PhiRefValue = 0;
309 (
310 Phi,
311 potentialFlow.dict(),
312 PhiRefCell,
313 PhiRefValue
314 );
315 mesh.setFluxRequired(Phi.name());
316 runTime.functionObjects().start();
317 MRF.makeRelative(phi);
318 adjustPhi(phi, Ulift, p);
319
320 while (potentialFlow.correctNonOrthogonal())
321 {
322 fvScalarMatrix PhiEqn
323 (
324 fvm::laplacian(dimensionedScalar("1", dimless, 1), Phi)
325 ==
326 fvc::div(phi)
327 );
328 PhiEqn.setReference(PhiRefCell, PhiRefValue);
329 PhiEqn.solve();
330
331 if (potentialFlow.finalNonOrthogonalIter())
332 {
333 phi -= PhiEqn.flux();
334 }
335 }
336
337 MRF.makeAbsolute(phi);
338 Info << "Continuity error = "
339 << mag(fvc::div(phi))().weightedAverage(mesh.V()).value()
340 << endl;
341 Ulift = fvc::reconstruct(phi);
342 Ulift.correctBoundaryConditions();
343 Info << "Interpolated velocity error = "
344 << (sqrt(sum(sqr((fvc::interpolate(U) & mesh.Sf()) - phi)))
345 / sum(mesh.magSf())).value()
346 << endl;
347 Ulift.write();
348 liftfield.append(Ulift.clone());
349 }
350}
351
352// * * * * * * * * * * * * * * Projection Methods * * * * * * * * * * * * * * //
353
354void steadyNS::projectPPE(fileName folder, label NU, label NP, label NSUP)
355{
356 NUmodes = NU;
357 NPmodes = NP;
358 NSUPmodes = 0;
359 L_U_SUPmodes.resize(0);
360
361 if (liftfield.size() != 0)
362 {
363 for (label k = 0; k < liftfield.size(); k++)
364 {
365 L_U_SUPmodes.append(liftfield[k].clone());
366 }
367 }
368
369 if (NUmodes != 0)
370 {
371 for (label k = 0; k < NUmodes; k++)
372 {
373 L_U_SUPmodes.append(Umodes[k].clone());
374 }
375 }
376
377 if (ITHACAutilities::check_folder("./ITHACAoutput/Matrices/"))
378 {
379 word B_str = "B_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
380 NSUPmodes);
381
382 if (ITHACAutilities::check_file("./ITHACAoutput/Matrices/" + B_str))
383 {
384 ITHACAstream::ReadDenseMatrix(B_matrix, "./ITHACAoutput/Matrices/", B_str);
385 }
386 else
387 {
389 }
390
391 word K_str = "K_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
392 NSUPmodes) + "_" + name(NPmodes);
393
394 if (ITHACAutilities::check_file("./ITHACAoutput/Matrices/" + K_str))
395 {
396 ITHACAstream::ReadDenseMatrix(K_matrix, "./ITHACAoutput/Matrices/", K_str);
397 }
398 else
399 {
401 }
402
403 word M_str = "M_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
404 NSUPmodes);
405
406 if (ITHACAutilities::check_file("./ITHACAoutput/Matrices/" + M_str))
407 {
408 ITHACAstream::ReadDenseMatrix(M_matrix, "./ITHACAoutput/Matrices/", M_str);
409 }
410 else
411 {
413 }
414
415 word D_str = "D_" + name(NPmodes);
416
417 if (ITHACAutilities::check_file("./ITHACAoutput/Matrices/" + D_str))
418 {
419 ITHACAstream::ReadDenseMatrix(D_matrix, "./ITHACAoutput/Matrices/", D_str);
420 }
421 else
422 {
424 }
425
426 word bc3_str = "BC3_" + name(liftfield.size()) + "_" + name(
427 NUmodes) + "_" + name(NPmodes);
428
429 if (ITHACAutilities::check_file("./ITHACAoutput/Matrices/" + bc3_str))
430 {
431 ITHACAstream::ReadDenseMatrix(BC3_matrix, "./ITHACAoutput/Matrices/", bc3_str);
432 }
433 else
434 {
436 }
437
438 word bc4_str = "BC4_" + name(liftfield.size()) + "_" + name(
439 NUmodes) + "_" + name(NPmodes);
440
441 if (ITHACAutilities::check_file("./ITHACAoutput/Matrices/" + bc4_str))
442 {
443 ITHACAstream::ReadDenseMatrix(BC4_matrix, "./ITHACAoutput/Matrices/", bc4_str);
444 }
445 else
446 {
448 }
449
450 word C_str = "C_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
451 NSUPmodes) + "_t";
452
453 if (ITHACAutilities::check_file("./ITHACAoutput/Matrices/" + C_str))
454 {
455 ITHACAstream::ReadDenseTensor(C_tensor, "./ITHACAoutput/Matrices/", C_str);
456 }
457 else
458 {
460 }
461
462 word G_str = "G_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
463 NSUPmodes) + "_" + name(NPmodes) + "_t";
464
465 if (ITHACAutilities::check_file("./ITHACAoutput/Matrices/" + G_str))
466 {
467 ITHACAstream::ReadDenseTensor(gTensor, "./ITHACAoutput/Matrices/", G_str);
468 }
469 else
470 {
472 }
473
474 if (bcMethod == "penalty")
475 {
478 }
479 }
480 else
481 {
490
491 if (bcMethod == "penalty")
492 {
495 }
496 }
497
498 // Export the matrices
499 if (para->exportPython)
500 {
501 ITHACAstream::exportMatrix(B_matrix, "B", "python", "./ITHACAoutput/Matrices/");
502 ITHACAstream::exportMatrix(K_matrix, "K", "python", "./ITHACAoutput/Matrices/");
503 ITHACAstream::exportMatrix(D_matrix, "D", "python", "./ITHACAoutput/Matrices/");
504 ITHACAstream::exportMatrix(M_matrix, "M", "python", "./ITHACAoutput/Matrices/");
505 ITHACAstream::exportMatrix(BC3_matrix, "BC3", "python",
506 "./ITHACAoutput/Matrices/");
507 ITHACAstream::exportMatrix(BC4_matrix, "BC4", "python",
508 "./ITHACAoutput/Matrices/");
509 ITHACAstream::exportTensor(C_tensor, "C", "python", "./ITHACAoutput/Matrices/");
510 ITHACAstream::exportTensor(gTensor, "G", "python", "./ITHACAoutput/Matrices/");
511 }
512
513 if (para->exportMatlab)
514 {
515 ITHACAstream::exportMatrix(B_matrix, "B", "matlab", "./ITHACAoutput/Matrices/");
516 ITHACAstream::exportMatrix(K_matrix, "K", "matlab", "./ITHACAoutput/Matrices/");
517 ITHACAstream::exportMatrix(D_matrix, "D", "matlab", "./ITHACAoutput/Matrices/");
518 ITHACAstream::exportMatrix(M_matrix, "M", "matlab", "./ITHACAoutput/Matrices/");
519 ITHACAstream::exportMatrix(BC3_matrix, "BC3", "matlab",
520 "./ITHACAoutput/Matrices/");
521 ITHACAstream::exportMatrix(BC4_matrix, "BC4", "matlab",
522 "./ITHACAoutput/Matrices/");
523 ITHACAstream::exportTensor(C_tensor, "C", "matlab", "./ITHACAoutput/Matrices/");
524 ITHACAstream::exportTensor(gTensor, "G", "matlab", "./ITHACAoutput/Matrices/");
525 }
526
527 if (para->exportTxt)
528 {
529 ITHACAstream::exportMatrix(B_matrix, "B", "eigen", "./ITHACAoutput/Matrices/");
530 ITHACAstream::exportMatrix(K_matrix, "K", "eigen", "./ITHACAoutput/Matrices/");
531 ITHACAstream::exportMatrix(D_matrix, "D", "eigen", "./ITHACAoutput/Matrices/");
532 ITHACAstream::exportMatrix(M_matrix, "M", "eigen", "./ITHACAoutput/Matrices/");
534 "./ITHACAoutput/Matrices/");
536 "./ITHACAoutput/Matrices/");
538 "./ITHACAoutput/Matrices/C");
540 "./ITHACAoutput/Matrices/G");
541 }
542
543 if (para->exportNpy)
544 {
545 cnpy::save(B_matrix, "./ITHACAoutput/Matrices/B.npy");
546 cnpy::save(K_matrix, "./ITHACAoutput/Matrices/K.npy");
547 cnpy::save(D_matrix, "./ITHACAoutput/Matrices/D.npy");
548 cnpy::save(M_matrix, "./ITHACAoutput/Matrices/M.npy");
549 cnpy::save(BC3_matrix, "./ITHACAoutput/Matrices/BC3.npy");
550 cnpy::save(BC4_matrix, "./ITHACAoutput/Matrices/BC4.npy");
551 cnpy::save(C_tensor, "./ITHACAoutput/Matrices/C.npy");
552 cnpy::save(gTensor, "./ITHACAoutput/Matrices/G.npy");
553 }
554}
555
556void steadyNS::projectSUP(fileName folder, label NU, label NP, label NSUP)
557{
558 NUmodes = NU;
559 NPmodes = NP;
560 NSUPmodes = NSUP;
561 L_U_SUPmodes.resize(0);
562
563 if (liftfield.size() != 0)
564 {
565 for (label k = 0; k < liftfield.size(); k++)
566 {
567 L_U_SUPmodes.append(liftfield[k].clone());
568 }
569 }
570
571 if (NUmodes != 0)
572 {
573 for (label k = 0; k < NUmodes; k++)
574 {
575 L_U_SUPmodes.append(Umodes[k].clone());
576 }
577 }
578
579 if (NSUPmodes != 0)
580 {
581 for (label k = 0; k < NSUPmodes; k++)
582 {
583 L_U_SUPmodes.append(supmodes[k].clone());
584 }
585 }
586
587 if (ITHACAutilities::check_folder("./ITHACAoutput/Matrices/"))
588 {
589 word B_str = "B_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
590 NSUPmodes);
591
592 if (ITHACAutilities::check_file("./ITHACAoutput/Matrices/" + B_str))
593 {
594 ITHACAstream::ReadDenseMatrix(B_matrix, "./ITHACAoutput/Matrices/", B_str);
595 }
596 else
597 {
599 }
600
601 word K_str = "K_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
602 NSUPmodes) + "_" + name(NPmodes);
603
604 if (ITHACAutilities::check_file("./ITHACAoutput/Matrices/" + K_str))
605 {
606 ITHACAstream::ReadDenseMatrix(K_matrix, "./ITHACAoutput/Matrices/", K_str);
607 }
608 else
609 {
611 }
612
613 word P_str = "P_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
614 NSUPmodes) + "_" + name(NPmodes);
615
616 if (ITHACAutilities::check_file("./ITHACAoutput/Matrices/" + P_str))
617 {
618 ITHACAstream::ReadDenseMatrix(P_matrix, "./ITHACAoutput/Matrices/", P_str);
619 }
620 else
621 {
623 }
624
625 word M_str = "M_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
626 NSUPmodes);
627
628 if (ITHACAutilities::check_file("./ITHACAoutput/Matrices/" + M_str))
629 {
630 ITHACAstream::ReadDenseMatrix(M_matrix, "./ITHACAoutput/Matrices/", M_str);
631 }
632 else
633 {
635 }
636
637 word C_str = "C_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
638 NSUPmodes) + "_t";
639
640 if (ITHACAutilities::check_file("./ITHACAoutput/Matrices/" + C_str))
641 {
642 ITHACAstream::ReadDenseTensor(C_tensor, "./ITHACAoutput/Matrices/", C_str);
643 }
644 else
645 {
647 }
648
649 if (bcMethod == "penalty")
650 {
653 }
654 }
655 else
656 {
662
663 if (bcMethod == "penalty")
664 {
667 }
668 }
669
670 // Export the matrices
671 if (para->exportPython)
672 {
673 ITHACAstream::exportMatrix(B_matrix, "B", "python", "./ITHACAoutput/Matrices/");
674 ITHACAstream::exportMatrix(K_matrix, "K", "python", "./ITHACAoutput/Matrices/");
675 ITHACAstream::exportMatrix(P_matrix, "P", "python", "./ITHACAoutput/Matrices/");
676 ITHACAstream::exportMatrix(M_matrix, "M", "python", "./ITHACAoutput/Matrices/");
677 ITHACAstream::exportTensor(C_tensor, "C", "python", "./ITHACAoutput/Matrices/");
678 }
679
680 if (para->exportMatlab)
681 {
682 ITHACAstream::exportMatrix(B_matrix, "B", "matlab", "./ITHACAoutput/Matrices/");
683 ITHACAstream::exportMatrix(K_matrix, "K", "matlab", "./ITHACAoutput/Matrices/");
684 ITHACAstream::exportMatrix(P_matrix, "P", "matlab", "./ITHACAoutput/Matrices/");
685 ITHACAstream::exportMatrix(M_matrix, "M", "matlab", "./ITHACAoutput/Matrices/");
686 ITHACAstream::exportTensor(C_tensor, "C", "python", "./ITHACAoutput/Matrices/");
687 }
688
689 if (para->exportTxt)
690 {
691 ITHACAstream::exportMatrix(B_matrix, "B", "eigen", "./ITHACAoutput/Matrices/");
692 ITHACAstream::exportMatrix(K_matrix, "K", "eigen", "./ITHACAoutput/Matrices/");
693 ITHACAstream::exportMatrix(P_matrix, "P", "eigen", "./ITHACAoutput/Matrices/");
694 ITHACAstream::exportMatrix(M_matrix, "M", "eigen", "./ITHACAoutput/Matrices/");
696 "./ITHACAoutput/Matrices/C");
697 }
698
699 if (para->exportNpy)
700 {
701 cnpy::save(B_matrix, "./ITHACAoutput/Matrices/B.npy");
702 cnpy::save(K_matrix, "./ITHACAoutput/Matrices/K.npy");
703 cnpy::save(P_matrix, "./ITHACAoutput/Matrices/P.npy");
704 cnpy::save(M_matrix, "./ITHACAoutput/Matrices/M.npy");
705 cnpy::save(C_tensor, "./ITHACAoutput/Matrices/C.npy");
706 }
707}
708
709void steadyNS::discretizeThenProject(fileName folder, label NU, label NP,
710 label NSUP)
711{
712 NUmodes = NU;
713 NPmodes = NP;
714 NSUPmodes = 0;
715 L_U_SUPmodes.resize(0);
716 Vector<double> inl(0, 0, 0);
717
718 if (NUmodes != 0)
719 {
720 for (label k = 0; k < NUmodes; k++)
721 {
722 L_U_SUPmodes.append(Umodes[k].clone());
723 // set homogenous boundary conditions
724 forAll(L_U_SUPmodes[k].mesh().boundary(), l)
725 {
726 assignBC(L_U_SUPmodes[k], l, inl);
727 }
728 }
729 }
730
731 if (fluxMethod == "consistent")
732 {
733 L_PHImodes.resize(0);
734
735 for (label k = 0; k < NUmodes; k++)
736 {
737 L_PHImodes.append(Phimodes[k].clone());
738 forAll(L_PHImodes[k].boundaryFieldRef()[0], l)
739 {
740 L_PHImodes[k].boundaryFieldRef()[0][l] = 0;
741 }
742 }
743 }
744
745 // Dummy field of which all boundary conditions converted to homogenous
746 // Dirichlet boundary conditions.
747 Uinl = autoPtr<volVectorField> (new volVectorField(_U()));
749 // dummy variables
750 dt_dummy = autoPtr<dimensionedScalar> (new dimensionedScalar
751 (
752 "dt_dummy",
753 dimensionSet(0, 0, 1, 0, 0, 0, 0),
754 scalar(1.0)
755 ));
756 nu_dummy = autoPtr<dimensionedScalar> (new dimensionedScalar
757 (
758 "nu_dummy",
759 dimensionSet(0, 2, -1, 0, 0, 0, 0),
760 scalar(1.0)
761 ));
762
763 if (ITHACAutilities::check_folder("./ITHACAoutput/Matrices/"))
764 {
765 word B_str = "B_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
766 NSUPmodes);
767
768 if (ITHACAutilities::check_file("./ITHACAoutput/Matrices/" + B_str))
769 {
770 ITHACAstream::ReadDenseMatrix(B_matrix, "./ITHACAoutput/Matrices/", B_str);
771 }
772 else
773 {
775 }
776
777 word K_str = "K_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
778 NSUPmodes) + "_" + name(NPmodes);
779
780 if (ITHACAutilities::check_file("./ITHACAoutput/Matrices/" + K_str))
781 {
782 ITHACAstream::ReadDenseMatrix(K_matrix, "./ITHACAoutput/Matrices/", K_str);
783 }
784 else
785 {
787 }
788
789 word P_str = "P_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
790 NSUPmodes) + "_" + name(NPmodes);
791
792 if (ITHACAutilities::check_file("./ITHACAoutput/Matrices/" + P_str))
793 {
794 ITHACAstream::ReadDenseMatrix(P_matrix, "./ITHACAoutput/Matrices/", P_str);
795 }
796 else
797 {
799 }
800
801 word C_str = "C_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
802 NSUPmodes) + "_t";
803
804 if (ITHACAutilities::check_file("./ITHACAoutput/Matrices/" + C_str))
805 {
806 ITHACAstream::ReadDenseTensor(C_tensor, "./ITHACAoutput/Matrices/", C_str);
807 }
808 else
809 {
811 }
812
813 word Cf_str = "Cf_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
814 NSUPmodes) + "_t";
815
816 if (ITHACAutilities::check_file("./ITHACAoutput/Matrices/" + Cf_str))
817 {
818 ITHACAstream::ReadDenseTensor(Cf_tensor, "./ITHACAoutput/Matrices/", Cf_str);
819 }
820 else
821 {
823 }
824
825 word BP_str = "BP_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
826 NSUPmodes);
827
828 if (ITHACAutilities::check_file("./ITHACAoutput/Matrices/" + BP_str))
829 {
830 ITHACAstream::ReadDenseMatrix(B_matrix, "./ITHACAoutput/Matrices/", BP_str);
831 }
832 else
833 {
835 }
836
842
843 if (fluxMethod == "consistent")
844 {
852 }
853 }
854 else
855 {
867
868 if (fluxMethod == "consistent")
869 {
877 }
878 }
879}
880
881// * * * * * * * * * * * * * * Momentum Eq. Methods * * * * * * * * * * * * * //
882
883Eigen::MatrixXd steadyNS::diffusive_term(label NUmodes, label NPmodes,
884 label NSUPmodes)
885{
886 label Bsize = NUmodes + NSUPmodes + liftfield.size();
887 Eigen::MatrixXd B_matrix;
888 B_matrix.resize(Bsize, Bsize);
889
890 // Project everything
891 for (label i = 0; i < Bsize; i++)
892 {
893 for (label j = 0; j < Bsize; j++)
894 {
895 B_matrix(i, j) = fvc::domainIntegrate(L_U_SUPmodes[i] & fvc::laplacian(
896 dimensionedScalar("1", dimless, 1), L_U_SUPmodes[j])).value();
897 }
898 }
899
900 if (Pstream::master())
901 {
902 ITHACAstream::SaveDenseMatrix(B_matrix, "./ITHACAoutput/Matrices/",
903 "B_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(NSUPmodes));
904 }
905
906 return B_matrix;
907}
908
909Eigen::MatrixXd steadyNS::diffusive_term_sym(label NUmodes, label NPmodes,
910 label NSUPmodes)
911{
912 label Bsize = NUmodes + NSUPmodes + liftfield.size();
913 Eigen::MatrixXd B_matrix;
914 B_matrix.resize(Bsize, Bsize);
915
916 // Project everything
917 for (label i = 0; i < Bsize; i++)
918 {
919 for (label j = 0; j < Bsize; j++)
920 {
921 B_matrix(i, j) = - fvc::domainIntegrate(fvc::grad(L_U_SUPmodes[i])
922 && fvc::grad(L_U_SUPmodes[j])).value();
923 }
924 }
925
926 if (Pstream::master())
927 {
928 ITHACAstream::SaveDenseMatrix(B_matrix, "./ITHACAoutput/Matrices/",
929 "B_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(NSUPmodes));
930 }
931
932 return B_matrix;
933}
934
936 label NSUPmodes)
937{
938 label K1size = NUmodes + NSUPmodes + liftfield.size();
939 label K2size = NPmodes + liftfieldP.size();
940 Eigen::MatrixXd K_matrix(K1size, K2size);
941
942 // Project everything
943 for (label i = 0; i < K1size; i++)
944 {
945 for (label j = 0; j < K2size; j++)
946 {
947 K_matrix(i, j) = fvc::domainIntegrate(L_U_SUPmodes[i] & fvc::grad(
948 Pmodes[j])).value();
949 }
950 }
951
952 if (Pstream::master())
953 {
954 ITHACAstream::SaveDenseMatrix(K_matrix, "./ITHACAoutput/Matrices/",
955 "K_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
956 NSUPmodes) + "_" + name(NPmodes));
957 }
958
959 return K_matrix;
960}
961
962List <Eigen::MatrixXd> steadyNS::convective_term(label NUmodes, label NPmodes,
963 label NSUPmodes)
964{
965 label Csize = NUmodes + NSUPmodes + liftfield.size();
966 List <Eigen::MatrixXd> C_matrix;
967 C_matrix.setSize(Csize);
968
969 for (label j = 0; j < Csize; j++)
970 {
971 C_matrix[j].resize(Csize, Csize);
972 }
973
974 for (label i = 0; i < Csize; i++)
975 {
976 for (label j = 0; j < Csize; j++)
977 {
978 for (label k = 0; k < Csize; k++)
979 {
980 C_matrix[i](j, k) = fvc::domainIntegrate(L_U_SUPmodes[i] & fvc::div(
981 linearInterpolate(L_U_SUPmodes[j]) & L_U_SUPmodes[j].mesh().Sf(),
982 L_U_SUPmodes[k])).value();
983 }
984 }
985 }
986
987 if (Pstream::master())
988 {
989 // Export the matrix
990 ITHACAstream::exportMatrix(C_matrix, "C", "python", "./ITHACAoutput/Matrices/");
991 ITHACAstream::exportMatrix(C_matrix, "C", "matlab", "./ITHACAoutput/Matrices/");
992 ITHACAstream::exportMatrix(C_matrix, "C", "eigen", "./ITHACAoutput/Matrices/C");
993 return C_matrix;
994 }
995}
996
997Eigen::Tensor<double, 3> steadyNS::convective_term_tens(label NUmodes,
998 label NPmodes,
999 label NSUPmodes)
1000{
1001 label Csize = NUmodes + NSUPmodes + liftfield.size();
1002 Eigen::Tensor<double, 3> C_tensor;
1003 C_tensor.resize(Csize, Csize, Csize);
1004
1005 for (label i = 0; i < Csize; i++)
1006 {
1007 for (label j = 0; j < Csize; j++)
1008 {
1009 for (label k = 0; k < Csize; k++)
1010 {
1011 if (fluxMethod == "consistent")
1012 {
1013 C_tensor(i, j, k) = fvc::domainIntegrate(L_U_SUPmodes[i] & fvc::div(
1014 L_PHImodes[j],
1015 L_U_SUPmodes[k])).value();
1016 }
1017 else
1018 {
1019 C_tensor(i, j, k) = fvc::domainIntegrate(L_U_SUPmodes[i] & fvc::div(
1020 linearInterpolate(L_U_SUPmodes[j]) & L_U_SUPmodes[j].mesh().Sf(),
1021 L_U_SUPmodes[k])).value();
1022 }
1023 }
1024 }
1025 }
1026
1027 if (Pstream::master())
1028 {
1029 // Export the tensor
1030 ITHACAstream::SaveDenseTensor(C_tensor, "./ITHACAoutput/Matrices/",
1031 "C_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
1032 NSUPmodes) + "_t");
1033 }
1034
1035 return C_tensor;
1036}
1037
1038Eigen::Tensor<double, 3> steadyNS::convective_term_tens_cache(label NUmodes,
1039 label NPmodes,
1040 label NSUPmodes)
1041{
1042 label Csize = NUmodes + NSUPmodes + liftfield.size();
1043 Eigen::Tensor<double, 3> C_tensor(Csize, Csize, Csize);
1044
1045 for (label j = 0; j < Csize; ++j)
1046 {
1047 surfaceScalarField SfUj = linearInterpolate(L_U_SUPmodes[j]) & L_U_SUPmodes[j].mesh().Sf();
1048
1049 // Cache all div fields for fixed j, all k
1050 List<tmp<volVectorField>> divRow(Csize);
1051 for (label k = 0; k < Csize; ++k)
1052 {
1053 if (fluxMethod == "consistent")
1054 {
1055 divRow[k] = fvc::div(L_PHImodes[j], L_U_SUPmodes[k]);
1056 }
1057 else
1058 {
1059 divRow[k] = fvc::div(SfUj, L_U_SUPmodes[k]);
1060 }
1061 }
1062
1063 for (label i = 0; i < Csize; ++i)
1064 {
1065 for (label k = 0; k < Csize; ++k)
1066 {
1067 const volVectorField& divField = divRow[k]();
1068 C_tensor(i, j, k) = fvc::domainIntegrate(L_U_SUPmodes[i] & divField).value();
1069 }
1070 }
1071 }
1072
1073 if (Pstream::master())
1074 {
1075 // Export the tensor
1076 ITHACAstream::SaveDenseTensor(C_tensor, "./ITHACAoutput/Matrices/",
1077 "C_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
1078 NSUPmodes) + "_t");
1079 }
1080
1081 return C_tensor;
1082}
1083
1084Eigen::MatrixXd steadyNS::mass_term(label NUmodes, label NPmodes,
1085 label NSUPmodes)
1086{
1087 label Msize = NUmodes + NSUPmodes + liftfield.size();
1088 Eigen::MatrixXd M_matrix(Msize, Msize);
1089
1090 // Project everything
1091 for (label i = 0; i < Msize; i++)
1092 {
1093 for (label j = 0; j < Msize; j++)
1094 {
1095 M_matrix(i, j) = fvc::domainIntegrate(L_U_SUPmodes[i] &
1096 L_U_SUPmodes[j]).value();
1097 }
1098 }
1099
1100 if (Pstream::master())
1101 {
1102 ITHACAstream::SaveDenseMatrix(M_matrix, "./ITHACAoutput/Matrices/",
1103 "M_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(NSUPmodes));
1104 }
1105 return M_matrix;
1106}
1107
1108// * * * * * * * * * * * * * * Continuity Eq. Methods * * * * * * * * * * * * * //
1109
1110Eigen::MatrixXd steadyNS::divergence_term(label NUmodes, label NPmodes,
1111 label NSUPmodes)
1112{
1113 label P1size = NPmodes;
1114 label P2size = NUmodes + NSUPmodes + liftfield.size();
1115 Eigen::MatrixXd P_matrix(P1size, P2size);
1116
1117 // Project everything
1118 for (label i = 0; i < P1size; i++)
1119 {
1120 for (label j = 0; j < P2size; j++)
1121 {
1122 P_matrix(i, j) = fvc::domainIntegrate(Pmodes[i] * fvc::div (
1123 L_U_SUPmodes[j])).value();
1124 }
1125 }
1126
1127 if (Pstream::master())
1128 {
1129 ITHACAstream::SaveDenseMatrix(P_matrix, "./ITHACAoutput/Matrices/",
1130 "P_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
1131 NSUPmodes) + "_" + name(NPmodes));
1132 }
1133
1134 return P_matrix;
1135}
1136
1137
1138List <Eigen::MatrixXd> steadyNS::div_momentum(label NUmodes, label NPmodes)
1139{
1140 label G1size = NPmodes;
1141 label G2size = NUmodes + NSUPmodes + liftfield.size();
1142 List <Eigen::MatrixXd> G_matrix;
1143 G_matrix.setSize(G1size);
1144
1145 for (label j = 0; j < G1size; j++)
1146 {
1147 G_matrix[j].resize(G2size, G2size);
1148 }
1149
1150 for (label i = 0; i < G1size; i++)
1151 {
1152 for (label j = 0; j < G2size; j++)
1153 {
1154 for (label k = 0; k < G2size; k++)
1155 {
1156 G_matrix[i](j, k) = fvc::domainIntegrate(fvc::grad(Pmodes[i]) & (fvc::div(
1157 fvc::interpolate(L_U_SUPmodes[j]) & L_U_SUPmodes[j].mesh().Sf(),
1158 L_U_SUPmodes[k]))).value();
1159 }
1160 }
1161 }
1162
1163 if (Pstream::master())
1164 {
1165 // Export the matrix
1166 ITHACAstream::exportMatrix(G_matrix, "G", "python", "./ITHACAoutput/Matrices/");
1167 ITHACAstream::exportMatrix(G_matrix, "G", "matlab", "./ITHACAoutput/Matrices/");
1168 ITHACAstream::exportMatrix(G_matrix, "G", "eigen", "./ITHACAoutput/Matrices/G");
1169 }
1170
1171 return G_matrix;
1172}
1173
1174Eigen::Tensor<double, 3> steadyNS::divMomentum(label NUmodes, label NPmodes)
1175{
1176 label g1Size = NPmodes + liftfieldP.size();
1177 label g2Size = NUmodes + NSUPmodes + liftfield.size();
1178 Eigen::Tensor<double, 3> gTensor;
1179 gTensor.resize(g1Size, g2Size, g2Size);
1180
1181 for (label i = 0; i < g1Size; i++)
1182 {
1183 for (label j = 0; j < g2Size; j++)
1184 {
1185 for (label k = 0; k < g2Size; k++)
1186 {
1187 gTensor(i, j, k) = fvc::domainIntegrate(fvc::grad(Pmodes[i]) & (fvc::div(
1188 fvc::interpolate(L_U_SUPmodes[j]) & L_U_SUPmodes[j].mesh().Sf(),
1189 L_U_SUPmodes[k]))).value();
1190 }
1191 }
1192 }
1193
1194 if (Pstream::master())
1195 {
1196 // Export the tensor
1197 ITHACAstream::SaveDenseTensor(gTensor, "./ITHACAoutput/Matrices/",
1198 "G_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
1199 NSUPmodes) + "_" + name(NPmodes) + "_t");
1200 }
1201
1202 return gTensor;
1203}
1204
1205Eigen::Tensor<double, 3> steadyNS::divMomentum_cache(label NUmodes, label NPmodes)
1206{
1207 label g1Size = NPmodes + liftfieldP.size();
1208 label g2Size = NUmodes + NSUPmodes + liftfield.size();
1209 Eigen::Tensor<double, 3> gTensor (g1Size, g2Size, g2Size);
1210
1211 List<tmp<volVectorField>> PmodesGrad(g1Size);
1212 for (label i = 0; i < g1Size; i++)
1213 {
1214 PmodesGrad[i] = fvc::grad(Pmodes[i]);
1215 }
1216
1217 for (label j = 0; j < g2Size; j++)
1218 {
1219 surfaceScalarField interpUj = fvc::interpolate(L_U_SUPmodes[j]) & L_U_SUPmodes[j].mesh().Sf();
1220
1221 // Cache only one row (j fixed)
1222 List<tmp<volVectorField>> divRow(g2Size);
1223 for (label k = 0; k < g2Size; ++k)
1224 {
1225 divRow[k] = fvc::div(interpUj, L_U_SUPmodes[k]);
1226 }
1227
1228 for (label i = 0; i < g1Size; i++)
1229 {
1230 const volVectorField& gradPi = PmodesGrad[i]();
1231 for (label k = 0; k < g2Size; k++)
1232 {
1233 const volVectorField& divField = divRow[k]();
1234 gTensor(i, j, k) = fvc::domainIntegrate(gradPi & divField).value();
1235 }
1236 }
1237 }
1238
1239 if (Pstream::master())
1240 {
1241 // Export the tensor
1242 ITHACAstream::SaveDenseTensor(gTensor, "./ITHACAoutput/Matrices/",
1243 "G_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
1244 NSUPmodes) + "_" + name(NPmodes) + "_t");
1245 }
1246
1247 return gTensor;
1248}
1249
1250// large scale convection (or background convection)
1251Eigen::MatrixXd steadyNS::convective_background(label NUmodes, volVectorField vls)
1252{
1253 label Lsize = NUmodes + liftfield.size();
1254 Eigen::MatrixXd L_matrix(Lsize, Lsize);
1255 for (label i = 0; i < Lsize; i++)
1256 {
1257 for (label j = 0; j < Lsize; j++)
1258 {
1259 L_matrix(i, j) = - fvc::domainIntegrate(L_U_SUPmodes[i] & fvc::div(
1260 fvc::interpolate(vls) & vls.mesh().Sf(),
1261 L_U_SUPmodes[j])).value();
1262 }
1263 }
1264
1265 return L_matrix;
1266}
1267
1268Eigen::MatrixXd steadyNS::divergent_convective_background(label NPmodes, label NUmodes, volVectorField vls)
1269{
1270 label LDsize1 = NPmodes + liftfieldP.size();
1271 label LDsize2 = NUmodes + liftfield.size();
1272 Eigen::MatrixXd L_D_matrix(LDsize1, LDsize2);
1273 for (label i = 0; i < LDsize1; i++)
1274 {
1275 for (label j = 0; j < LDsize2; j++)
1276 {
1277 L_D_matrix(i, j) = - fvc::domainIntegrate(fvc::grad(Pmodes[i]) & fvc::div(
1278 fvc::interpolate(vls) & vls.mesh().Sf(),
1279 L_U_SUPmodes[j])).value();
1280 }
1281 }
1282
1283 return L_D_matrix;
1284}
1285
1287{
1288 label Dsize = NPmodes + liftfieldP.size();
1289 Eigen::MatrixXd D_matrix(Dsize, Dsize);
1290
1291 // Project everything
1292 for (label i = 0; i < Dsize; i++)
1293 {
1294 for (label j = 0; j < Dsize; j++)
1295 {
1296 D_matrix(i, j) = fvc::domainIntegrate(fvc::grad(Pmodes[i]) & fvc::grad(
1297 Pmodes[j])).value();
1298 }
1299 }
1300
1301 if (Pstream::master())
1302 {
1303 ITHACAstream::SaveDenseMatrix(D_matrix, "./ITHACAoutput/Matrices/",
1304 "D_" + name(NPmodes));
1305 }
1306 return D_matrix;
1307}
1308
1309Eigen::MatrixXd steadyNS::pressure_BC1(label NUmodes, label NPmodes)
1310{
1311 label P_BC1size = NPmodes;
1312 label P_BC2size = NUmodes + liftfield.size();
1313 Eigen::MatrixXd BC1_matrix(P_BC1size, P_BC2size);
1314 const fvMesh& mesh = L_U_SUPmodes[0].mesh();
1315
1316 for (label i = 0; i < P_BC1size; i++)
1317 {
1318 for (label j = 0; j < P_BC2size; j++)
1319 {
1320 surfaceScalarField lpl((fvc::interpolate(fvc::laplacian(
1321 L_U_SUPmodes[j])) & mesh.Sf()) * fvc::interpolate(Pmodes[i]));
1322 double s = 0;
1323
1324 for (label k = 0; k < lpl.boundaryField().size(); k++)
1325 {
1326 s += gSum(lpl.boundaryField()[k]);
1327 }
1328
1329 BC1_matrix(i, j) = s;
1330 }
1331 }
1332
1333 if (Pstream::master())
1334 {
1335 ITHACAstream::SaveDenseMatrix(BC1_matrix, "./ITHACAoutput/Matrices/",
1336 "BC1_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(NPmodes));
1337 }
1338
1339 return BC1_matrix;
1340}
1341
1342
1343List <Eigen::MatrixXd> steadyNS::pressure_BC2(label NUmodes, label NPmodes)
1344{
1345 label P2_BC1size = NPmodes;
1346 label P2_BC2size = NUmodes + NSUPmodes + liftfield.size();
1347 List <Eigen::MatrixXd> BC2_matrix;
1348 const fvMesh& mesh = L_U_SUPmodes[0].mesh();
1349 BC2_matrix.setSize(P2_BC1size);
1350
1351 for (label j = 0; j < P2_BC1size; j++)
1352 {
1353 BC2_matrix[j].resize(P2_BC2size, P2_BC2size);
1354 }
1355
1356 for (label i = 0; i < P2_BC1size; i++)
1357 {
1358 for (label j = 0; j < P2_BC2size; j++)
1359 {
1360 for (label k = 0; k < P2_BC2size; k++)
1361 {
1362 surfaceScalarField div_m(fvc::interpolate(fvc::div(fvc::interpolate(
1363 L_U_SUPmodes[j]) & mesh.Sf(),
1364 L_U_SUPmodes[k])) & mesh.Sf() * fvc::interpolate(Pmodes[i]));
1365 double s = 0;
1366
1367 for (label k = 0; k < div_m.boundaryField().size(); k++)
1368 {
1369 s += gSum(div_m.boundaryField()[k]);
1370 }
1371
1372 BC2_matrix[i](j, k) = s;
1373 }
1374 }
1375 }
1376
1377 return BC2_matrix;
1378}
1379
1380Eigen::Tensor<double, 3> steadyNS::pressureBC2(label NUmodes, label NPmodes)
1381{
1382 label pressureBC1Size = NPmodes;
1383 label pressureBC2Size = NUmodes + NSUPmodes + liftfield.size();
1384 Eigen::Tensor<double, 3> bc2Tensor;
1385 const fvMesh& mesh = L_U_SUPmodes[0].mesh();
1386 bc2Tensor.resize(pressureBC1Size, pressureBC2Size, pressureBC2Size);
1387
1388 for (label i = 0; i < pressureBC1Size; i++)
1389 {
1390 for (label j = 0; j < pressureBC2Size; j++)
1391 {
1392 for (label k = 0; k < pressureBC2Size; k++)
1393 {
1394 surfaceScalarField div_m(fvc::interpolate(fvc::div(fvc::interpolate(
1395 L_U_SUPmodes[j]) & mesh.Sf(),
1396 L_U_SUPmodes[k])) & mesh.Sf() * fvc::interpolate(Pmodes[i]));
1397 double s = 0;
1398
1399 for (label k = 0; k < div_m.boundaryField().size(); k++)
1400 {
1401 s += gSum(div_m.boundaryField()[k]);
1402 }
1403
1404 bc2Tensor(i, j, k) = s;
1405 }
1406 }
1407 }
1408
1409 if (Pstream::master())
1410 {
1411 // Export the tensor
1412 ITHACAstream::SaveDenseTensor(bc2Tensor, "./ITHACAoutput/Matrices/",
1413 "BC2_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
1414 NSUPmodes) + "_" + name(NPmodes) + "_t");
1415 }
1416
1417 return bc2Tensor;
1418}
1419
1420Eigen::MatrixXd steadyNS::pressure_BC3(label NUmodes, label NPmodes)
1421{
1422 label P3_BC1size = NPmodes;
1423 label P3_BC2size = NUmodes + liftfield.size();
1424 Eigen::MatrixXd BC3_matrix(P3_BC1size, P3_BC2size);
1425 const fvMesh& mesh = L_U_SUPmodes[0].mesh();
1426 surfaceVectorField n(mesh.Sf() / mesh.magSf());
1427 for (label i = 0; i < P3_BC1size; i++)
1428 {
1429 for (label j = 0; j < P3_BC2size; j++)
1430 {
1431 surfaceVectorField BC3 = fvc::interpolate(fvc::curl(L_U_SUPmodes[j])).ref();
1432 surfaceVectorField BC4 = (n^ fvc::interpolate(fvc::grad(Pmodes[i]))).ref();
1433 surfaceScalarField BC5 = ((BC3& BC4) * mesh.magSf()).ref();
1434 double s = 0;
1435 for (label k = 0; k < BC5.boundaryField().size(); k++)
1436 {
1437 s += gSum(BC5.boundaryField()[k]);
1438 }
1439
1440 BC3_matrix(i, j) = s;
1441 }
1442 }
1443
1444 if (Pstream::master())
1445 {
1446 ITHACAstream::SaveDenseMatrix(BC3_matrix, "./ITHACAoutput/Matrices/",
1447 "BC3_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(NPmodes));
1448 }
1449 return BC3_matrix;
1450}
1451
1452Eigen::MatrixXd steadyNS::pressure_BC4(label NUmodes, label NPmodes)
1453{
1454 label P4_BC1size = NPmodes;
1455 label P4_BC2size = NUmodes + liftfield.size();
1456 Eigen::MatrixXd BC4_matrix(P4_BC1size, P4_BC2size);
1457 const fvMesh& mesh = L_U_SUPmodes[0].mesh();
1458 surfaceVectorField n(mesh.Sf() / mesh.magSf());
1459
1460 for (label i = 0; i < P4_BC1size; i++)
1461 {
1462 for (label j = 0; j < P4_BC2size; j++)
1463 {
1464 surfaceScalarField BC3 = fvc::interpolate(Pmodes[i]).ref();
1465 surfaceScalarField BC4 = (n & fvc::interpolate(L_U_SUPmodes[j])).ref();
1466 surfaceScalarField BC5 = ((BC3 * BC4) * mesh.magSf()).ref();
1467 double s = 0;
1468
1469 for (label k = 0; k < BC5.boundaryField().size(); k++)
1470 {
1471 s += gSum(BC5.boundaryField()[k]);
1472 }
1473
1474 BC4_matrix(i, j) = s;
1475 }
1476 }
1477
1478 if (Pstream::master())
1479 {
1480 ITHACAstream::SaveDenseMatrix(BC4_matrix, "./ITHACAoutput/Matrices/",
1481 "BC4_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(NPmodes));
1482 }
1483
1484 return BC4_matrix;
1485}
1486
1487List<Eigen::MatrixXd> steadyNS::bcVelocityVec(label NUmodes,
1488 label NSUPmodes)
1489{
1490 label BCsize = NUmodes + NSUPmodes;
1491 List <Eigen::MatrixXd> bcVelVec(inletIndex.rows());
1492
1493 for (label j = 0; j < inletIndex.rows(); j++)
1494 {
1495 bcVelVec[j].resize(BCsize, 1);
1496 }
1497
1498 for (label k = 0; k < inletIndex.rows(); k++)
1499 {
1500 label BCind = inletIndex(k, 0);
1501 label BCcomp = inletIndex(k, 1);
1502
1503 for (label i = 0; i < BCsize; i++)
1504 {
1505 bcVelVec[k](i, 0) = gSum(L_U_SUPmodes[i].boundaryField()[BCind].component(
1506 BCcomp));
1507 }
1508 }
1509
1510 if (Pstream::master())
1511 {
1512 ITHACAstream::exportMatrix(bcVelVec, "bcVelVec", "eigen",
1513 "./ITHACAoutput/Matrices/bcVelVec");
1514 }
1515
1516 return bcVelVec;
1517}
1518
1519List<Eigen::MatrixXd> steadyNS::bcVelocityMat(label NUmodes,
1520 label NSUPmodes)
1521{
1522 label BCsize = NUmodes + NSUPmodes;
1523 label BCUsize = inletIndex.rows();
1524 List <Eigen::MatrixXd> bcVelMat(BCUsize);
1525
1526 for (label j = 0; j < inletIndex.rows(); j++)
1527 {
1528 bcVelMat[j].resize(BCsize, BCsize);
1529 }
1530
1531 for (label k = 0; k < inletIndex.rows(); k++)
1532 {
1533 label BCind = inletIndex(k, 0);
1534 label BCcomp = inletIndex(k, 1);
1535
1536 for (label i = 0; i < BCsize; i++)
1537 {
1538 for (label j = 0; j < BCsize; j++)
1539 {
1540 bcVelMat[k](i, j) = gSum(L_U_SUPmodes[i].boundaryField()[BCind].component(
1541 BCcomp) *
1542 L_U_SUPmodes[j].boundaryField()[BCind].component(BCcomp));
1543 }
1544 }
1545 }
1546
1547 if (Pstream::master())
1548 {
1549 ITHACAstream::exportMatrix(bcVelMat, "bcVelMat", "eigen",
1550 "./ITHACAoutput/Matrices/bcVelMat");
1551 }
1552
1553 return bcVelMat;
1554}
1555
1557 label NPmodes, label NSUPmodes)
1558{
1559 label BPsize1 = NPmodes;
1560 label BPsize2 = NUmodes + NSUPmodes + liftfield.size();
1561 Eigen::MatrixXd BP_matrix(BPsize1, BPsize2);
1562 volVectorField L_U_SUPmodesaux(L_U_SUPmodes[0]);
1563
1564 for (label i = 0; i < BPsize1; i++)
1565 {
1566 for (label j = 0; j < BPsize2; j++)
1567 {
1568 L_U_SUPmodesaux = dt_dummy * fvc::laplacian(
1569 nu_dummy(), L_U_SUPmodes[j]);
1570 BP_matrix(i, j) = fvc::domainIntegrate(Pmodes[i] *
1571 fvc::div(L_U_SUPmodesaux)).value();
1572 }
1573 }
1574
1575 if (Pstream::master())
1576 {
1577 ITHACAstream::SaveDenseMatrix(BP_matrix, "./ITHACAoutput/Matrices/",
1578 "BP_" + name(NPmodes));
1579 }
1580
1581 return BP_matrix;
1582}
1583
1585 label NPmodes, label NSUPmodes)
1586{
1587 Eigen::VectorXd ModeVector;
1588 label BCsize = inletIndex.rows();
1589 label RDsize = NUmodes + NSUPmodes;
1590 List <Eigen::MatrixXd> RD_matrix(BCsize);
1591 Eigen::SparseMatrix<double> A;
1592 Eigen::VectorXd b;
1593
1594 for (label i = 0; i < BCsize; i++)
1595 {
1596 label BCind = inletIndex(i, 0);
1597 Vector<double> v(0, 0, 0);
1598 v[inletIndex(i, 1)] = 1;
1599 volVectorField Upara(Uinl());
1600 assignBC(Upara, BCind, v);
1601 // Determine boundary vector
1602 fvVectorMatrix UEqn
1603 (
1604 -fvm::laplacian(nu_dummy(), Upara)
1605 );
1607 RD_matrix[i].resize(RDsize, 1);
1608
1609 for (label j = 0; j < RDsize; j++)
1610 {
1611 ModeVector = Foam2Eigen::field2Eigen(L_U_SUPmodes[j]);
1612 RD_matrix[i](j, 0) = ModeVector.dot(b.col(0));
1613 }
1614
1615 if (Pstream::parRun())
1616 {
1617 reduce(RD_matrix[i], sumOp<Eigen::MatrixXd>());
1618 }
1619
1620 if (Pstream::master())
1621 {
1622 ITHACAstream::SaveDenseMatrix(RD_matrix[i], "./ITHACAoutput/Matrices/RD/",
1623 "RD" + name(i) + "_" + name(NUmodes) + "_" + name(NSUPmodes));
1624 }
1625 }
1626
1627 return RD_matrix;
1628}
1629
1631 label NPmodes, label NSUPmodes)
1632{
1633 Eigen::VectorXd ModeVector;
1634 label BCsize = inletIndex.rows();
1635 label RCsize = NUmodes + NSUPmodes;
1636 List <Eigen::MatrixXd> RC_matrix(BCsize);
1637 Eigen::SparseMatrix<double> A;
1638 Eigen::VectorXd b;
1639
1640 for (label i = 0; i < BCsize; i++)
1641 {
1642 label BCind = inletIndex(i, 0);
1643 Vector<double> v(0, 0, 0);
1644 v[inletIndex(i, 1)] = 1;
1645 volVectorField Upara(Uinl());
1646 assignBC(Upara, BCind, v);
1647 // Determine boundary vector
1648 fvVectorMatrix UEqn
1649 (
1650 fvm::div(fvc::flux(Upara), Upara)
1651 );
1653 RC_matrix[i].resize(RCsize, 1);
1654
1655 for (label j = 0; j < RCsize; j++)
1656 {
1657 ModeVector = Foam2Eigen::field2Eigen(L_U_SUPmodes[j]);
1658 RC_matrix[i](j, 0) = ModeVector.dot(b.col(0));
1659 }
1660
1661 if (Pstream::parRun())
1662 {
1663 reduce(RC_matrix[i], sumOp<Eigen::MatrixXd>());
1664 }
1665
1666 if (Pstream::master())
1667 {
1668 ITHACAstream::SaveDenseMatrix(RC_matrix[i], "./ITHACAoutput/Matrices/RC/",
1669 "RC" + name(i) + "_" + name(NUmodes) + "_" + name(NSUPmodes));
1670 }
1671 }
1672
1673 return RC_matrix;
1674}
1675
1676Eigen::Tensor<double, 3> steadyNS::convective_term_flux_tens(label NUmodes,
1677 label NPmodes, label NSUPmodes)
1678{
1679 label Csize1 = NUmodes + NSUPmodes + liftfield.size();
1680 label Csize2 = NPmodes;
1681 Eigen::Tensor<double, 3> Cf_tensor;
1682 volVectorField L_U_SUPmodesaux(L_U_SUPmodes[0]);
1683 Cf_tensor.resize(Csize2, Csize1, Csize1);
1684
1685 for (label i = 0; i < Csize2; i++)
1686 {
1687 for (label j = 0; j < Csize1; j++)
1688 {
1689 for (label k = 0; k < Csize1; k++)
1690 {
1691 if (fluxMethod == "consistent")
1692 {
1693 L_U_SUPmodesaux = dt_dummy * (fvc::div(
1694 L_PHImodes[j],
1695 L_U_SUPmodes[k]));
1696 }
1697 else
1698 {
1699 L_U_SUPmodesaux = dt_dummy * (fvc::div(
1700 fvc::flux(L_U_SUPmodes[j]),
1701 L_U_SUPmodes[k]));
1702 }
1703
1704 Cf_tensor(i, j, k) = fvc::domainIntegrate(Pmodes[i]
1705 * fvc::div(L_U_SUPmodesaux)).value();
1706 }
1707 }
1708 }
1709
1710 if (Pstream::master())
1711 {
1712 ITHACAstream::SaveDenseTensor(Cf_tensor, "./ITHACAoutput/Matrices/",
1713 "Cf_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
1714 NSUPmodes) + "_t");
1715 }
1716
1717 return Cf_tensor;
1718}
1719
1721{
1722 label BCsize = inletIndex.rows();
1723 List<Eigen::MatrixXd> LinSysDivDummy;
1724 LinSysDiv.resize(BCsize + 1);
1725 volScalarField p(_p());
1726
1727 for (label i = 0; i < BCsize; i++)
1728 {
1729 label BCind = inletIndex(i, 0);
1730 Vector<double> v(0, 0, 0);
1731 v[inletIndex(i, 1)] = 1;
1732 volVectorField Upara(Uinl());
1733 assignBC(Upara, BCind, v);
1734 fvScalarMatrix pEqn
1735 (
1736 fvm::laplacian(p) == (1.0 / dt_dummy) * fvc::div(Upara)
1737 );
1738 pEqn.setReference(0, 0);
1739 LinSysDivDummy = Pmodes.project(pEqn, NPmodes);
1740
1741 if (i == 0)
1742 {
1743 LinSysDiv[0] = LinSysDivDummy[0];
1744 }
1745
1746 LinSysDiv[i + 1] = LinSysDivDummy[1];
1747 }
1748
1749 return LinSysDiv;
1750}
1751
1753 label NPmodes)
1754{
1755 label BCsize = inletIndex.rows();
1756 List<Eigen::MatrixXd> LinSysConvDummy;
1757 LinSysConv.resize(BCsize + 1);
1758 volScalarField p(_p());
1759
1760 for (label i = 0; i < BCsize; i++)
1761 {
1762 label BCind = inletIndex(i, 0);
1763 Vector<double> v(0, 0, 0);
1764 v[inletIndex(i, 1)] = 1;
1765 volVectorField Upara(Uinl());
1766 assignBC(Upara, BCind, v);
1767 volVectorField Caux(L_U_SUPmodes[0]);
1768 Caux = dt_dummy * (-fvc::div(fvc::flux(Upara), Upara));
1769 fvScalarMatrix pEqn
1770 (
1771 fvm::laplacian(p) == (1.0 / dt_dummy) * fvc::div(Caux)
1772 );
1773 pEqn.setReference(0, 0);
1774 LinSysConvDummy = Pmodes.project(pEqn, NPmodes);
1775
1776 if (i == 0)
1777 {
1778 LinSysConv[0] = LinSysConvDummy[0];
1779 }
1780
1781 LinSysConv[i + 1] = LinSysConvDummy[1];
1782 }
1783
1784 return LinSysConv;
1785}
1786
1788 label NPmodes)
1789{
1790 label BCsize = inletIndex.rows();
1791 List<Eigen::MatrixXd> LinSysDiffDummy;
1792 LinSysDiff.resize(BCsize + 1);
1793 volScalarField p(_p());
1794
1795 for (label i = 0; i < BCsize; i++)
1796 {
1797 label BCind = inletIndex(i, 0);
1798 Vector<double> v(0, 0, 0);
1799 v[inletIndex(i, 1)] = 1;
1800 volVectorField Upara(Uinl());
1801 assignBC(Upara, BCind, v);
1802 volVectorField Daux(L_U_SUPmodes[0]);
1803 Daux = dt_dummy * fvc::laplacian(nu_dummy(), Upara);
1804 fvScalarMatrix pEqn
1805 (
1806 fvm::laplacian(p) == (1.0 / dt_dummy) * fvc::div(Daux)
1807 );
1808 pEqn.setReference(0, 0);
1809 LinSysDiffDummy = Pmodes.project(pEqn, NPmodes);
1810
1811 if (i == 0)
1812 {
1813 LinSysDiff[0] = LinSysDiffDummy[0];
1814 }
1815
1816 LinSysDiff[i + 1] = LinSysDiffDummy[1];
1817 }
1818
1819 return LinSysDiff;
1820}
1821
1823 label NPmodes,
1824 label NSUPmodes)
1825{
1826 label Isize = NUmodes + NSUPmodes + liftfield.size();
1827 Eigen::MatrixXd I_matrix;
1828 I_matrix.resize(NUmodes, Isize);
1829
1830 for (label i = 0; i < NUmodes; i++)
1831 {
1832 volVectorField CoeffA = (fvc::reconstruct(L_PHImodes[i])).ref();
1833
1834 for (label j = 0; j < Isize; j++)
1835 {
1836 surfaceScalarField B = fvc::flux(L_U_SUPmodes[j]).ref();
1837 volVectorField CoeffB = fvc::reconstruct(B).ref();
1838 I_matrix(i, j) = fvc::domainIntegrate(CoeffA & CoeffB).value();
1839 }
1840 }
1841
1842 if (Pstream::master())
1843 {
1844 ITHACAstream::SaveDenseMatrix(I_matrix, "./ITHACAoutput/Matrices/",
1845 "I_" + name(NUmodes));
1846 }
1847
1848 return I_matrix;
1849}
1850
1852 label NPmodes,
1853 label NSUPmodes)
1854{
1855 label DFsize = NUmodes + NSUPmodes + liftfield.size();
1856 Eigen::MatrixXd DF_matrix;
1857 DF_matrix.resize(DFsize, NUmodes);
1858 surfaceScalarField phi_tmp("Phi_tmp", _phi());
1859
1860 for (label i = 0; i < NUmodes; i++)
1861 {
1862 for (label j = 0; j < DFsize; j++)
1863 {
1864 phi_tmp = dt_dummy * nu_dummy() * fvc::flux(fvc::laplacian(
1865 dimensionedScalar("1", dimless, 1),
1866 L_U_SUPmodes[j]));
1867 volVectorField CoeffB = fvc::reconstruct(phi_tmp).ref();
1868 volVectorField CoeffA = fvc::reconstruct(L_PHImodes[i]).ref();
1869 DF_matrix(i, j) = fvc::domainIntegrate(CoeffA & CoeffB).value();
1870 }
1871 }
1872
1873 if (Pstream::master())
1874 {
1875 ITHACAstream::SaveDenseMatrix(DF_matrix, "./ITHACAoutput/Matrices/",
1876 "DF_" + name(NUmodes) + "_" + name(
1877 NSUPmodes));
1878 }
1879
1880 return DF_matrix;
1881}
1882
1884 label NPmodes,
1885 label NSUPmodes)
1886{
1887 label KF1size = NUmodes ;
1888 label KF2size = NPmodes;
1889 Eigen::MatrixXd KF_matrix(KF1size, KF2size);
1890
1891 for (label i = 0; i < KF1size; i++)
1892 {
1893 for (label j = 0; j < KF2size; j++)
1894 {
1895 volVectorField CoeffA = (fvc::reconstruct(dt_dummy * fvc::snGrad(
1896 Pmodes[j]) * mag(Pmodes[j].mesh().magSf()))).ref();
1897 volVectorField CoeffB = fvc::reconstruct(L_PHImodes[i]).ref();
1898 KF_matrix(i, j) = fvc::domainIntegrate(CoeffA & CoeffB).value();
1899 }
1900 }
1901
1902 if (Pstream::master())
1903 {
1904 ITHACAstream::SaveDenseMatrix(KF_matrix, "./ITHACAoutput/Matrices/",
1905 "KF_" + name(NUmodes) + "_" + name(
1906 NSUPmodes));
1907 }
1908
1909 return KF_matrix;
1910}
1911
1913 label NUmodes,
1914 label NPmodes, label NSUPmodes)
1915{
1916 label Csize1 = NUmodes + NSUPmodes + liftfield.size();
1917 Eigen::Tensor<double, 3> Ci_tensor;
1918 volVectorField L_U_SUPmodesaux(L_U_SUPmodes[0]);
1919 Ci_tensor.resize(NUmodes, Csize1, Csize1);
1920 surfaceScalarField phi_tmp("Phi_tmp", _phi());
1921
1922 for (label i = 0; i < NUmodes; i++)
1923 {
1924 for (label j = 0; j < Csize1; j++)
1925 {
1926 for (label k = 0; k < Csize1; k++)
1927 {
1928 phi_tmp = dt_dummy * fvc::flux(fvc::div(L_PHImodes[i], L_U_SUPmodes[k]));
1929 volVectorField CoeffA = fvc::reconstruct(phi_tmp).ref();
1930 volVectorField CoeffB = fvc::reconstruct(L_PHImodes[j]).ref();
1931 Ci_tensor(i, j, k) = fvc::domainIntegrate(CoeffB & CoeffA).value();
1932 }
1933 }
1934 }
1935
1936 if (Pstream::master())
1937 {
1938 ITHACAstream::SaveDenseTensor(Ci_tensor, "./ITHACAoutput/Matrices/",
1939 "Ci_" + name(liftfield.size()) + "_" + name(NUmodes) + "_" + name(
1940 NSUPmodes) + "_t");
1941 }
1942
1943 return Ci_tensor;
1944}
1945
1947 label NUmodes,
1948 label NSUPmodes)
1949{
1950 label BCsize = inletIndex.rows();
1951 label SDsize = NUmodes + NSUPmodes;
1952 List <Eigen::MatrixXd> SD_matrix(BCsize);
1953 surfaceScalarField phi_tmp("Phi_tmp", _phi());
1954
1955 for (label i = 0; i < BCsize; i++)
1956 {
1957 label BCind = inletIndex(i, 0);
1958 Vector<double> v(0, 0, 0);
1959 v[inletIndex(i, 1)] = 1;
1960 volVectorField Upara(Uinl());
1961 assignBC(Upara, BCind, v);
1962 SD_matrix[i].resize(SDsize, 1);
1963
1964 // Project everything
1965 for (label j = 0; j < SDsize; j++)
1966 {
1967 volVectorField CoeffB = fvc::reconstruct(L_PHImodes[j]).ref();
1968 phi_tmp = dt_dummy * fvc::flux(fvc::laplacian(nu_dummy(), Upara));
1969 volVectorField CoeffA = fvc::reconstruct(phi_tmp).ref();
1970 SD_matrix[i](j, 0) = fvc::domainIntegrate(CoeffA & CoeffB).value();
1971 }
1972
1973 ITHACAstream::SaveDenseMatrix(SD_matrix[i], "./ITHACAoutput/Matrices/SD/",
1974 "SD" + name(i) + "_" + name(NUmodes) + "_" + name(NSUPmodes));
1975 }
1976
1977 return SD_matrix;
1978}
1979
1981 label NUmodes,
1982 label NSUPmodes)
1983{
1984 label BCsize = inletIndex.rows();
1985 label SCsize = NUmodes + NSUPmodes;
1986 List <Eigen::MatrixXd> SC_matrix(BCsize);
1987 surfaceScalarField phi_tmp("Phi_tmp", _phi());
1988
1989 for (label i = 0; i < BCsize; i++)
1990 {
1991 label BCind = inletIndex(i, 0);
1992 Vector<double> v(0, 0, 0);
1993 v[inletIndex(i, 1)] = 1;
1994 volVectorField Upara(Uinl());
1995 assignBC(Upara, BCind, v);
1996 SC_matrix[i].resize(SCsize, 1);
1997
1998 // Project everything
1999 for (label j = 0; j < SCsize; j++)
2000 {
2001 volVectorField CoeffB = fvc::reconstruct(L_PHImodes[j]).ref();
2002 phi_tmp = dt_dummy * fvc::flux(fvc::div(fvc::flux(Upara), Upara));
2003 volVectorField CoeffA = fvc::reconstruct(phi_tmp).ref();
2004 SC_matrix[i](j, 0) = fvc::domainIntegrate(CoeffA & CoeffB).value();
2005 }
2006
2007 ITHACAstream::SaveDenseMatrix(SC_matrix[i], "./ITHACAoutput/Matrices/SC/",
2008 "SD" + name(i) + "_" + name(NUmodes) + "_" + name(NSUPmodes));
2009 }
2010
2011 return SC_matrix;
2012}
2013
2015 label NPmodes,
2016 label NSUPmodes)
2017{
2018 Eigen::MatrixXd W_matrix;
2019 W_matrix.resize(NUmodes, NUmodes);
2020
2021 for (label i = 0; i < NUmodes; i++)
2022 {
2023 volVectorField A = fvc::reconstruct(L_PHImodes[i]).ref();
2024
2025 for (label j = 0; j < NUmodes; j++)
2026 {
2027 volVectorField B = fvc::reconstruct(L_PHImodes[j]).ref();
2028 W_matrix(i, j) = fvc::domainIntegrate(A & B).value();
2029 }
2030 }
2031
2032 ITHACAstream::SaveDenseMatrix(W_matrix, "./ITHACAoutput/Matrices/",
2033 "W_" + name(NUmodes));
2034 return W_matrix;
2035}
2036
2037
2039{
2040 const volScalarField& nu = _laminarTransport().nu();
2041 volScalarField& ciao = const_cast<volScalarField&>(nu);
2042 this->assignIF(ciao, mu);
2043
2044 for (label i = 0; i < ciao.boundaryFieldRef().size(); i++)
2045 {
2046 this->assignBC(ciao, i, mu);
2047 }
2048}
2049
2050
2052{
2053 tauMatrix.resize(L_U_SUPmodes.size(), 3);
2054 nMatrix.resize(NPmodes, 3);
2055 tauMatrix = tauMatrix * 0;
2056 nMatrix = nMatrix * 0;
2057 Time& runTime = _runTime();
2058 instantList Times = runTime.times();
2059 fvMesh& mesh = _mesh();
2060 volScalarField& p = _p();
2061 volVectorField& U = _U();
2062 //Read FORCESdict
2063 IOdictionary FORCESdict
2064 (
2065 IOobject
2066 (
2067 "FORCESdict",
2068 runTime.system(),
2069 mesh,
2070 IOobject::MUST_READ,
2071 IOobject::NO_WRITE
2072 )
2073 );
2074 IOdictionary transportProperties
2075 (
2076 IOobject
2077 (
2078 "transportProperties",
2079 runTime.constant(),
2080 mesh,
2081 IOobject::MUST_READ,
2082 IOobject::NO_WRITE
2083 )
2084 );
2085 word pName(FORCESdict.lookup("pName"));
2086 word UName(FORCESdict.lookup("UName"));
2087 functionObjects::ITHACAforces f("Forces", mesh, FORCESdict);
2088
2089 for (label i = 0; i < L_U_SUPmodes.size(); i++)
2090 {
2091 U = L_U_SUPmodes[i];
2092 p = Pmodes[0];
2093 mesh.readUpdate();
2094 f.write();
2095 f.calcForcesMoment();
2096
2097 for (label j = 0; j < 3; j++)
2098 {
2099 tauMatrix(i, j) = f.forceTau()[j];
2100 }
2101 }
2102
2103 for (label i = 0; i < NPmodes; i++)
2104 {
2105 U = L_U_SUPmodes[0];
2106 p = Pmodes[i];
2107 mesh.readUpdate();
2108 f.write();
2109 f.calcForcesMoment();
2110
2111 for (label j = 0; j < 3; j++)
2112 {
2113 nMatrix(i, j) = f.forcePressure()[j];
2114 }
2115 }
2116
2117 if (para->exportPython)
2118 {
2119 ITHACAstream::exportMatrix(tauMatrix, "tau", "python",
2120 "./ITHACAoutput/Matrices/");
2121 ITHACAstream::exportMatrix(nMatrix, "n", "python", "./ITHACAoutput/Matrices/");
2122 }
2123
2124 if (para->exportMatlab)
2125 {
2126 ITHACAstream::exportMatrix(tauMatrix, "tau", "matlab",
2127 "./ITHACAoutput/Matrices/");
2128 ITHACAstream::exportMatrix(nMatrix, "n", "matlab", "./ITHACAoutput/Matrices/");
2129 }
2130
2131 if (para->exportTxt)
2132 {
2133 ITHACAstream::exportMatrix(tauMatrix, "tau", "eigen",
2134 "./ITHACAoutput/Matrices/");
2135 ITHACAstream::exportMatrix(nMatrix, "n", "eigen", "./ITHACAoutput/Matrices/");
2136 }
2137}
2138
2140{
2141 tauMatrix.resize(nModes, 3);
2142 nMatrix.resize(nModes, 3);
2143 tauMatrix = tauMatrix * 0;
2144 nMatrix = nMatrix * 0;
2145 Time& runTime = _runTime();
2146 instantList Times = runTime.times();
2147 fvMesh& mesh = _mesh();
2148 volScalarField& p = _p();
2149 volVectorField& U = _U();
2150 //Read FORCESdict
2151 IOdictionary FORCESdict
2152 (
2153 IOobject
2154 (
2155 "FORCESdict",
2156 runTime.system(),
2157 mesh,
2158 IOobject::MUST_READ,
2159 IOobject::NO_WRITE
2160 )
2161 );
2162 IOdictionary transportProperties
2163 (
2164 IOobject
2165 (
2166 "transportProperties",
2167 runTime.constant(),
2168 mesh,
2169 IOobject::MUST_READ,
2170 IOobject::NO_WRITE
2171 )
2172 );
2173 word pName(FORCESdict.lookup("pName"));
2174 word UName(FORCESdict.lookup("UName"));
2175 functionObjects::ITHACAforces f("Forces", mesh, FORCESdict);
2176
2177 for (label i = 0; i < nModes; i++)
2178 {
2179 U = Umodes[i];
2180 p = Pmodes[0];
2181 mesh.readUpdate();
2182 f.write();
2183 f.calcForcesMoment();
2184
2185 for (label j = 0; j < 3; j++)
2186 {
2187 tauMatrix(i, j) = f.forceTau()[j];
2188 }
2189 }
2190
2191 for (label i = 0; i < nModes; i++)
2192 {
2193 U = Umodes[0];
2194 p = Pmodes[i];
2195 mesh.readUpdate();
2196 f.write();
2197 f.calcForcesMoment();
2198
2199 for (label j = 0; j < 3; j++)
2200 {
2201 nMatrix(i, j) = f.forcePressure()[j];
2202 }
2203 }
2204
2205 if (para->exportPython)
2206 {
2207 ITHACAstream::exportMatrix(tauMatrix, "tau", "python",
2208 "./ITHACAoutput/Matrices/");
2209 ITHACAstream::exportMatrix(nMatrix, "n", "python", "./ITHACAoutput/Matrices/");
2210 }
2211
2212 if (para->exportMatlab)
2213 {
2214 ITHACAstream::exportMatrix(tauMatrix, "tau", "matlab",
2215 "./ITHACAoutput/Matrices/");
2216 ITHACAstream::exportMatrix(nMatrix, "n", "matlab", "./ITHACAoutput/Matrices/");
2217 }
2218
2219 if (para->exportTxt)
2220 {
2221 ITHACAstream::exportMatrix(tauMatrix, "tau", "eigen",
2222 "./ITHACAoutput/Matrices/");
2223 ITHACAstream::exportMatrix(nMatrix, "n", "eigen", "./ITHACAoutput/Matrices/");
2224 }
2225}
2226
2227void steadyNS::reconstructLiftAndDrag(const Eigen::MatrixXd& velCoeffs,
2228 const Eigen::MatrixXd& pressureCoeffs, fileName folder)
2229{
2230 M_Assert(velCoeffs.cols() == tauMatrix.rows(),
2231 "The number of velocity modes in the coefficients matrix is not equal to the number of modes in the viscous forces matrix.");
2232 M_Assert(pressureCoeffs.cols() == nMatrix.rows(),
2233 "The number of pressure modes in the coefficients matrix is not equal to the number of modes in the pressure forces matrix.");
2234 mkDir(folder);
2235 system("ln -s ../../constant " + folder + "/constant");
2236 system("ln -s ../../0 " + folder + "/0");
2237 system("ln -s ../../system " + folder + "/system");
2238 //Read FORCESdict
2239 IOdictionary FORCESdict
2240 (
2241 IOobject
2242 (
2243 "FORCESdict",
2244 "./system",
2245 Umodes[0].mesh(),
2246 IOobject::MUST_READ,
2247 IOobject::NO_WRITE
2248 )
2249 );
2250 Eigen::MatrixXd fTau;
2251 Eigen::MatrixXd fN;
2252 fTau.setZero(velCoeffs.rows(), 3);
2253 fN.setZero(pressureCoeffs.rows(), 3);
2254 fTau = velCoeffs * tauMatrix;
2255 fN = pressureCoeffs * nMatrix;
2256
2257 // Export the matrices
2258 if (para->exportPython)
2259 {
2260 ITHACAstream::exportMatrix(fTau, "fTau", "python", folder);
2261 ITHACAstream::exportMatrix(fN, "fN", "python", folder);
2262 }
2263
2264 if (para->exportMatlab)
2265 {
2266 ITHACAstream::exportMatrix(fTau, "fTau", "matlab", folder);
2267 ITHACAstream::exportMatrix(fN, "fN", "matlab", folder);
2268 }
2269
2270 if (para->exportTxt)
2271 {
2272 ITHACAstream::exportMatrix(fTau, "fTau", "eigen", folder);
2273 ITHACAstream::exportMatrix(fN, "fN", "eigen", folder);
2274 }
2275}
2276
2278{
2279 //_runTime().objectRegistry::clear();
2280 //_mesh().objectRegistry::clear();
2281 // _mesh.clear();
2282 // _runTime.clear();
2283 //_simple.clear();
2284 _p.clear();
2285 _U.clear();
2286 _phi.clear();
2287 turbulence.clear();
2288 _fvOptions.clear();
2289 argList& args = _args();
2290 Time& runTime = _runTime();
2291 runTime.setTime(0, 1);
2292 Foam::fvMesh& mesh = _mesh();
2293 // _simple = autoPtr<simpleControl>
2294 // (
2295 // new simpleControl
2296 // (
2297 // mesh
2298 // )
2299 // );
2300 simpleControl& simple = _simple();
2301 Info << "ReReading field p\n" << endl;
2302 _p = autoPtr<volScalarField>
2303 (
2304 new volScalarField
2305 (
2306 IOobject
2307 (
2308 "p",
2309 runTime.timeName(),
2310 mesh,
2311 IOobject::MUST_READ,
2312 IOobject::AUTO_WRITE
2313 ),
2314 mesh
2315 )
2316 );
2317 volScalarField& p = _p();
2318 Info << "ReReading field U\n" << endl;
2319 _U = autoPtr<volVectorField>
2320 (
2321 new volVectorField
2322 (
2323 IOobject
2324 (
2325 "U",
2326 runTime.timeName(),
2327 mesh,
2328 IOobject::MUST_READ,
2329 IOobject::AUTO_WRITE
2330 ),
2331 mesh
2332 )
2333 );
2334 volVectorField& U = _U();
2335 Info << "ReReading/calculating face flux field phi\n" << endl;
2336 _phi = autoPtr<surfaceScalarField>
2337 (
2338 new surfaceScalarField
2339 (
2340 IOobject
2341 (
2342 "phi",
2343 runTime.timeName(),
2344 mesh,
2345 IOobject::READ_IF_PRESENT,
2346 IOobject::AUTO_WRITE
2347 ),
2348 linearInterpolate(U) & mesh.Sf()
2349 )
2350 );
2351 surfaceScalarField& phi = _phi();
2352 pRefCell = 0;
2353 pRefValue = 0.0;
2355 _laminarTransport = autoPtr<singlePhaseTransportModel>
2356 (
2357 new singlePhaseTransportModel( U, phi )
2358 );
2359 singlePhaseTransportModel& laminarTransport = _laminarTransport();
2360 turbulence = autoPtr<incompressible::turbulenceModel>
2361 (
2362 incompressible::turbulenceModel::New(U, phi, laminarTransport)
2363 );
2364 _MRF = autoPtr<IOMRFZoneList>
2365 (
2366 new IOMRFZoneList(mesh)
2367 );
2368 _fvOptions = autoPtr<fv::options>(new fv::options(mesh));
2369 turbulence->validate();
2370}
forAll(example_CG.gList, solutionI)
Definition CGtest.H:21
Foam::fvMesh & mesh
Definition createMesh.H:47
Foam::Time & runTime
Definition createTime.H:33
#define M_Assert(Expr, Msg)
fv::options & fvOptions
Definition NLsolve.H:25
TEqn solve()
fvScalarMatrix pEqn
Definition CFM.H:31
static Eigen::VectorXd field2Eigen(GeometricField< tensor, PatchField, GeoMesh > &field)
Convert a vector OpenFOAM field into an Eigen Vector.
Definition Foam2Eigen.C:40
static void fvMatrix2Eigen(fvMatrix< type_foam_matrix > foam_matrix, type_A &A, type_B &b)
Convert a FvMatrix OpenFOAM matrix (Linear System) into a Eigen Matrix A and a source vector b.
static ITHACAparameters * getInstance()
Gets an instance of ITHACAparameters, to be used if the instance is already existing.
void writeMu(List< scalar > mu_now)
Write out a list of scalar corresponding to the parameters used in the truthSolve.
Eigen::MatrixXd mu_samples
Matrix of parameters to be used for PODI, where each row corresponds to a sample point....
label counter
Counter used for the output of the full order solutions.
void assignBC(volVectorField &s, label BC_ind, Vector< double > &value)
Assign Boundary Condition to a volVectorField.
void assignIF(T &s, G &value)
Assign internal field condition.
bool offline
Boolean variable, it is 1 if the Offline phase has already been computed, else 0.
IOdictionary * ITHACAdict
dictionary to store input output infos
Eigen::MatrixXd mu
Row matrix of parameters.
autoPtr< argList > _args
argList
Eigen::MatrixXi inletIndex
Matrix that contains informations about the inlet boundaries.
bool podex
Boolean variable, it is 1 if the POD has already been computed, else 0.
void truthSolve()
Perform a TruthSolve.
void change_viscosity(double mu)
Function to change the viscosity.
Definition steadyNS.C:2038
List< Eigen::MatrixXd > bcVelVec
Boundary term for penalty method - vector.
Definition steadyNS.H:227
scalar maxIter
Number of maximum iterations to be done for the computation of the truth solution.
Definition steadyNS.H:128
void restart()
set U and P back to the values into the 0 folder
Definition steadyNS.C:2277
List< Eigen::MatrixXd > pressure_gradient_term_linsys_div(label NPmodes)
Laplacian of pressure Linear System - Divergence term.
Definition steadyNS.C:1720
label NPmodes
Number of pressure modes used for the projection.
Definition steadyNS.H:146
List< Eigen::MatrixXd > pressure_gradient_term_linsys_conv(label NPmodes)
Laplacian of pressure Linear System - Convection term.
Definition steadyNS.C:1752
bool supex
Boolean variable to check the existence of the supremizer modes.
Definition steadyNS.H:265
void projectPPE(fileName folder, label NUmodes, label NPmodes, label NSUPmodes=0)
Project using the Poisson Equation for pressure.
Definition steadyNS.C:354
Eigen::MatrixXd nMatrix
Pressure forces.
Definition steadyNS.H:224
Eigen::MatrixXd BC1_matrix
PPE BC1.
Definition steadyNS.H:191
Eigen::MatrixXd diffusive_term(label NUmodes, label NPmodes, label NSUPmodes)
Diffusive Term.
Definition steadyNS.C:883
autoPtr< surfaceScalarField > _phi
Flux.
Definition steadyNS.H:302
Eigen::MatrixXd BC4_matrix
PPE BC4.
Definition steadyNS.H:203
Eigen::MatrixXd tauMatrix
Viscous forces.
Definition steadyNS.H:221
Eigen::MatrixXd BC3_matrix
PPE BC3.
Definition steadyNS.H:200
Eigen::Tensor< double, 3 > C_tensor
Diffusion term.
Definition steadyNS.H:170
Eigen::Tensor< double, 3 > convective_term_tens_cache(label NUmodes, label NPmodes, label NSUPmodes)
Export convective term as a tensor using the cached procedure.
Definition steadyNS.C:1038
void forcesMatrices(label NUmodes, label NPmodes, label NSUPmodes)
Compute lift and drag matrices.
Definition steadyNS.C:2051
autoPtr< simpleControl > _simple
simpleControl
Definition steadyNS.H:293
surfaceScalarModes L_PHImodes
List of pointers containing the total number of flux modes.
Definition steadyNS.H:122
PtrList< volScalarField > Pfield
List of pointers used to form the pressure snapshots matrix.
Definition steadyNS.H:86
volVectorModes supmodes
List of pointers used to form the supremizer modes.
Definition steadyNS.H:104
List< Eigen::MatrixXd > bcVelocityVec(label NUmodes, label NSUPmodes)
Boundary integral modes on boundary used by the penaly method.
Definition steadyNS.C:1487
List< Eigen::MatrixXd > boundary_vector_convection_consistent(label NUmodes, label NSUPmodes)
Boundary vector convection term - Consistent Flux Method.
Definition steadyNS.C:1980
Eigen::MatrixXd W_matrix
Mass Matrix New Time Step - Consistent Flux Method.
Definition steadyNS.H:206
Eigen::MatrixXd mass_matrix_oldtime_consistent(label NUmodes, label NPmodes, label NSUPmodes)
Mass Matrix old time step (consistent flux method)
Definition steadyNS.C:1822
List< Eigen::MatrixXd > pressure_gradient_term_linsys_diff(label NPmodes)
Laplacian of pressure Linear System - Diffusion term.
Definition steadyNS.C:1787
autoPtr< fv::options > _fvOptions
fvOptions
Definition steadyNS.H:296
Eigen::MatrixXd pressure_BC4(label NPmodes, label NUmodes)
Term N° 4 given by the additional boundary condition using a PPE approach for time-dependent BCs.
Definition steadyNS.C:1452
void solvesupremizer(word type="snapshots")
solve the supremizer either with the use of the pressure snaphots or the pressure modes
Definition steadyNS.C:137
autoPtr< Time > _runTime
Time.
Definition steadyNS.H:299
Eigen::MatrixXd I_matrix
Mass Matrix Old Time Step - Consistent Flux Method.
Definition steadyNS.H:209
volVectorModes Umodes
List of pointers used to form the velocity modes.
Definition steadyNS.H:101
Eigen::MatrixXd diffusive_term_sym(label NUmodes, label NPmodes, label NSUPmodes)
Symetric diffusive Term.
Definition steadyNS.C:909
PtrList< volVectorField > Ufield
List of pointers used to form the velocity snapshots matrix.
Definition steadyNS.H:89
List< Eigen::MatrixXd > boundary_vector_diffusion_consistent(label NUmodes, label NSUPmodes)
Boundary vector diffusion term (consistent flux method)
Definition steadyNS.C:1946
List< Eigen::MatrixXd > LinSysDiff
Projection Peqn onto Pressure modes - Diffusion term.
Definition steadyNS.H:257
autoPtr< dimensionedScalar > dt_dummy
Dummy time step including unit.
Definition steadyNS.H:284
Eigen::MatrixXd diffusive_term_flux_method(label NUmodes, label NPmodes, label NSUPmodes)
Diffusive Flux Method.
Definition steadyNS.C:1556
Eigen::MatrixXd diffusive_term_consistent(label NUmodes, label NPmodes, label NSUPmodes)
Diffusion Term (consistent flux method)
Definition steadyNS.C:1851
Eigen::MatrixXd pressure_BC1(label NPmodes, label NUmodes)
Term N° 1 given by the additional boundary condition using a PPE approach.
Definition steadyNS.C:1309
steadyNS()
Null constructor.
Definition steadyNS.C:40
Eigen::MatrixXd divergence_term(label NUmodes, label NPmodes, label NSUPmodes)
Divergence Term (supremizer approach)
Definition steadyNS.C:1110
List< Eigen::MatrixXd > G_matrix
Divergence of momentum PPE.
Definition steadyNS.H:185
scalar tolerance
Tolerance for the residual of the stationary problems, there is the same tolerance for velocity and p...
Definition steadyNS.H:125
Eigen::MatrixXd mass_term(label NUmodes, label NPmodes, label NSUPmodes)
Mass Term.
Definition steadyNS.C:1084
Eigen::Tensor< double, 3 > divMomentum_cache(label NUmodes, label NPmodes)
Divergence of convective term (PPE approach) using the cached procedure.
Definition steadyNS.C:1205
autoPtr< fvMesh > _mesh
Mesh.
Definition steadyNS.H:290
autoPtr< singlePhaseTransportModel > _laminarTransport
Laminar transport (used by turbulence model)
Definition steadyNS.H:311
label NUmodes
Number of velocity modes used for the projection.
Definition steadyNS.H:143
autoPtr< dimensionedScalar > nu_dummy
Dummy viscocity including unit.
Definition steadyNS.H:287
List< Eigen::MatrixXd > boundary_vector_diffusion(label NUmodes, label NPmodes, label NSUPmodes)
Boundary vector diffusion term.
Definition steadyNS.C:1584
List< Eigen::MatrixXd > LinSysDiv
Projection Peqn onto Pressure modes - Divergence term.
Definition steadyNS.H:254
PtrList< volVectorField > liftfield
List of pointers used to form the list of lifting functions.
Definition steadyNS.H:110
Eigen::Tensor< double, 3 > convective_term_flux_tens(label NUmodes, label NPmodes, label NSUPmodes)
Convective Term.
Definition steadyNS.C:1676
Eigen::Tensor< double, 3 > convective_term_consistent_tens(label NUmodes, label NPmodes, label NSUPmodes)
Convective Term (consistent flux method)
Definition steadyNS.C:1912
scalar pRefValue
Reference pressure value.
Definition steadyNS.H:320
label pRefCell
Reference pressure cell.
Definition steadyNS.H:317
word fluxMethod
Flux Method.
Definition steadyNS.H:329
volVectorModes L_U_SUPmodes
List of pointers containing the total number of lift, supremizer and velocity modes.
Definition steadyNS.H:119
ITHACAparameters * para
Definition steadyNS.H:82
Eigen::MatrixXd pressure_BC3(label NPmodes, label NUmodes)
Term N° 3 given by the additional boundary condition using a PPE approach.
Definition steadyNS.C:1420
Eigen::MatrixXd L_matrix
Convective background / Large scale advection term.
Definition steadyNS.H:176
List< Eigen::MatrixXd > boundary_vector_convection(label NUmodes, label NPmodes, label NSUPmodes)
Boundary vector convection term.
Definition steadyNS.C:1630
Eigen::MatrixXd B_matrix
Diffusion term.
Definition steadyNS.H:160
List< Eigen::MatrixXd > RD_matrix
Boundary term for diffusion term.
Definition steadyNS.H:236
Eigen::MatrixXd D_matrix
Laplacian term PPE.
Definition steadyNS.H:182
autoPtr< IOMRFZoneList > _MRF
MRF variable.
Definition steadyNS.H:314
List< Eigen::MatrixXd > SD_matrix
Boundary term for diffusion term - Consistent Flux Method.
Definition steadyNS.H:242
label NSUPmodes
Number of supremizer modes used for the projection.
Definition steadyNS.H:149
Eigen::Tensor< double, 3 > gTensor
Divergence of momentum PPE.
Definition steadyNS.H:188
Eigen::MatrixXd KF_matrix
Pressure Gradient Term - Consistent Flux Method.
Definition steadyNS.H:215
Eigen::MatrixXd K_matrix
Gradient of pressure matrix.
Definition steadyNS.H:166
List< Eigen::MatrixXd > C_matrix
Non linear term.
Definition steadyNS.H:169
Eigen::Tensor< double, 3 > convective_term_tens(label NUmodes, label NPmodes, label NSUPmodes)
Export convective term as a tensor.
Definition steadyNS.C:997
autoPtr< incompressible::turbulenceModel > turbulence
Turbulence model.
Definition steadyNS.H:308
List< Eigen::MatrixXd > convective_term(label NUmodes, label NPmodes, label NSUPmodes)
Convective Term.
Definition steadyNS.C:962
Eigen::MatrixXd pressure_gradient_term_consistent(label NUmodes, label NPmodes, label NSUPmodes)
Pressure Gradient Term (consistent flux method)
Definition steadyNS.C:1883
List< Eigen::MatrixXd > pressure_BC2(label NPmodes, label NUmodes)
Term N° 2 given by the additional boundary condition using a PPE approach.
Definition steadyNS.C:1343
Eigen::MatrixXd divergent_convective_background(label NPmodes, label NUmodes, volVectorField vls)
Divergent of Large Scale / Background Advection.
Definition steadyNS.C:1268
List< Eigen::MatrixXd > LinSysConv
Projection Peqn onto Pressure modes - Convection term.
Definition steadyNS.H:260
PtrList< volVectorField > supfield
List of pointers used to form the supremizer snapshots matrix.
Definition steadyNS.H:92
Eigen::Tensor< double, 3 > divMomentum(label NUmodes, label NPmodes)
Divergence of convective term (PPE approach)
Definition steadyNS.C:1174
List< Eigen::MatrixXd > SC_matrix
Boundary term for convection term - Consistent Flux Method.
Definition steadyNS.H:245
Eigen::MatrixXd pressure_gradient_term(label NUmodes, label NPmodes, label NSUPmodes)
Gradient of pressure.
Definition steadyNS.C:935
Eigen::MatrixXd DF_matrix
Diffusion Term - Consistent Flux Method.
Definition steadyNS.H:212
List< Eigen::MatrixXd > bcVelMat
Boundary term for penalty method - matrix.
Definition steadyNS.H:230
Eigen::MatrixXd P_matrix
Div of velocity.
Definition steadyNS.H:173
List< Eigen::MatrixXd > RC_matrix
Boundary vector for convection term.
Definition steadyNS.H:239
Eigen::MatrixXd BP_matrix
Diffusion term for flux method PPE.
Definition steadyNS.H:233
Eigen::Tensor< double, 3 > Cf_tensor
Convection term for flux method.
Definition steadyNS.H:248
Eigen::MatrixXd L_D_matrix
Divergent convective background / Large scale advection term.
Definition steadyNS.H:179
Eigen::MatrixXd M_matrix
Mass Matrix.
Definition steadyNS.H:163
List< Eigen::MatrixXd > BC2_matrix
PPE BC2.
Definition steadyNS.H:194
autoPtr< volVectorField > Uinl
Initial dummy field with all Dirichlet boundary conditions.
Definition steadyNS.H:281
Eigen::MatrixXd convective_background(label NUmodes, volVectorField vls)
Large Scale / Background Advection.
Definition steadyNS.C:1251
void discretizeThenProject(fileName folder, label NUmodes, label NPmodes, label NSUPmodes=0)
Project using the Discretize-then-project approach.
Definition steadyNS.C:709
void projectSUP(fileName folder, label NUmodes, label NPmodes, label NSUPmodes)
Project using a supremizer approach.
Definition steadyNS.C:556
Eigen::MatrixXd laplacian_pressure(label NPmodes)
Laplacian of pressure term (PPE approach)
Definition steadyNS.C:1286
surfaceScalarModes Phimodes
List of pointers used to form the flux modes.
Definition steadyNS.H:107
Eigen::MatrixXd mass_matrix_newtime_consistent(label NUmodes, label NPmodes, label NSUPmodes)
Mass Matrix new time step (consistent flux method)
Definition steadyNS.C:2014
List< Eigen::MatrixXd > bcVelocityMat(label NUmodes, label NSUPmodes)
Boundary integral modes on boundary used by the penaly method.
Definition steadyNS.C:1519
Eigen::Tensor< double, 3 > bc2Tensor
PPE BC2.
Definition steadyNS.H:197
PtrList< volScalarField > liftfieldP
List of pointer used to form the list of lifting functions for the pressure.
Definition steadyNS.H:113
autoPtr< volVectorField > _U
Velocity field.
Definition steadyNS.H:272
Eigen::Tensor< double, 3 > pressureBC2(label NPmodes, label NUmodes)
Term N° 2 given by the additional boundary condition using a PPE approach.
Definition steadyNS.C:1380
Eigen::Tensor< double, 3 > Ci_tensor
Convection term - Consistent Flux Method.
Definition steadyNS.H:251
void liftSolve()
Perform a lift solve.
Definition steadyNS.C:253
List< Eigen::MatrixXd > div_momentum(label NUmodes, label NPmodes)
Divergence of convective term (PPE approach)
Definition steadyNS.C:1138
volScalarModes Pmodes
List of pointers used to form the pressure modes.
Definition steadyNS.H:98
word bcMethod
Boundary Method.
Definition steadyNS.H:326
void reconstructLiftAndDrag(const Eigen::MatrixXd &velCoeffs, const Eigen::MatrixXd &pressureCoeffs, fileName folder)
Method to reconstruct the forces using velocity and pressure coefficients.
Definition steadyNS.C:2227
autoPtr< volScalarField > _p
Pressure field.
Definition steadyNS.H:269
volScalarField & A
volScalarField v0(v)
volScalarField & v
dimensionedScalar & nu
void ReadDenseMatrix(MatrixType &Matrix, word folder, word MatrixName)
Read a dense matrix from a binary format file.
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 ...
void SaveDenseMatrix(MatrixType &Matrix, word folder, word MatrixName)
Save a dense matrix to a binary format file.
void ReadDenseTensor(TensorType &Tensor, word folder, word MatrixName)
Read a dense tensor from file.
void read_fields(PtrList< GeometricField< Type, PatchField, GeoMesh > > &Lfield, word Name, fileName casename, int first_snap, int n_snap)
Function to read a list of fields from the name of the field and casename.
void exportTensor(Eigen::Tensor< T, 3 > tensor, word Name, word type, word folder)
Export the reduced tensor in numpy (tipo=python), matlab (tipo=matlab) and txt (tipo=eigen) format.
void SaveDenseTensor(TensorType &Tensor, word folder, word MatrixName)
Save a dense tensor to file.
bool check_pod()
Check if the POD data folder "./ITHACAoutput/POD" exists.
bool check_off()
Check if the offline data folder "./ITHACAoutput/Offline" exists.
void assignZeroDirichlet(GeometricField< Type, fvPatchField, volMesh > &field)
Assign zero internal field.
bool check_folder(word folder)
Checks if a folder exists.
bool check_file(std::string fileName)
Function that returns true if a file exists.
bool check_sup()
Check if the supremizer folder exists.
void createSymLink(word folder)
Creates symbolic links to 0, system and constant.
void changeBCtype(GeometricField< Type, fvPatchField, volMesh > &field, word BCtype, label BC_ind)
Change the boundary condition type for a GeometricField.
void save(const Eigen::Matrix< T, -1, dim > &mat, const std::string fname)
simpleControl simple(mesh)
surfaceScalarField & phi
volVectorField & U
fvVectorMatrix & UEqn
Definition UEqn.H:13
volScalarField & p
IOdictionary transportProperties(IOobject("transportProperties", runTime.constant(), mesh, IOobject::MUST_READ_IF_MODIFIED, IOobject::NO_WRITE))
singlePhaseTransportModel & laminarTransport
setRefCell(p, mesh.solutionDict().subDict("SIMPLE"), pRefCell, pRefValue)
adjustPhi(phiHbyA, U, p)
label i
Definition pEqn.H:46
Header file of the steadyNS class.