Loading...
Searching...
No Matches
inverseLaplacianProblem.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
33
34
36
37// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * //
38
39// Constructors
41
43 :
44 DT("DT", dimensionSet(1, 1, -3, -1, 0, 0, 0), 1.0)
45{
46 _args = autoPtr<argList>
47 (
48 new argList(argc, argv)
49 );
50
51 if (!_args->checkRootCase())
52 {
53 Foam::FatalError.exit();
54 }
55
56 argList& args = _args();
57#include "createTime.H"
58#include "createMesh.H"
59 _simple = autoPtr<simpleControl>
60 (
61 new simpleControl
62 (
63 mesh
64 )
65 );
66 simpleControl& simple = _simple();
67#include "createFields.H"
68#include "createThermocouples.H"
70#include "createFvOptions.H"
71 ITHACAdict = new IOdictionary
72 (
73 IOobject
74 (
75 "ITHACAdict",
76 runTime.system(),
77 mesh,
78 IOobject::MUST_READ,
79 IOobject::NO_WRITE
80 )
81 );
85 nProcs = Pstream::nProcs();
86}
87
88// * * * * * * * * * * * * * * Full Order Methods * * * * * * * * * * * * * * //
89
91{
92 volScalarField& T = _T();
93 g.resize(T.boundaryField()[hotSide_ind].size(), 0.0);
94 forAll (T.boundaryField()[hotSide_ind], faceI)
95 {
96 g[faceI] = 0.0;
97 }
98}
99
100volScalarField inverseLaplacianProblem::list2Field(List<scalar> list,
101 scalar innerField)
102{
103 volScalarField& T = _T();
104 fvMesh& mesh = _mesh();
105 volScalarField field(T);
106 ITHACAutilities::assignIF(field, innerField);
107 //Access the mesh information for the boundary
108 const polyPatch& cPatch = mesh.boundaryMesh()[hotSide_ind];
109 //List of cells close to a boundary
110 const labelUList& faceCells = cPatch.faceCells();
111 M_Assert(faceCells.size() == list.size(), "Inpust list has the wrong size.");
112 forAll(cPatch, faceI)
113 {
114 //id of the owner cell having the face
115 label faceOwner = faceCells[faceI] ;
116 field[faceOwner] = list[faceI];
117 }
118
119 return field;
120}
121
123{
124 fvMesh& mesh = _mesh();
125 valueFraction.resize(mesh.boundaryMesh()["coldSide"].size());
126 homogeneousBCcoldSide.resize(mesh.boundaryMesh()["coldSide"].size());
127 coldSide_ind = mesh.boundaryMesh().findPatchID("coldSide");
128 Eigen::VectorXd faceCellDist =
130 forAll (valueFraction, faceI)
131 {
132 scalar faceDist = faceCellDist(faceI);
133 valueFraction[faceI] = 1.0 / (1.0 + (k / H / faceDist));
134 homogeneousBCcoldSide[faceI] = 0;
135 }
136
138}
139
140
142{
143 fvMesh& mesh = _mesh();
144 volScalarField& T = _T();
146 forAll(mesh.boundaryMesh(), patchI)
147 {
148 if (patchI == mesh.boundaryMesh().findPatchID("coldSide"))
149 {
151 }
152 else if (patchI == mesh.boundaryMesh().findPatchID("hotSide"))
153 {
154 ITHACAutilities::assignBC(T, patchI, - g / k);
155 }
156 else
157 {
159 }
160 }
161}
162
164{
165 restart();
167 solve("direct");
168}
169
170void inverseLaplacianProblem::solve(const char* problemID)
171{
172 volScalarField& T = _T();
173 simpleControl& simple = _simple();
174 Foam::Time& runTime = _runTime();
175
176 if (strcmp( problemID, "direct") == 0)
177 {
179 }
180 else
181 {
182 Info << "Problem name should be direct or sensitivity" << endl;
183 exit(10);
184 }
185
186#if defined(OFVER) && (OFVER == 6)
187
188 while (simple.loop(runTime))
189#else
190 while (simple.loop())
191#endif
192 {
193 while (simple.correctNonOrthogonal())
194 {
195 if (strcmp( problemID, "direct") == 0)
196 {
197 fvScalarMatrix TEqn
198 (
199 fvm::laplacian(DT, T)
200 );
201 TEqn.solve();
202 }
203 }
204 }
205}
206
208{
210 {
211 word fileName = "./thermocouplesCellsID";
212
213 if (ITHACAutilities::check_file(fileName + "_mat.txt"))
214 {
215 Info << "Reading thermocouples cells from file" << endl;
216 Eigen::MatrixXi TCmatrix = ITHACAstream::readMatrix(fileName + "_mat.txt").cast
217 <int> ();
219 }
220 else
221 {
222 Info << "Defining positions of thermocouples" << endl;
223 fvMesh& mesh = _mesh();
224 volScalarField& T = _T();
227 {
228 thermocouplesCellID[tcI] = mesh.findCell(thermocouplesPos[tcI]);
229 }
230
231 volScalarField thermocouplesField(T);
232 ITHACAutilities::assignIF(thermocouplesField, homogeneousBC);
234 {
235 thermocouplesField.ref()[thermocouplesCellID[tcI]] = 1;
236 }
237
238 ITHACAstream::exportSolution(thermocouplesField, "1", "./ITHACAoutput/debug/",
239 "thermocouplesField,");
240 Eigen::MatrixXi thermocouplesCellID_eigen = Foam2Eigen::List2EigenMatrix(
242 ITHACAstream::exportMatrix(thermocouplesCellID_eigen, fileName,
243 "eigen", "./");
244 }
245
248 }
249 else
250 {
251 WarningInFunction << "readThermocouples function called twice." << endl;
252 WarningInFunction << "I am not doing the second reading." << endl;
253 }
254}
255
257 volScalarField& field)
258{
260 {
262 }
263
264 fvMesh& mesh = _mesh();
265 dictionary interpolationDict =
266 mesh.solutionDict().subDict("interpolationSchemes");
267 autoPtr<Foam::interpolation<scalar >> fieldInterp =
268 Foam::interpolation<scalar>::New(interpolationDict, field);
269 Eigen::VectorXd fieldInt;
270 fieldInt.resize(thermocouplesPos.size());
272 {
273 fieldInt(tcI) = fieldInterp->interpolate(thermocouplesPos[tcI],
275 }
276
277 return fieldInt;
278}
279
286
287
288Foam::vector inverseLaplacianProblem::cellDim(const faceList& ff,
289 const pointField& pp,
290 const cell& cc, labelList pLabels, pointField pLocal)
291{
292 forAll (pLabels, pointi)
293 pLocal[pointi] = pp[pLabels[pointi]];
294 double xDim = Foam::max(pLocal & Foam::vector(1, 0, 0))
295 - Foam::min(pLocal & Foam::vector(1, 0, 0));
296 double yDim = Foam::max(pLocal & Foam::vector(0, 1, 0))
297 - Foam::min(pLocal & Foam::vector(0, 1, 0));
298 double zDim = Foam::max(pLocal & Foam::vector(0, 0, 1))
299 - Foam::min(pLocal & Foam::vector(0, 0, 1));
300 Foam::vector dim (xDim, yDim, zDim);
301 return dim;
302}
303
304
306{
307 _simple.clear();
308 _T.clear();
309 argList& args = _args();
310 Time& runTime = _runTime();
311 //Reinitializing runTime
312 instantList Times = runTime.times();
313 runTime.setTime(Times[1], 1);
314 Foam::fvMesh& mesh = _mesh();
315 _simple = autoPtr<simpleControl>
316 (
317 new simpleControl
318 (
319 mesh
320 )
321 );
322 _T = autoPtr<volScalarField>
323 (
324 new volScalarField
325 (
326 IOobject
327 (
328 "T",
329 runTime.timeName(),
330 mesh,
331 IOobject::MUST_READ,
332 IOobject::AUTO_WRITE
333 ),
334 mesh
335 )
336 );
337 Info << "Ready for new computation" << endl;
338}
339
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)
TEqn solve()
static Eigen::Matrix< type_matrix, Eigen::Dynamic, Eigen::Dynamic > List2EigenMatrix(List< type_matrix > list)
Convert a Foam List into an Eigen matrix with one column.
static List< type_matrix > EigenMatrix2List(Eigen::Matrix< type_matrix, Eigen::Dynamic, Eigen::Dynamic > matrix)
Convert an Eigen matrix with one column into a Foam List.
static ITHACAparameters * getInstance()
Gets an instance of ITHACAparameters, to be used if the instance is already existing.
Eigen::VectorXd Tdiff
Difference between computed and measured temperatures at the thermocouples.
label hotSide_ind
Index of the hotSide patch.
dimensionedScalar DT
Dummy thermal conductivity with unitary value.
List< vector > thermocouplesPos
List containing the positions of the thermocouples.
double H
Heat transfer coefficient [W/(m2 K)].
List< scalar > Tf
Temperature at coldSide [K].
autoPtr< simpleControl > _simple
simpleControl
List< scalar > g
Heat flux at hotSide [W/m2].
bool thermocouplesRead
Flag to know if thermocouples file was read.
Eigen::VectorXd Tdirect
Vector of computed temperatures at the thermocouples locations [K].
List< scalar > homogeneousBCcoldSide
List of zeros of the size of coldSide patch.
List< scalar > valueFraction
Value fraction for the Robin BC.
scalar homogeneousBC
Homogenerous BC.
volScalarField list2Field(List< scalar > list, scalar innerField=0.0)
Create a field with the hotSide boundary heat flux at the hotSide bounday cells for visualization.
Eigen::VectorXd Tmeas
Vector of measured temperatures at the thermocouples locations [K].
virtual void assignDirectBC()
Set boundary condition of the direct problem.
void set_valueFraction()
Set valueFraction list values for Robin condition.
Foam::vector cellDim(const faceList &ff, const pointField &pp, const cell &cc, labelList pLabels, pointField pLocal)
Compute maximum cell dimension in x, y and z.
void set_g()
Set the right g size and fills it with zeros.
label coldSide_ind
Index of the coldSide patch.
autoPtr< fvMesh > _mesh
Mesh.
Eigen::VectorXd fieldValueAtThermocouples(volScalarField &field)
Interpolates the field value at the thermocouples points.
List< scalar > refGrad
Reference gradient for the Robin BC.
void solve(const char *problem)
Solve Laplacian problem without source term.
virtual void readThermocouples()
Identifies in the mesh the cells corresponding to the termocouples locations.
inverseLaplacianProblem()
Null constructor.
void differenceBetweenDirectAndMeasure()
Computes the difference between direct problem solution and measures Saves the difference vector in T...
int thermocouplesNum
Number of thermocouples.
double k
Thermal diffusivity [W/(m K)].
void solveDirect()
Solve direct problem.
label nProcs
Number of processors.
autoPtr< volScalarField > _T
Temperature field.
List< int > thermocouplesCellID
List of cells indices containing a thermocouple.
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
autoPtr< argList > _args
argList
bool podex
Boolean variable, it is 1 if the POD has already been computed, else 0.
volScalarField & T
Definition createT.H:46
List< vector > TCpos(thermocouplesPosition.lookup("positions"))
Header file of the inverseLaplacianProblem class.
fvScalarMatrix & TEqn
Definition TEqn.H:15
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 ...
List< Eigen::MatrixXd > readMatrix(word folder, word mat_name)
Read a three dimensional matrix from a txt file in Eigen format.
void assignMixedBC(GeometricField< Type, fvPatchField, volMesh > &field, label BC_ind, List< Type > &value, List< Type > &grad, List< scalar > &valueFrac)
Assign value of a boundary condition of type "mixed".
void assignIF(GeometricField< Type, fvPatchField, volMesh > &s, Type value)
Assign internal field.
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 assignBC(GeometricField< scalar, fvPatchField, volMesh > &s, label BC_ind, double value)
Assign uniform Boundary Condition to a volScalarField.
bool check_file(std::string fileName)
Function that returns true if a file exists.
Eigen::VectorXd boudaryFaceToCellDistance(fvMesh &mesh, label BC_ind)
Compute the distance between the boundary face center and the boundary cell center.
simpleControl simple(mesh)