Loading...
Searching...
No Matches
ReducedCompressibleSteadyNS.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
35
36// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * //
37
38// Constructor
42
44 CompressibleSteadyNS& FOMproblem)
45 :
46 problem(&FOMproblem)
47{
48 // Create a new Umodes set where the first ones are the lift functions
49 for (label i = 0; i < problem->liftfield.size(); i++)
50 {
51 ULmodes.append(problem->liftfield[i].clone());
52 }
53
54 for (label i = 0; i < problem->Umodes.size(); i++)
55 {
56 ULmodes.append(problem->Umodes.toPtrList()[i].clone());
57 }
58}
59
61{
62 M_Assert(problem->inletIndex.rows() == vel.size(),
63 "Imposed boundary conditions dimensions do not match given values matrix dimensions into setOnlineVelocity");
64 Eigen::MatrixXd vel_scal;
65 vel_scal.resize(vel.rows(), vel.cols());
66
67 for (int k = 0; k < problem->inletIndex.rows(); k++)
68 {
69 label p = problem->inletIndex(k, 0);
70 label l = problem->inletIndex(k, 1);
71 scalar area = gSum(problem->liftfield[0].mesh().magSf().boundaryField()[p]);
72 scalar u_lf = gSum(problem->liftfield[k].mesh().magSf().boundaryField()[p] *
73 problem->liftfield[k].boundaryField()[p]).component(l) / area;
74 vel_scal(k, 0) = vel(k, 0) / u_lf;
75 }
76
77 vel_now = vel_scal;
78}
79
80
82 int NmodesPproj, int NmodesEproj)
83{
84 PtrList<volVectorField> gradModP;
85
86 for (label i = 0; i < NmodesPproj; i++)
87 {
88 gradModP.append(fvc::grad(problem->Pmodes[i]));
89 }
90
91 projGradModP = problem->Umodes.project(gradModP, NmodesUproj);
92}
93
94// * * * * * * * * * * * * * * * Solve Functions * * * * * * * * * * * * * //
95
97 int NmodesUproj, int NmodesPproj, int NmodesEproj)
98{
99 counter++;
100 // Residuals initialization
101 scalar residualNorm(1);
102 scalar residualJump(1);
103 Eigen::MatrixXd uResidualOld = Eigen::MatrixXd::Zero(1, NmodesUproj);
104 Eigen::MatrixXd eResidualOld = Eigen::MatrixXd::Zero(1, NmodesEproj);
105 Eigen::MatrixXd pResidualOld = Eigen::MatrixXd::Zero(1, NmodesPproj);
106 Eigen::VectorXd uResidual(Eigen::Map<Eigen::VectorXd>(uResidualOld.data(),
107 NmodesUproj));
108 Eigen::VectorXd eResidual(Eigen::Map<Eigen::VectorXd>(eResidualOld.data(),
109 NmodesEproj));
110 Eigen::VectorXd pResidual(Eigen::Map<Eigen::VectorXd>(pResidualOld.data(),
111 NmodesPproj));
112 // Parameters definition
114 float residualJumpLim =
115 para->ITHACAdict->lookupOrDefault<float>("residualJumpLim", 1e-5);
116 float normalizedResidualLim =
117 para->ITHACAdict->lookupOrDefault<float>("normalizedResidualLim", 1e-5);
118 int maxIter =
119 para->ITHACAdict->lookupOrDefault<float>("maxIter", 2000);
120 bool closedVolume = false;
121 label csolve = 0;
122 // Full variables initialization
123 fluidThermo& thermo = problem->pThermo();
124 volVectorField& U = problem->_U();
125 volScalarField& P = problem->pThermo->p();
126 volScalarField& E = problem->pThermo->he();
127 volScalarField& rho = problem->_rho();
128 volScalarField& psi = problem->_psi();
129 surfaceScalarField& phi = problem->_phi();
130 Time& runTime = problem->_runTime();
131 fvMesh& mesh = problem->_mesh();
132 fv::options& fvOptions = problem->_fvOptions();
133 scalar cumulativeContErr = problem->cumulativeContErr;
134 // Reduced variables initialization
135 Eigen::MatrixXd u = Eigen::MatrixXd::Zero(NmodesUproj, 1);
136 Eigen::MatrixXd e = Eigen::MatrixXd::Zero(NmodesEproj, 1);
137 Eigen::MatrixXd p = Eigen::MatrixXd::Zero(NmodesPproj, 1);
138
139 while ((residualJump > residualJumpLim
140 || residualNorm > normalizedResidualLim) && csolve < maxIter)
141 {
142 csolve++;
143 Info << "csolve:" << csolve << endl;
144#if OFVER == 6
145 problem->_simple().loop(runTime);
146#else
147 problem->_simple().loop();
148#endif
149 uResidualOld = uResidual;
150 eResidualOld = eResidual;
151 pResidualOld = pResidual;
152 //Momentum equation phase
153 List<Eigen::MatrixXd> RedLinSysU;
154 //problem->getUmatrix(U);
155 fvVectorMatrix UEqnR
156 (
157 fvm::div(phi, U)
158 - fvc::div((rho * problem->turbulence->nuEff()) * dev2(T(fvc::grad(U))))
159 - fvm::laplacian(rho * problem->turbulence->nuEff(), U)
160 ==
161 fvOptions(rho, U)
162 );
163 UEqnR.relax();
164 fvOptions.constrain(UEqnR);
165 std::cout <<
166 "################################ line 165 ##############################" <<
167 std::endl;
168 //RedLinSysU = ULmodes.project(problem->Ueqn_global(), NmodesUproj);
169 RedLinSysU = problem->Umodes.project(UEqnR, NmodesUproj);
170 std::cout <<
171 "################################ line 169 ##############################" <<
172 std::endl;
173 Eigen::MatrixXd projGradP = projGradModP * p;
174 std::cout <<
175 "################################ line 171 ##############################" <<
176 std::endl;
177 RedLinSysU[1] = RedLinSysU[1] - projGradP;
178 //u = reducedProblem::solveLinearSys(RedLinSysU, u, uResidual, vel_now, "bdcSvd");
179 u = reducedProblem::solveLinearSys(RedLinSysU, u, uResidual);
180 std::cout <<
181 "################################ line 174 ##############################" <<
182 std::endl;
183 problem->Umodes.reconstruct(U, u, "U");
184 std::cout <<
185 "################################ line 175 ##############################" <<
186 std::endl;
187 //solve(problem->Ueqn_global() == -problem->getGradP(P)); //For debug purposes only, second part only useful when using uEqn_global==-getGradP
188 //solve(UEqnR == -problem->getGradP(P)); //For debug purposes only, second part only useful when using uEqn_global==-getGradP
189 fvOptions.correct(U);
190 //Energy equation phase
191 //problem->getEmatrix(U, P);
192 fvScalarMatrix EEqnR
193 (
194 fvm::div(phi, E)
195 + fvc::div(phi, volScalarField("Ekp", 0.5 * magSqr(U) + P / rho))
196 - fvm::laplacian(problem->turbulence->alphaEff(), E)
197 ==
198 fvOptions(rho, E)
199 );
200 EEqnR.relax();
201 fvOptions.constrain(EEqnR);
202 // List<Eigen::MatrixXd> RedLinSysE = problem->Emodes.project(
203 // problem->Eeqn_global(), NmodesEproj);
204 List<Eigen::MatrixXd> RedLinSysE = problem->Emodes.project(EEqnR, NmodesEproj);
205 std::cout <<
206 "################################ line 196 ##############################" <<
207 std::endl;
208 e = reducedProblem::solveLinearSys(RedLinSysE, e, eResidual);
209 problem->Emodes.reconstruct(E, e, "e");
210 std::cout <<
211 "################################ line 198 ##############################" <<
212 std::endl;
213 //problem->Eeqn_global().solve(); //For debug purposes only
214 //EEqnR.solve(); //For debug purposes only
215 fvOptions.correct(E);
216 thermo.correct(); // Here are calculated both temperature and density based on P,U and he.
217 // Pressure equation phase
218 // constrainPressure(P, rho, U, problem->getPhiHbyA(problem->Ueqn_global(), U, P),
219 // problem->getRhorAUf(problem->Ueqn_global()));// Update the pressure BCs to ensure flux consistency
220 // surfaceScalarField phiHbyACalculated = problem->getPhiHbyA(problem->Ueqn_global(), U, P);
221 constrainPressure(P, rho, U, problem->getPhiHbyA(UEqnR, U, P),
222 problem->getRhorAUf(
223 UEqnR));// Update the pressure BCs to ensure flux consistency
224 surfaceScalarField phiHbyACalculated = problem->getPhiHbyA(UEqnR, U, P);
225 closedVolume = adjustPhi(phiHbyACalculated, U, P);
226 List<Eigen::MatrixXd> RedLinSysP;
227
228 while (problem->_simple().correctNonOrthogonal())
229 {
230 // problem->getPmatrix(problem->Ueqn_global(), U, P);
231 volScalarField rAU(1.0 /
232 UEqnR.A()); // Inverse of the diagonal part of the U equation matrix
233 volVectorField HbyA(constrainHbyA(rAU * UEqnR.H(), U,
234 P)); // H is the extra diagonal part summed to the r.h.s. of the U equation
235 surfaceScalarField phiHbyA("phiHbyA", fvc::interpolate(rho)*fvc::flux(HbyA));
236 surfaceScalarField rhorAUf("rhorAUf", fvc::interpolate(rho * rAU));
237 fvScalarMatrix PEqnR
238 (
239 fvc::div(phiHbyA)
240 - fvm::laplacian(rhorAUf, P)
241 ==
242 fvOptions(psi, P, rho.name())
243 );
244 PEqnR.setReference
245 (
246 problem->_pressureControl().refCell(),
247 problem->_pressureControl().refValue()
248 );
249 // RedLinSysP = problem->Pmodes.project(problem->Peqn_global(), NmodesPproj);
250 RedLinSysP = problem->Pmodes.project(PEqnR, NmodesPproj);
251 p = reducedProblem::solveLinearSys(RedLinSysP, p, pResidual);
252 problem->Pmodes.reconstruct(P, p, "p");
253 //problem->Peqn_global().solve(); //For debug purposes only
254 //PEqnR.solve(); //For debug purposes only
255
256 if (problem->_simple().finalNonOrthogonalIter())
257 {
258 // phi = problem->getPhiHbyA(problem->Ueqn_global(), U, P) + problem->Peqn_global().flux();
259 phi = problem->getPhiHbyA(UEqnR, U,
260 P) + PEqnR.flux(); //Are you sure you still can use it?????????????????????????????????
261 }
262 }
263
264#include "continuityErrs.H"
265 P.relax();// Explicitly relax pressure for momentum corrector
266 //U = problem->HbyA() - (1.0 / problem->Ueqn_global().A()) * problem->getGradP(P);
267 U = problem->HbyA() - (1.0 / UEqnR.A()) * problem->getGradP(P);
268 U.correctBoundaryConditions();
269 fvOptions.correct(U);
270 bool pLimited = problem->_pressureControl().limit(P);
271
272 // For closed-volume cases adjust the pressure and density levels to obey overall mass continuity
273 if (closedVolume)
274 {
275 P += (problem->_initialMass() - fvc::domainIntegrate(psi * P))
276 / fvc::domainIntegrate(psi);
277 }
278
279 if (pLimited || closedVolume)
280 {
281 P.correctBoundaryConditions();
282 }
283
284 rho = thermo.rho(); // Here rho is calculated as p*psi = p/(R*T)
285 rho.relax();
286 std::cout << "Ures = " << (uResidual.cwiseAbs()).sum() /
287 (RedLinSysU[1].cwiseAbs()).sum() << std::endl;
288 std::cout << "Eres = " << (eResidual.cwiseAbs()).sum() /
289 (RedLinSysE[1].cwiseAbs()).sum() << std::endl;
290 std::cout << "Pres = " << (pResidual.cwiseAbs()).sum() /
291 (RedLinSysP[1].cwiseAbs()).sum() << std::endl;
292 // std::cout << "U = " << u << std::endl;
293 // std::cout << "E = " << e << std::endl;
294 // std::cout << "P = " << p << std::endl;
295 residualNorm = max(max((uResidual.cwiseAbs()).sum() /
296 (RedLinSysU[1].cwiseAbs()).sum(),
297 (pResidual.cwiseAbs()).sum() / (RedLinSysP[1].cwiseAbs()).sum()),
298 (eResidual.cwiseAbs()).sum() / (RedLinSysE[1].cwiseAbs()).sum());
299 residualJump = max(max(((uResidual - uResidualOld).cwiseAbs()).sum() /
300 (RedLinSysU[1].cwiseAbs()).sum(),
301 ((pResidual - pResidualOld).cwiseAbs()).sum() /
302 (RedLinSysP[1].cwiseAbs()).sum()),
303 ((eResidual - eResidualOld).cwiseAbs()).sum() /
304 (RedLinSysE[1].cwiseAbs()).sum());
305 std::cout << residualNorm << std::endl;
306 std::cout << residualJump << std::endl;
307 problem->turbulence->correct();
308 }
309
310 label k = 1;
311 ITHACAstream::exportSolution(U, name(counter), "./ITHACAoutput/Online/");
312 ITHACAstream::exportSolution(P, name(counter), "./ITHACAoutput/Online/");
313 ITHACAstream::exportSolution(E, name(counter), "./ITHACAoutput/Online/");
314}
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
label csolve
Definition NLsolve.H:42
maxIter
Definition NLsolve.H:75
bool closedVolume
Definition NLsolve.H:33
volScalarField & psi
Definition NLsolve.H:29
Header file of the reducedSteadyNS class.
Implementation of a parametrized full order steady NS problem and preparation of the the reduced ma...
Class for the definition of some general parameters, the parameters must be defined from the file ITH...
static ITHACAparameters * getInstance()
Gets an instance of ITHACAparameters, to be used if the instance is already existing.
Eigen::MatrixXd vel_now
Imposed boundary conditions.
void projectReducedOperators(int NmodesUproj, int NmodesPproj, int NmodesEproj)
It assembles the reduced oeprators using the modes.
void setOnlineVelocity(Eigen::MatrixXd vel)
It checks if the number of imposed boundary conditions is correct and set the inlet velocity equal to...
Eigen::MatrixXd projGradModP
Projected gradient of the pressure modes.
volVectorModes ULmodes
Lifted velocity modes.
CompressibleSteadyNS * problem
Full problem.
void solveOnlineCompressible(scalar mu_now, int NmodesUproj, int NmodesPproj, int NmodesEproj)
Method to perform an online solve using a PPE stabilisation method.
static Eigen::MatrixXd solveLinearSys(List< Eigen::MatrixXd > LinSys, Eigen::MatrixXd x, Eigen::VectorXd &residual, const Eigen::MatrixXd &bc=Eigen::MatrixXd::Zero(0, 0), const std::string solverType="fullPivLu")
Linear system solver for the online problem.
ITHACAparameters * para
parameters to be read from the ITHACAdict file
volScalarField & T
Definition createT.H:46
void exportSolution(GeometricField< Type, PatchField, GeoMesh > &s, fileName subfolder, fileName folder, word fieldName)
Export a field to file in a certain folder and subfolder.
volScalarField rAU(1.0/Ueqn.A())
constrainPressure(p, rho, U, phiHbyA, rhorAtU, MRF)
phiHbyA
Definition pcEqn.H:61
bool pLimited
Definition pcEqn.H:98
HbyA
Definition pcEqn.H:62
surfaceScalarField & phi
volVectorField & U
cumulativeContErr
volScalarField & p
volScalarField & rho
fluidThermo & thermo
surfaceScalarField rhorAUf("rhorAUf", fvc::interpolate(rho *rAU))
adjustPhi(phiHbyA, U, p)
label i
Definition pEqn.H:46