Loading...
Searching...
No Matches
ReducedSteadyNSTurbIntrusive.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
32
33// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * //
34
35// Constructor
39
41 SteadyNSTurbIntrusive& fomProblem)
42 :
43 problem(&fomProblem)
44{
45 N_BC = problem->inletIndex.rows();
46 Nphi_u = problem->bMatrix.rows();
47
48 for (int k = 0; k < Nphi_u; k++)
49 {
50 Umodes.append((problem->Umodes[k]).clone());
51 }
52
54 fomProblem);
55}
56
57int newtonSteadyNSTurbIntrusive::operator()(const Eigen::VectorXd& x,
58 Eigen::VectorXd& fvec) const
59{
60 Eigen::VectorXd aTmp(Nphi_u);
61 aTmp = x;
62 // Convective term
63 Eigen::MatrixXd cc(1, 1);
64 // Mom Term
65 Eigen::VectorXd m1 = problem->bTotalMatrix * aTmp * nu;
66 // Gradient of pressure
67 Eigen::VectorXd m2 = problem->kMatrix * aTmp;
68 // Penalty term
69 Eigen::MatrixXd penaltyU = Eigen::MatrixXd::Zero(Nphi_u, N_BC);
70
71 // Term for penalty method
72 if (problem->bcMethod == "penalty")
73 {
74 for (int l = 0; l < N_BC; l++)
75 {
76 penaltyU.col(l) = bc(l) * problem->bcVelVec[l] - problem->bcVelMat[l] *
77 aTmp;
78 }
79 }
80
81 for (int i = 0; i < Nphi_u; i++)
82 {
83 cc = aTmp.transpose() * Eigen::SliceFromTensor(problem->cTotalTensor, 0,
84 i) * aTmp;
85 fvec(i) = m1(i) - cc(0, 0) - m2(i);
86
87 if (problem->bcMethod == "penalty")
88 {
89 fvec(i) += ((penaltyU * tauU)(i, 0));
90 }
91 }
92
93 if (problem->bcMethod == "lift")
94 {
95 for (int j = 0; j < N_BC; j++)
96 {
97 fvec(j) = x(j) - bc(j);
98 }
99 }
100
101 return 0;
102}
103
104int newtonSteadyNSTurbIntrusive::df(const Eigen::VectorXd& x,
105 Eigen::MatrixXd& fjac) const
106{
107 Eigen::NumericalDiff<newtonSteadyNSTurbIntrusive> numDiff(*this);
108 numDiff.df(x, fjac);
109 return 0;
110}
111
112
113// * * * * * * * * * * * * * * * Solve Functions * * * * * * * * * * * * * //
114
115
117{
118 if (problem->bcMethod == "lift")
119 {
121 }
122 else if (problem->bcMethod == "penalty")
123 {
124 vel_now = vel;
125 }
126
127 y.resize(Nphi_u, 1);
128 y.setZero();
129
130 // Change initial condition for the lifting function
131 if (problem->bcMethod == "lift")
132 {
133 for (int j = 0; j < N_BC; j++)
134 {
135 y(j) = vel_now(j, 0);
136 }
137 }
138
142 Eigen::HybridNonLinearSolver<newtonSteadyNSTurbIntrusive> hnls(newtonObject);
143 newtonObject.bc.resize(N_BC);
145
146 for (int j = 0; j < N_BC; j++)
147 {
148 newtonObject.bc(j) = vel_now(j, 0);
149 }
150
152 hnls.solve(y);
153 Eigen::VectorXd res(y);
154 newtonObject.operator()(y, res);
155 std::cout << "################## Online solve N° " << count_online_solve <<
156 " ##################" << std::endl;
157 std::cout << "Solving for the parameter: " << vel_now << std::endl;
158
159 if (res.norm() < 1e-5)
160 {
161 std::cout << green << "|F(x)| = " << res.norm() << " - Minimun reached in " <<
162 hnls.iter << " iterations " << def << std::endl << std::endl;
163 }
164 else
165 {
166 std::cout << red << "|F(x)| = " << res.norm() << " - Minimun reached in " <<
167 hnls.iter << " iterations " << def << std::endl << std::endl;
168 }
169
171}
172
173
175 int printEvery)
176{
177 mkDir(folder);
179 int counter = 0;
180 int nextWrite = 0;
181
182 for (int i = 0; i < online_solution.size(); i++)
183 {
184 if (counter == nextWrite)
185 {
186 volVectorField uRec("uRec", Umodes[0] * 0);
187 volScalarField pRec("pRec", problem->Pmodes[0] * 0);
188 volScalarField nutTemp("nutTemp", problem->nutModes[0] * 0);
189
190 for (int j = 0; j < Nphi_u; j++)
191 {
192 uRec += Umodes[j] * online_solution[i](j + 1, 0);
193 pRec += problem->Pmodes[j] * online_solution[i](j + 1, 0);
194 nutTemp += problem->nutModes[j] * online_solution[i](j + 1, 0);
195 }
196
197 ITHACAstream::exportSolution(uRec, name(online_solution[i](0, 0)), folder);
198 ITHACAstream::exportSolution(pRec, name(online_solution[i](0, 0)), folder);
199 nextWrite += printEvery;
200 UREC.append(uRec.clone());
201 PREC.append(pRec.clone());
202 nutRec.append(nutTemp.clone());
203 }
204
205 counter++;
206 }
207}
208
210 Eigen::MatrixXd vel)
211{
212 assert(problem->inletIndex.rows() == vel.rows()
213 && "Imposed boundary conditions dimensions do not match given values matrix dimensions");
214 Eigen::MatrixXd vel_scal;
215 vel_scal.resize(vel.rows(), vel.cols());
216
217 for (int k = 0; k < problem->inletIndex.rows(); k++)
218 {
219 int p = problem->inletIndex(k, 0);
220 int l = problem->inletIndex(k, 1);
221 scalar area = gSum(problem->liftfield[0].mesh().magSf().boundaryField()[p]);
222 scalar u_lf = gSum(problem->liftfield[k].mesh().magSf().boundaryField()[p] *
223 problem->liftfield[k].boundaryField()[p]).component(l) / area;
224 vel_scal(k, 0) = vel(k, 0) / u_lf;
225 }
226
227 return vel_scal;
228}
229
231 SteadyNSTurbIntrusive& problem,
232 fileName folder)
233{
234 mkDir(folder);
235 system("ln -s ../../constant " + folder + "/constant");
236 system("ln -s ../../0 " + folder + "/0");
237 system("ln -s ../../system " + folder + "/system");
238 Eigen::VectorXd cl(online_solution.size());
239 Eigen::VectorXd cd(online_solution.size());
240 //Read FORCESdict
241 IOdictionary FORCESdict
242 (
243 IOobject
244 (
245 "FORCESdict",
246 "./system",
247 Umodes[0].mesh(),
248 IOobject::MUST_READ,
249 IOobject::NO_WRITE
250 )
251 );
252 fTau.setZero(online_solution.size(), 3);
253 fN.setZero(online_solution.size(), 3);
254
255 for (int i = 0; i < online_solution.size(); i++)
256 {
257 for (int j = 0; j < Nphi_u; j++)
258 {
259 fTau.row(i) += problem.tauMatrix.row(j) * online_solution[i](j + 1, 0);
260 }
261
262 for (int j = 0; j < Nphi_u; j++)
263 {
264 fN.row(i) += problem.nMatrix.row(j) * online_solution[i](j + 1, 0);
265 }
266 }
267
268 // Export the matrices
269 if (para->exportPython)
270 {
271 ITHACAstream::exportMatrix(fTau, "fTau", "python", folder);
272 ITHACAstream::exportMatrix(fN, "fN", "python", folder);
273 }
274
275 if (para->exportMatlab)
276 {
277 ITHACAstream::exportMatrix(fTau, "fTau", "matlab", folder);
278 ITHACAstream::exportMatrix(fN, "fN", "matlab", folder);
279 }
280
281 if (para->exportTxt)
282 {
283 ITHACAstream::exportMatrix(fTau, "fTau", "eigen", folder);
284 ITHACAstream::exportMatrix(fN, "fN", "eigen", folder);
285 }
286}
287// ************************************************************************* //
288
289
290// ************************************************************************* //
291
Foam::fvMesh & mesh
Definition createMesh.H:47
Header file of the ReducedSteadyNSTurbIntrusive class.
Class to change color to the output stream.
Definition colormod.H:24
PtrList< volScalarField > nutRec
Reconstructed eddy viscosity field.
void reconstructLiftAndDrag(SteadyNSTurbIntrusive &problem, fileName folder)
Method to compute the reduced order forces for same number of modes of velocity and pressure.
Eigen::MatrixXd setOnlineVelocity(Eigen::MatrixXd vel)
Sets the online velocity.
newtonSteadyNSTurbIntrusive newtonObject
Newton Object to solve the nonlinear problem.
SteadyNSTurbIntrusive * problem
Pointer to the FOM problem.
void reconstruct(fileName folder="./ITHACAOutput/online_rec", int printEvery=1)
Method to reconstruct the solutions from an online solve with a supremizer stabilisation technique.
Implementation of a parametrized full order steady turbulent Navier Stokes problem and preparation ...
Eigen::MatrixXd bTotalMatrix
Total B Matrix.
PtrList< volScalarField > nutModes
List of POD modes for eddy viscosity.
Eigen::Tensor< double, 3 > cTotalTensor
Total Turbulent tensor.
Eigen::MatrixXd kMatrix
Pressure Gradient matrix.
Eigen::MatrixXd bMatrix
Diffusive matrix.
virtual void solveOnline()
Virtual Method to perform and online Solve.
PtrList< volScalarField > PREC
Reconstructed pressure field.
Eigen::VectorXd y
Vector to store the solution during the Newton procedure.
ITHACAparameters * para
parameters to be read from the ITHACAdict file
Eigen::MatrixXd fTau
Reduced matrix for tangent forces.
List< Eigen::MatrixXd > online_solution
List of Eigen matrices to store the online solution.
scalar nu
Reduced viscosity in case of parametrized viscosity.
Eigen::MatrixXd tauU
Penalty Factor.
int count_online_solve
Counter to count the online solutions.
Eigen::MatrixXd vel_now
Online inlet velocity vector.
Eigen::MatrixXd fN
Reduced matrix for normal forces.
PtrList< volVectorField > Umodes
List of pointers to store the modes for velocity.
int N_BC
Number of parametrized boundary conditions.
PtrList< volVectorField > UREC
Recontructed velocity field.
int Nphi_u
Number of velocity modes.
Eigen::MatrixXi inletIndex
Matrix that contains informations about the inlet boundaries.
List< Eigen::MatrixXd > bcVelVec
Boundary term for penalty method - vector.
Definition steadyNS.H:218
Eigen::MatrixXd nMatrix
Pressure forces.
Definition steadyNS.H:215
Eigen::MatrixXd tauMatrix
Viscous forces.
Definition steadyNS.H:212
volVectorModes Umodes
List of pointers used to form the velocity modes.
Definition steadyNS.H:101
PtrList< volVectorField > liftfield
List of pointers used to form the list of lifting functions.
Definition steadyNS.H:110
List< Eigen::MatrixXd > bcVelMat
Boundary term for penalty method - matrix.
Definition steadyNS.H:221
volScalarModes Pmodes
List of pointers used to form the pressure modes.
Definition steadyNS.H:98
word bcMethod
Boundary Method.
Definition steadyNS.H:317
@ FG_GREEN
Definition colormod.H:14
@ FG_DEFAULT
Definition colormod.H:16
@ FG_RED
Definition colormod.H:13
Matrix< VectorType, Dynamic, Dynamic > SliceFromTensor(Eigen::Tensor< VectorType, 3 > &tensor, label dim, label index1)
void 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 createSymLink(word folder)
Creates symbolic links to 0, system and constant.
volScalarField & p
label i
Definition pEqn.H:46
Structure to implement a newton object for a stationary NS problem.
int operator()(const Eigen::VectorXd &x, Eigen::VectorXd &fvec) const
int df(const Eigen::VectorXd &x, Eigen::MatrixXd &fjac) const