Loading...
Searching...
No Matches
SteadyNSSimple.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 "SteadyNSSimple.H"
36#include "viscosityModel.H"
37
38// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * //
39
40// Constructor
42
43SteadyNSSimple::SteadyNSSimple(int argc, char* argv[])
44 :
45 steadyNS(argc, argv)
46{
47 Info << offline << endl;
49 NUmodesOut = para->ITHACAdict->lookupOrDefault<label>("NmodesUout", 15);
51 NPmodesOut = para->ITHACAdict->lookupOrDefault<label>("NmodesPout", 15);
53 NNutModesOut = para->ITHACAdict->lookupOrDefault<label>("NmodesNutOut", 15);
55 NUmodes = para->ITHACAdict->lookupOrDefault<label>("NmodesUproj", 10);
57 NPmodes = para->ITHACAdict->lookupOrDefault<label>("NmodesPproj", 10);
59 NNutModes = para->ITHACAdict->lookupOrDefault<label>("NmodesNutProj", 0);
60}
61
62void SteadyNSSimple::getTurbRBF(label NNutModes)
63{
64 if (NNutModes == 0)
65 {
66 NNutModes = nutModes.size();
67 }
68
70 samples.resize(NNutModes);
71 rbfSplines.resize(NNutModes);
72 Eigen::MatrixXd weights;
73
74 for (label i = 0; i < NNutModes; i++) // i is the nnumber of th mode
75 {
76 word weightName = "wRBF_M" + name(i + 1);
77
78 if (ITHACAutilities::check_file("./ITHACAoutput/weights/" + weightName))
79 {
80 samples[i] = new SPLINTER::DataTable(1, 1);
81
82 for (label j = 0; j < coeffL2.cols();
83 j++) // j is the number of the nut snapshot
84 {
85 samples[i]->addSample(mu.row(j), coeffL2(i, j));
86 }
87
88 ITHACAstream::ReadDenseMatrix(weights, "./ITHACAoutput/weights/", weightName);
89 rbfSplines[i] = new SPLINTER::RBFSpline(*samples[i],
90 SPLINTER::RadialBasisFunctionType::GAUSSIAN, weights);
91 // std::cout << "Constructing RadialBasisFunction for mode " << i + 1 << std::endl;
92 Info<< "Constructing RadialBasisFunction for mode " << i + 1 << endl;
93 }
94 else
95 {
96 samples[i] = new SPLINTER::DataTable(1, 1);
97
98 for (label j = 0; j < coeffL2.cols();
99 j++) // j is the number of the nut snapshot
100 {
101 samples[i]->addSample(mu.row(j), coeffL2(i, j));
102 }
103
104 rbfSplines[i] = new SPLINTER::RBFSpline(*samples[i],
105 SPLINTER::RadialBasisFunctionType::GAUSSIAN);
107 "./ITHACAoutput/weights/", weightName);
108 // std::cout << "Constructing RadialBasisFunction for mode " << i + 1 << std::endl;
109 Info<< "Constructing RadialBasisFunction for mode " << i + 1 << endl;
110 }
111 }
112}
113
114void SteadyNSSimple::truthSolve2(List<scalar> mu_now, word Folder)
115{
116 Time& runTime = _runTime();
117 volScalarField& p = _p();
118 volVectorField& U = _U();
119 fvMesh& mesh = _mesh();
120 surfaceScalarField& phi = _phi();
121 simpleControl& simple = _simple();
122 singlePhaseTransportModel& laminarTransport = _laminarTransport();
123 scalar residual = 1;
124 scalar uresidual = 1;
125 Vector<double> uresidual_v(0, 0, 0);
126 scalar presidual = 1;
127 scalar csolve = 0;
128 turbulence->read();
129 std::ofstream res_os;
130 std::ofstream snaps_os;
131 std::ofstream iters;
132 std::ofstream res_U;
133 std::ofstream res_P;
134 res_os.open(Folder + "/residuals", std::ios_base::app);
135 snaps_os.open(Folder + "/snaps", std::ios_base::app);
136 iters.open(Folder + "/iters", std::ios_base::app);
137 res_U.open(Folder + name(counter) + "/res_U", std::ios_base::app);
138 res_P.open(Folder + name(counter) + "/res_P", std::ios_base::app);
139 folderN = 0;
140 saver = 0;
141 middleStep = para->ITHACAdict->lookupOrDefault<label>("middleStep", 20);
142 middleExport = para->ITHACAdict->lookupOrDefault<bool>("middleExport", true);
143#if defined(OFVER) && (OFVER == 6)
144
145 while (simple.loop(runTime) && residual > tolerance && csolve < maxIter )
146#else
147 while (simple.loop() && residual > tolerance && csolve < maxIter )
148#endif
149 {
150 csolve++;
151 saver++;
152 Info << "Time = " << runTime.timeName() << nl << endl;
153 volScalarField nueff = turbulence->nuEff().ref();
154 fvVectorMatrix UEqn
155 (
156 fvm::div(phi, U)
157 - fvm::laplacian(nueff, U)
158 - fvc::div(nueff * dev2(T(fvc::grad(U))))
159 );
160 UEqn.relax();
161
162 if (simple.momentumPredictor())
163 {
164 uresidual_v = solve(UEqn == - fvc::grad(p)).initialResidual();
165 }
166
167 volVectorField U2(U);
168 scalar C = 0;
169
170 for (label i = 0; i < 3; i++)
171 {
172 if (C < uresidual_v[i])
173 {
174 C = uresidual_v[i];
175 }
176 }
177
178 uresidual = C;
179 volScalarField rAU(1.0 / UEqn.A());
180 volVectorField HbyA(constrainHbyA(1.0 / UEqn.A() * UEqn.H(), U, p));
181 surfaceScalarField phiHbyA("phiHbyA", fvc::flux(HbyA));
182 adjustPhi(phiHbyA, U, p);
183 tmp<volScalarField> rAtU(rAU);
184
185 if (simple.consistent())
186 {
187 rAtU = 1.0 / (1.0 / rAU - UEqn.H1());
188 phiHbyA +=
189 fvc::interpolate(rAtU() - rAU) * fvc::snGrad(p) * mesh.magSf();
190 HbyA -= (rAU - rAtU()) * fvc::grad(p);
191 }
192
193 label i = 0;
194
195 while (simple.correctNonOrthogonal())
196 {
197 fvScalarMatrix pEqn
198 (
199 fvm::laplacian(rAtU(), p) == fvc::div(phiHbyA)
200 );
201 pEqn.setReference(pRefCell, pRefValue);
202
203 if (i == 0)
204 {
205 presidual = pEqn.solve().initialResidual();
206 }
207 else
208 {
209 pEqn.solve().initialResidual();
210 }
211
212 if (simple.finalNonOrthogonalIter())
213 {
214 phi = phiHbyA - pEqn.flux();
215 }
216
217 i++;
218 }
219
220#include "continuityErrs.H"
221 p.relax();
222 // Momentum corrector
223 U = HbyA - rAtU() * fvc::grad(p);
224 U.correctBoundaryConditions();
226 Info << "Time = " << runTime.timeName() << nl << endl;
227 laminarTransport.correct();
228 turbulence->correct();
229
230 if (saver == middleStep && middleExport)
231 {
232 saver = 0;
233 folderN++;
234 // if (folderN % 2 == 0)
235 // {
236 ITHACAstream::exportSolution(U, name(folderN), Folder + name(counter));
237 // }
238 // else
239 // {
240 // ITHACAstream::exportSolution(U2, name(folderN), Folder + name(counter));
241 // }
242 ITHACAstream::exportSolution(p, name(folderN), Folder + name(counter));
243 Ufield.append(U.clone());
244 Pfield.append(p.clone());
245 res_U << uresidual << std::endl;
246 res_P << presidual << std::endl;
247
249 {
250 auto nut = mesh.lookupObject<volScalarField>("nut");
251 ITHACAstream::exportSolution(nut, name(folderN), Folder + name(counter));
252 nutFields.append(nut.clone());
253 }
254 }
255 }
256
257 snaps_os << folderN + 1 << std::endl;
258 iters << csolve << std::endl;
259 res_os << residual << std::endl;
260 res_os.close();
261 res_U.close();
262 res_P.close();
263 snaps_os.close();
264 iters.close();
265 runTime.setTime(runTime.startTime(), 0);
266
267 if (middleExport)
268 {
269 ITHACAstream::exportSolution(U, name(folderN + 1), Folder + name(counter));
270 ITHACAstream::exportSolution(p, name(folderN + 1), Folder + name(counter));
271 }
272 else
273 {
274 ITHACAstream::exportSolution(U, name(counter), Folder);
275 ITHACAstream::exportSolution(p, name(counter), Folder);
276 }
277
279 {
280 auto nut = mesh.lookupObject<volScalarField>("nut");
281 ITHACAstream::exportSolution(nut, name(folderN + 1), Folder + name(counter));
282 nutFields.append(nut.clone());
283 }
284
285 Ufield.append(U.clone());
286 Pfield.append(p.clone());
287 counter++;
288 writeMu(mu_now);
289 // --- Fill in the mu_samples with parameters (mu) to be used for the POD sample points
290 mu_samples.conservativeResize(mu_samples.rows() + 1, mu_now.size());
291
292 for (label i = 0; i < mu_now.size(); i++)
293 {
294 mu_samples(mu_samples.rows() - 1, i) = mu_now[i];
295 }
296
297 // Resize to Unitary if not initialized by user (i.e. non-parametric problem)
298 if (mu.cols() == 0)
299 {
300 mu.resize(1, 1);
301 }
302
303 if (mu_samples.rows() == mu.cols())
304 {
305 ITHACAstream::exportMatrix(mu_samples, "mu_samples", "eigen",
306 Folder);
307 }
308}
fvScalarMatrix pEqn
Definition CFM.H:31
Foam::fvMesh & mesh
Definition createMesh.H:47
Foam::Time & runTime
Definition createTime.H:33
scalar csolve
std::ofstream res_os
Vector< double > uresidual_v(0, 0, 0)
scalar uresidual
scalar presidual
scalar residual
Header file of the steadyNS class.
TEqn solve()
IOdictionary * ITHACAdict
Dictionary for input objects from file.
std::vector< SPLINTER::DataTable * > samples
Create a samples for interpolation.
std::vector< SPLINTER::RBFSpline * > rbfSplines
Create a RBF splines for interpolation.
SteadyNSSimple()
Null constructor.
label folderN
Counter to save intermediate steps in the correct folder (for turbulent case only)
void getTurbRBF(label NNutModes)
Function to calculate RBF weights for turbulence.
void truthSolve2(List< scalar > mu_now, word Folder="./ITHACAoutput/Offline/")
Offline solver for the whole Navier-Stokes problem.
volScalarModes nutModes
List of POD modes for eddy viscosity.
bool middleExport
Export also intermediate fields.
Eigen::MatrixXd coeffL2
The matrix of L2 projection coefficients for the eddy viscosity.
label saver
Counter to check if the middleStep has been reached or not (for turbulent case only)
label middleStep
Distancing between intermediate steps (for turbulent case only)
PtrList< volScalarField > nutFields
List of snapshots for the solution for eddy viscosity.
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.
bool offline
Boolean variable, it is 1 if the Offline phase has already been computed, else 0.
Eigen::MatrixXd mu
Row matrix of parameters.
Implementation of a parametrized full order steady NS problem and preparation of the the reduced ma...
Definition steadyNS.H:70
scalar maxIter
Number of maximum iterations to be done for the computation of the truth solution.
Definition steadyNS.H:125
label NPmodes
Number of pressure modes used for the projection.
Definition steadyNS.H:143
autoPtr< surfaceScalarField > _phi
Flux.
Definition steadyNS.H:293
autoPtr< simpleControl > _simple
simpleControl
Definition steadyNS.H:284
PtrList< volScalarField > Pfield
List of pointers used to form the pressure snapshots matrix.
Definition steadyNS.H:86
autoPtr< Time > _runTime
Time.
Definition steadyNS.H:290
PtrList< volVectorField > Ufield
List of pointers used to form the velocity snapshots matrix.
Definition steadyNS.H:89
scalar tolerance
Tolerance for the residual of the stationary problems, there is the same tolerance for velocity and p...
Definition steadyNS.H:122
autoPtr< fvMesh > _mesh
Mesh.
Definition steadyNS.H:281
autoPtr< singlePhaseTransportModel > _laminarTransport
Laminar transport (used by turbulence model)
Definition steadyNS.H:302
label NUmodes
Number of velocity modes used for the projection.
Definition steadyNS.H:140
scalar pRefValue
Reference pressure value.
Definition steadyNS.H:311
label pRefCell
Reference pressure cell.
Definition steadyNS.H:308
ITHACAparameters * para
Definition steadyNS.H:82
label NNutModesOut
Number of nut modes to be calculated.
Definition steadyNS.H:137
label NNutModes
Number of nut modes used for the projection.
Definition steadyNS.H:149
autoPtr< incompressible::turbulenceModel > turbulence
Turbulence model.
Definition steadyNS.H:299
label NUmodesOut
Number of velocity modes to be calculated.
Definition steadyNS.H:128
label NPmodesOut
Number of pressure modes to be calculated.
Definition steadyNS.H:131
autoPtr< volVectorField > _U
Velocity field.
Definition steadyNS.H:263
autoPtr< volScalarField > _p
Pressure field.
Definition steadyNS.H:260
volScalarField & T
Definition createT.H:46
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.
Eigen::VectorXd getCoeffs(GeometricField< Type, PatchField, GeoMesh > &snapshot, PtrList< GeometricField< Type, PatchField, GeoMesh > > &modes, label Nmodes, bool consider_volumes)
Projects a snapshot on a basis function and gets the coefficients of the projection.
bool isTurbulent()
This function checks if the case is turbulent.
bool check_file(std::string fileName)
Function that returns true if a file exists.
simpleControl simple(mesh)
surfaceScalarField & phi
volVectorField & U
volScalarField & nut
fvVectorMatrix & UEqn
Definition UEqn.H:37
volScalarField & p
singlePhaseTransportModel & laminarTransport
adjustPhi(phiHbyA, U, p)
tmp< volScalarField > rAtU(rAU)
surfaceScalarField phiHbyA("phiHbyA", fvc::flux(HbyA))
volVectorField HbyA(constrainHbyA(rAU *UEqn.H(), U, p))
label i
Definition pEqn.H:46
volScalarField rAU(1.0/UEqn.A())