Loading...
Searching...
No Matches
inverseLaplacianProblem_CG.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 :
45{
46 Foam::Time& runTime = _runTime();
47 Foam::fvMesh& mesh = _mesh();
48#include "createFields.H"
49}
50
51// * * * * * * * * * * * * * * Full Order Methods * * * * * * * * * * * * * * //
52
54{
55 fvMesh& mesh = _mesh();
56 valueFraction.resize(mesh.boundaryMesh()["coldSide"].size());
57 homogeneousBCcoldSide.resize(mesh.boundaryMesh()["coldSide"].size());
58 valueFractionAdj.resize(mesh.boundaryMesh()["coldSide"].size());
59 Eigen::VectorXd faceCellDist =
61 forAll (valueFraction, faceI)
62 {
63 scalar faceDist = faceCellDist(faceI);
64 valueFraction[faceI] = 1.0 / (1.0 + (k / H / faceDist));
65 valueFractionAdj[faceI] = 1 / (1 + (1 / k / H / faceDist));
66 homogeneousBCcoldSide[faceI] = 0;
67 }
68
70}
71
73{
74 fvMesh& mesh = _mesh();
75 volScalarField& lambda = _lambda();
77 forAll(mesh.boundaryMesh(), patchI)
78 {
79 if (patchI == mesh.boundaryMesh().findPatchID("coldSide"))
80 {
83 }
84 else if (patchI == mesh.boundaryMesh().findPatchID("hotSide"))
85 {
87 }
88 else
89 {
91 }
92 }
93
95}
96
98{
99 volScalarField& lambda = _lambda();
100 fvMesh& mesh = _mesh();
102 dimensionedScalar sourceDim("sourceDim", dimensionSet(1, -1, -3, -1, 0, 0, 0),
103 1);
104 autoPtr<volScalarField> f_
105 (
106 new volScalarField("f", lambda)
107 );
108 volScalarField& f = f_();
109
110 if (interpolation)
111 {
112 forAll(interpolationPlane.cellID, cellI)
113 {
114 f.ref()[interpolationPlane.cellID [cellI]] =
115 interpolationPlane.Tdiff[cellI] * k;
116 }
117 }
118 else
119 {
120 for (int i = 0; i < thermocouplesCellID.size(); i++)
121 {
122 f.ref()[thermocouplesCellID [i]] = Tdiff(i) * k /
124 }
125 }
126
127 return (f * sourceDim).ref();
128}
129
131{
132 fvMesh& mesh = _mesh();
133 volScalarField& deltaT = _deltaT();
135 forAll(mesh.boundaryMesh(), patchI)
136 {
137 if (patchI == mesh.boundaryMesh().findPatchID("coldSide"))
138 {
141 }
142 else if (patchI == mesh.boundaryMesh().findPatchID("hotSide"))
143 {
144 ITHACAutilities::assignBC(deltaT, patchI, - P / k);
145 }
146 else
147 {
149 }
150 }
151}
152
154{
155 restart();
156 volScalarField& lambda = _lambda();
157 Foam::Time& runTime = _runTime();
158 volScalarField f = assignAdjointBCandSource();
159 simpleControl& simple = _simple();
160#if defined(OFVER) && (OFVER == 6)
161
162 while (simple.loop(runTime))
163#else
164 while (simple.loop())
165#endif
166 {
167 //Info << "Time = " << runTime.timeName() << nl << endl;
168 while (simple.correctNonOrthogonal())
169 {
170 fvScalarMatrix TEqn
171 (
172 fvm::laplacian(DT, lambda) == - f
173 );
174 TEqn.solve();
175 }
176 }
177}
178
179
181{
182 restart();
184 solve("sensitivity");
185}
186
187void inverseLaplacianProblem_CG::solve(const char* problemID)
188{
189 volScalarField& T = _T();
190 volScalarField& deltaT = _deltaT();
191 simpleControl& simple = _simple();
192 Foam::Time& runTime = _runTime();
193
194 if (strcmp( problemID, "direct") == 0)
195 {
197 }
198 else if (strcmp( problemID, "sensitivity") == 0)
199 {
201 }
202 else
203 {
204 Info << "Problem name should be direct or sensitivity" << endl;
205 exit(10);
206 }
207
208#if defined(OFVER) && (OFVER == 6)
209
210 while (simple.loop(runTime))
211#else
212 while (simple.loop())
213#endif
214 {
215 while (simple.correctNonOrthogonal())
216 {
217 if (strcmp( problemID, "direct") == 0)
218 {
219 fvScalarMatrix TEqn
220 (
221 fvm::laplacian(DT, T)
222 );
223 TEqn.solve();
224 }
225 else if (strcmp( problemID, "sensitivity") == 0)
226 {
227 fvScalarMatrix TEqn
228 (
229 fvm::laplacian(DT, deltaT)
230 );
231 TEqn.solve();
232 }
233 }
234 }
235}
236
238{
239 Info << "Defining the plane for measurements interpolation" << endl;
240 fvMesh& mesh = _mesh();
241 //Define thermocouples plane
242 bool firstCell = 1;
244 {
245 if (thermocouplesCellID[cellI] != -1)
246 {
247 thermocouplesCellProc[cellI] = Pstream::myProcNo();
248
249 if (firstCell)
250 {
251 interpolationPlane.minX = mesh.C()[thermocouplesCellID[cellI]].component(0);
252 interpolationPlane.maxX = mesh.C()[thermocouplesCellID[cellI]].component(0);
253 interpolationPlane.Y = mesh.C()[thermocouplesCellID[cellI]].component(1);
254 interpolationPlane.minZ = mesh.C()[thermocouplesCellID[cellI]].component(2);
255 interpolationPlane.maxZ = mesh.C()[thermocouplesCellID[cellI]].component(2);
256 firstCell = 0;
257 }
258
259 if (mesh.C()[thermocouplesCellID[cellI]].component(0) < interpolationPlane.minX)
260 {
261 interpolationPlane.minX = mesh.C()[thermocouplesCellID[cellI]].component(0);
262 }
263
264 if (mesh.C()[thermocouplesCellID[cellI]].component(0) > interpolationPlane.maxX)
265 {
266 interpolationPlane.maxX = mesh.C()[thermocouplesCellID[cellI]].component(0) ;
267 }
268
269 if (mesh.C()[thermocouplesCellID[cellI]].component(2) < interpolationPlane.minZ)
270 {
271 interpolationPlane.minZ = mesh.C()[thermocouplesCellID[cellI]].component(2);
272 }
273
274 if (mesh.C()[thermocouplesCellID[cellI]].component(2) > interpolationPlane.maxZ)
275 {
276 interpolationPlane.maxZ = mesh.C()[thermocouplesCellID[cellI]].component(2) ;
277 }
278 }
279 else
280 {
281 Tmeas (cellI) = 0;
282 thermocouplesCellProc[cellI] = -1;
283 }
284 }
285}
286
288{
289 volScalarField& deltaT = _deltaT();
290
291 if (interpolation)
292 {
293 forAll(interpolationPlane.cellID, cellI)
294 {
295 interpolationPlane.Tsens[cellI] =
296 deltaT.internalField()[interpolationPlane.cellID [cellI]];
297 }
298 }
299 else
300 {
302 }
303}
304
306{
307 set_g();
309 cgIter = 0;
310 J = 0;
311 P = g;
312 gradJ = g; //Gradient of the cost function [W/m2]
313 gamma = 0.0;
314 gamma_den = 0.0;
315 label sampleI = 1;
316 gList.resize(0);
317 Tfield.resize(0);
318 lambdaField.resize(0);
319 deltaTfield.resize(0);
320
321 while (cgIter < cgIterMax)
322 {
323 Info << "Iteration " << cgIter + 1 << endl;
324 restart();
325 solveDirect();
326
327 if (saveSolInLists && cgIter == 0)
328 {
329 gList.append(g.clone());
330 }
331
332 volScalarField& T = _T();
333 //ITHACAstream::exportSolution(T, std::to_string(sampleI),
334 // "./ITHACAoutput/CGtest/", T.name());
336
338 {
339 Jlist.conservativeResize(cgIter + 1, 1);
340 Jlist(cgIter) = J;
341 ITHACAstream::exportMatrix(Jlist, "costFunctionFull", "eigen", "./");
342 return (1);
343 }
344
345 Jlist.conservativeResize(cgIter + 1, 1);
346 Jlist(cgIter) = J;
347 solveAdjoint();
348 volScalarField& lambda = _lambda();
349 //ITHACAstream::exportSolution(lambda, std::to_string(sampleI),
350 // "./ITHACAoutput/CGtest/", lambda.name());
351 computeGradJ();
354 volScalarField& deltaT = _deltaT();
355 //ITHACAstream::exportSolution(deltaT, std::to_string(sampleI),
356 // "./ITHACAoutput/CGtest/", deltaT.name());
360
361 if (saveSolInLists)
362 {
363 volScalarField& T = _T();
364 volScalarField& lambda = _lambda();
365 volScalarField& deltaT = _deltaT();
366 gList.append(g.clone());
367 Tfield.append(T.clone());
368 lambdaField.append(lambda.clone());
369 deltaTfield.append(deltaT.clone());
370 sampleI++;
371 }
372
373 cgIter++;
374 }
375
376 return (0);
377}
378
380{
381 fvMesh& mesh = _mesh();
382 volScalarField& lambda = _lambda();
383 gradJ_L2norm = 0;
384 forAll (lambda.boundaryField()[hotSide_ind], faceI)
385 {
386 gradJ [faceI] = - lambda.boundaryField()[hotSide_ind][faceI];
387 gradJ_L2norm += gradJ[faceI] * gradJ[faceI] *
388 mesh.magSf().boundaryField()[hotSide_ind][faceI];
389 }
390
391 gradJ_L2norm = Foam::sqrt(gradJ_L2norm);
392 Info << "gradJ L2norm = " << gradJ_L2norm << endl;
393}
394
396{
397 fvMesh& mesh = _mesh();
398 gamma = 0.0;
399 scalar gammaNum = 0;
400 gammaNum = gradJ_L2norm;
401
402 if (cgIter > 0)
403 {
404 //reduce(gamma, sumOp<double>());
405 gamma = gammaNum / gamma_den;
406 Info << "gamma = " << gamma << endl;
407 }
408
409 P = gradJ + gamma * P; //Updating P
410 gamma_den = gammaNum;
411 //reduce(gamma_den, sumOp<double>());
412}
413
415{
416 if (interpolation)
417 {
418 List<scalar> temp = interpolationPlane.Tdiff *
419 interpolationPlane.Tsens;
420 beta = 0.0;
421 forAll(interpolationPlane.cellVol, cellI)
422 {
423 beta += interpolationPlane.cellVol [cellI] * temp [cellI];
424 }
425
426 //reduce(beta, sumOp<double>());
427 temp = interpolationPlane.Tsens * interpolationPlane.Tsens;
428 scalar betaDiv = 0.0;
429 forAll(interpolationPlane.cellVol, cellI)
430 {
431 betaDiv += interpolationPlane.cellVol [cellI] * temp [cellI];
432 }
433
434 //reduce(betaDiv, sumOp<double>());
435 beta = beta / betaDiv;
436 temp.clear();
437 }
438 else
439 {
440 beta = Tdiff.dot(Tsens);
441 //reduce(beta, sumOp<double>());
442 double betaDiv = Tsens.dot(Tsens);
443 //reduce(betaDiv, sumOp<double>());
444 beta = beta / betaDiv;
445 }
446
447 Info << "beta = " << beta << endl;
448}
449
454
455
457{
458 double Jold = J;
459
460 if (interpolation)
461 {
462 List<scalar> sqTdiff;
463 sqTdiff = interpolationPlane.Tdiff * interpolationPlane.Tdiff;
464 J = 0.0;
465 forAll(sqTdiff, cellI)
466 {
467 J += 0.5 * sqTdiff[cellI] * interpolationPlane.cellVol[cellI];
468 }
469
470 sqTdiff.clear();
471 }
472 else
473 {
474 J = 0.5 * Tdiff.dot(Tdiff);
475 }
476
477 //reduce(J, sumOp<double>());
478 Info << "J = " << J << endl;
479
480 if (J <= Jtol)
481 {
482 Info << "Convergence reached in " << cgIter << " iterations" << endl;
483 return (1);
484 }
485 else if (Foam::mag((Jold - J) / J) <= JtolRel)
486 {
487 Info << "Relative tolerance criteria meet in " << cgIter << " iterations" <<
488 endl;
489 Info << "|Jold - J| / |J| = " << Foam::mag((Jold - J) / J) << endl;
490 return (1);
491 }
492 else
493 {
494 return (0);
495 }
496}
497
498
499
500int inverseLaplacianProblem_CG::isInPlane(double cx, double cy, double cz,
501 Foam::vector thermocoupleCellDim)
502{
503 return (cx >= interpolationPlane.minX - thermocoupleCellDim[0] / 4 &&
504 cy >= interpolationPlane.Y - thermocoupleCellDim[1] / 4 &&
505 cy <= interpolationPlane.Y + thermocoupleCellDim[1] / 4 &&
506 cz >= interpolationPlane.minZ - thermocoupleCellDim[2] / 4 &&
507 cx <= interpolationPlane.maxX + thermocoupleCellDim[0] / 4 &&
508 cz <= interpolationPlane.maxZ + thermocoupleCellDim[2] / 4
509 );
510}
511
513 const char* folder)
514{
515 fvMesh& mesh = _mesh();
516 volScalarField& T = _T();
517 volScalarField& lambda = _lambda();
518 volScalarField& deltaT = _deltaT();
519 autoPtr<volScalarField> gVolField_
520 (
521 new volScalarField("g", T)
522 );
523 volScalarField& gVolField = gVolField_();
525 //Access the mesh information for the boundary
526 const polyPatch& cPatch = mesh.boundaryMesh()[hotSide_ind];
527 //List of cells close to a boundary
528 const labelUList& faceCells = cPatch.faceCells();
529 forAll(cPatch, faceI)
530 {
531 //id of the owner cell having the face
532 label faceOwner = faceCells[faceI] ;
533 gVolField[faceOwner] = g[faceI];
534 }
535
536 ITHACAstream::exportSolution(T, std::to_string(folderNumber + 1), folder,
537 "T");
538 ITHACAstream::exportSolution(lambda, std::to_string(folderNumber + 1), folder,
539 "lambda");
540 ITHACAstream::exportSolution(deltaT, std::to_string(folderNumber + 1), folder,
541 "deltaT");
542 ITHACAstream::exportSolution(gVolField, std::to_string(folderNumber + 1),
543 folder, "g");
544}
545
546//Interpolates the values in Tmeas on the interpolation plane defined in readThermocouples()
548{
549 fvMesh& mesh = _mesh();
550 volScalarField& T = _T();
551 DataTable thermocouplesSamples;
552 DenseVector x(2);
553 unsigned i = 0;
554
556 {
557 interpolationPlane.thermocoupleX.resize(thermocouplesNum);
558 interpolationPlane.thermocoupleZ.resize(thermocouplesNum);
559
560 //find the dimensions of the cells containing the thermocouples
561 //I am assuming all thermocouples are a the same y coordinate
562 //I am assuming all cells have the same dimensions
563 if ( Pstream::master() == true )
564 {
565 unsigned flag = 1;
566
567 while (flag == 1)
568 {
569 if (thermocouplesCellID [i] != -1)
570 {
571 labelList pLabels(mesh.cells()[thermocouplesCellID [i]].labels(mesh.faces()));
572 pointField pLocal(pLabels.size(), Foam::vector::zero);
573 interpolationPlane.thermocoupleCellDim = cellDim (mesh.faces(),
574 mesh.points(),
575 mesh.cells()[thermocouplesCellID [i]],
576 pLabels,
577 pLocal);
578 flag = 0;
579 }
580
581 i++;
582 }
583 }
584
585 //reduce(interpolationPlane.thermocoupleCellDim, sumOp<vector>());
586 forAll(thermocouplesCellID, thermocoupleI)
587 {
588 if (thermocouplesCellID[thermocoupleI] != -1)
589 {
590 interpolationPlane.thermocoupleX [thermocoupleI] =
591 mesh.C()[thermocouplesCellID [thermocoupleI]].component(0);
592 interpolationPlane.thermocoupleZ [thermocoupleI] =
593 mesh.C()[thermocouplesCellID [thermocoupleI]].component(2);
594 }
595 else
596 {
597 interpolationPlane.thermocoupleX [thermocoupleI] = 0;
598 interpolationPlane.thermocoupleZ [thermocoupleI] = 0;
599 }
600 }
601
602 //reduce(interpolationPlane.thermocoupleX, sumOp<List<scalar>>());
603 //reduce(interpolationPlane.thermocoupleZ, sumOp<List<scalar>>());
604 }
605
606 forAll(thermocouplesCellID, thermocoupleI)
607 {
608 x(0) = interpolationPlane.thermocoupleX[thermocoupleI];
609 x(1) = interpolationPlane.thermocoupleZ[thermocoupleI];
610 thermocouplesSamples.addSample(x, Tmeas(thermocoupleI));
611 }
612
613 std::cout << Tmeas << std::endl;
614 RBFSpline rbfspline(thermocouplesSamples, RadialBasisFunctionType::GAUSSIAN);
615 auto inPlaneCellID = 0;
616 forAll(T.internalField(), cellI)
617 {
618 auto cx = mesh.C()[cellI].component(Foam::vector::X);
619 auto cy = mesh.C()[cellI].component(Foam::vector::Y);
620 auto cz = mesh.C()[cellI].component(Foam::vector::Z);
621
623 {
624 if (isInPlane(cx, cy, cz, interpolationPlane.thermocoupleCellDim))
625 {
626 auto planeSize = interpolationPlane.cellID.size() + 1;
627 interpolationPlane.cellID.resize (planeSize);
628 interpolationPlane.Tmeas.resize (planeSize);
629 interpolationPlane.Tdirect.resize(planeSize);
630 interpolationPlane.Tdiff.resize (planeSize);
631 interpolationPlane.Tsens.resize (planeSize);
632 interpolationPlane.cellVol.resize(planeSize);
633 x(0) = cx;
634 x(1) = cz;
635 interpolationPlane.cellID [planeSize - 1] = cellI;
636 interpolationPlane.Tmeas [planeSize - 1] =
637 rbfspline.eval(x);
638 interpolationPlane.cellVol[planeSize - 1] =
639 mesh.V()[cellI];
640 }
641 }
642 else
643 {
644 if (isInPlane(cx, cy, cz, interpolationPlane.thermocoupleCellDim))
645 {
646 x(0) = cx;
647 x(1) = cz;
648 interpolationPlane.Tmeas [inPlaneCellID] =
649 rbfspline.eval(x);
650 inPlaneCellID++;
651 }
652 }
653 }
654
656}
657
658//Interpolates the values in Tmeas on the interpolation plane defined in readThermocouples()
660 DenseMatrix& RBFweights, DenseMatrix& RBFbasis)
661{
662 fvMesh& mesh = _mesh();
663 volScalarField& T = _T();
664 DataTable thermocouplesSamples;
665 DenseVector x(2);
666 unsigned i = 0;
667
669 {
670 interpolationPlane.thermocoupleX.resize(thermocouplesNum);
671 interpolationPlane.thermocoupleZ.resize(thermocouplesNum);
672
673 //find the dimensions of the cells containing the thermocouples
674 //I am assuming all thermocouples are a the same y coordinate
675 //I am assuming all cells have the same dimensions
676 if ( Pstream::master() == true )
677 {
678 unsigned flag = 1;
679
680 while (flag == 1)
681 {
682 if (thermocouplesCellID [i] != -1)
683 {
684 labelList pLabels(mesh.cells()[thermocouplesCellID [i]].labels(mesh.faces()));
685 pointField pLocal(pLabels.size(), Foam::vector::zero);
686 interpolationPlane.thermocoupleCellDim = cellDim (mesh.faces(),
687 mesh.points(),
688 mesh.cells()[thermocouplesCellID [i]],
689 pLabels,
690 pLocal);
691 flag = 0;
692 }
693
694 i++;
695 }
696 }
697
698 //reduce(interpolationPlane.thermocoupleCellDim, sumOp<vector>());
699 forAll(thermocouplesCellID, thermocoupleI)
700 {
701 if (thermocouplesCellID[thermocoupleI] != -1)
702 {
703 interpolationPlane.thermocoupleX [thermocoupleI] =
704 mesh.C()[thermocouplesCellID [thermocoupleI]].component(0);
705 interpolationPlane.thermocoupleZ [thermocoupleI] =
706 mesh.C()[thermocouplesCellID [thermocoupleI]].component(2);
707 }
708 else
709 {
710 interpolationPlane.thermocoupleX [thermocoupleI] = 0;
711 interpolationPlane.thermocoupleZ [thermocoupleI] = 0;
712 }
713 }
714
715 //reduce(interpolationPlane.thermocoupleX, sumOp<List<scalar>>());
716 //reduce(interpolationPlane.thermocoupleZ, sumOp<List<scalar>>());
717 }
718
719 forAll(thermocouplesCellID, thermocoupleI)
720 {
721 x(0) = interpolationPlane.thermocoupleX[thermocoupleI];
722 x(1) = interpolationPlane.thermocoupleZ[thermocoupleI];
723 thermocouplesSamples.addSample(x, Tmeas(thermocoupleI));
724 }
725
726 std::cout << Tmeas << std::endl;
727 RBFSpline rbfspline(thermocouplesSamples, RadialBasisFunctionType::GAUSSIAN);
728 auto inPlaneCellID = 0;
729 forAll(T.internalField(), cellI)
730 {
731 auto cx = mesh.C()[cellI].component(Foam::vector::X);
732 auto cy = mesh.C()[cellI].component(Foam::vector::Y);
733 auto cz = mesh.C()[cellI].component(Foam::vector::Z);
734
736 {
737 if (isInPlane(cx, cy, cz, interpolationPlane.thermocoupleCellDim))
738 {
739 auto planeSize = interpolationPlane.cellID.size() + 1;
740 interpolationPlane.cellID.resize (planeSize);
741 interpolationPlane.Tmeas.resize (planeSize);
742 interpolationPlane.Tdirect.resize(planeSize);
743 interpolationPlane.Tdiff.resize (planeSize);
744 interpolationPlane.Tsens.resize (planeSize);
745 interpolationPlane.cellVol.resize(planeSize);
746 x(0) = cx;
747 x(1) = cz;
748 interpolationPlane.cellID [planeSize - 1] = cellI;
749 interpolationPlane.Tmeas [planeSize - 1] =
750 rbfspline.eval(x);
751 interpolationPlane.cellVol[planeSize - 1] =
752 mesh.V()[cellI];
753 }
754 }
755 else
756 {
757 if (isInPlane(cx, cy, cz, interpolationPlane.thermocoupleCellDim))
758 {
759 x(0) = cx;
760 x(1) = cz;
761 interpolationPlane.Tmeas [inPlaneCellID] =
762 rbfspline.eval(x);
763 inPlaneCellID++;
764 }
765 }
766 }
767
769}
770
772{
773 volScalarField& T = _T();
774
775 if (interpolation)
776 {
777 forAll(interpolationPlane.cellID, cellI)
778 {
779 interpolationPlane.Tdirect[cellI] =
780 T.internalField()[interpolationPlane.cellID [cellI]];
781 }
782
783 interpolationPlane.Tdiff = interpolationPlane.Tdirect -
784 interpolationPlane.Tmeas;
785 }
786 else
787 {
789 Tdiff = Tdirect - Tmeas;
790 }
791}
792
794{
795 Info << "\nResetting time, mesh and fields: " << fieldName << "\n" << endl;
796 _simple.clear();
797
798 if (fieldName == "T" || fieldName == "all")
799 {
800 _T.clear();
801 }
802
803 if (fieldName == "lambda" || fieldName == "all")
804 {
805 _lambda.clear();
806 }
807
808 if (fieldName == "deltaT" || fieldName == "all")
809 {
810 _deltaT.clear();
811 }
812
813 argList& args = _args();
814 Time& runTime = _runTime();
815 //Reinitializing runTime
816 instantList Times = runTime.times();
817 runTime.setTime(Times[1], 1);
818 Foam::fvMesh& mesh = _mesh();
819 _simple = autoPtr<simpleControl>
820 (
821 new simpleControl
822 (
823 mesh
824 )
825 );
826
827 if (fieldName == "T" || fieldName == "all")
828 {
829 //Info << "ReReading field T\n" << endl;
830 _T = autoPtr<volScalarField>
831 (
832 new volScalarField
833 (
834 IOobject
835 (
836 "T",
837 runTime.timeName(),
838 mesh,
839 IOobject::MUST_READ,
840 IOobject::AUTO_WRITE
841 ),
842 mesh
843 )
844 );
845 }
846
847 if (fieldName == "deltaT" || fieldName == "all")
848 {
849 //Info << "ReReading field deltaT\n" << endl;
850 _deltaT = autoPtr<volScalarField>
851 (
852 new volScalarField
853 (
854 IOobject
855 (
856 "deltaT",
857 runTime.timeName(),
858 mesh,
859 IOobject::MUST_READ,
860 IOobject::AUTO_WRITE
861 ),
862 mesh
863 )
864 );
865 }
866
867 if (fieldName == "lambda" || fieldName == "all")
868 {
869 //Info << "ReReading field lambda\n" << endl;
870 _lambda = autoPtr<volScalarField>
871 (
872 new volScalarField
873 (
874 IOobject
875 (
876 "lambda",
877 runTime.timeName(),
878 mesh,
879 IOobject::MUST_READ,
880 IOobject::AUTO_WRITE
881 ),
882 mesh
883 )
884 );
885 }
886
887 Info << "Ready for new computation" << endl;
888}
889
890
891//void inverseLaplacianProblem_CG::offlineSolve()
892//{
893// volScalarField& T = _T();
894// volScalarField& lambda = _lambda();
895// volScalarField& deltaT = _deltaT();
896//
897// if (offline)
898// {
899// ITHACAstream::read_fields(Tfield, T, "./ITHACAoutput/Offline/");
900// ITHACAstream::read_fields(lambdaField, lambda, "./ITHACAoutput/Offline/");
901// ITHACAstream::read_fields(deltaTfield, deltaT, "./ITHACAoutput/Offline/");
902// }
903// else
904// {
905// offlinePhase = 1;
906// set_g();
907// readThermocouples();
908// set_valueFraction();
909// saveSolInLists = 0;
910// offlineSolutionI = 1;
911//
912// for (label i = 0; i < muSamples.cols(); i++)
913// {
914// Info << "Sample number " << i + 1 << endl;
915// Tmeas = muSamples.col(i);
916//
917// if (interpolation)
918// {
919// Info << "Interpolating thermocouples measurements in the " <<
920// "plane defined by them" << endl;
921// thermocouplesInterpolation();
922// }
923// else
924// {
925// Info << "NOT interpolating thermocouples measurements" << endl;
926// }
927//
928// if (!conjugateGradient())
929// {
930// Info << "Conjugate gradient method did not converge" <<
931// "Exiting" << endl;
932// exit(10);
933// }
934// }
935//
936// saveSolInLists = 0;
937// offlinePhase = 0;
938// }
939//}
940
forAll(example_CG.gList, solutionI)
Definition CGtest.H:21
Foam::fvMesh & mesh
Definition createMesh.H:47
Foam::Time & runTime
Definition createTime.H:33
TEqn solve()
int cgIterMax
Maximum CG iterations.
Eigen::VectorXd Tsens
Vector of solutions of the sensitivity problem at the thermocouples points.
Eigen::MatrixXd Jlist
Vector to store the const function J.
void set_valueFraction()
Set valueFraction list values for Robin condition.
PtrList< volScalarField > lambdaField
List of adjoint solutions.
double gamma
Conjugate coefficient.
bool interpolationPlaneDefined
Flag for definition of interpolation plane.
bool saveSolInLists
Flag to save solutions in lists.
double Jtol
Absolute stopping criterion for the CG.
void defineThermocouplesPlane()
Identifies the plane defined by the thermocouples.
void assignSensitivityBC()
Set BC and IF of the sensitivity problem.
thermocouplesPlane interpolationPlane
Interpolation plane.
void thermocouplesInterpolation()
Interpolates the thermocouples measurements in the plane defined in readThermocouples() using radial ...
int isInPlane(double cx, double cy, double cz, Foam::vector thermocoupleCellDim)
Checks if a cell crosses the interpolation plane.
int cgIter
Conjugate Gradient (CG) interations counter.
double gamma_den
Denoinator of the conjugate coefficient.
void sensibilitySolAtThermocouplesLocations()
Fill the Foam::vector containing the values of the sensitivity solution at the thermocouples location...
void assignAdjointBC()
Set BC of the adjoint problem.
void updateHeatFlux()
Updates the heat flux in the conjugate gradient iterations.
int conjugateGradient()
Conjugate gradient method.
void writeFields(label folderNumber, const char *folder)
Writes fields to file.
List< scalar > gradJ
Gradient of the cost function.
void solve(const char *problemID)
Solve for direct and sensitivity.
bool interpolation
Flag for interpolation of the temperature measurements.
List< scalar > P
Search direction.
void solveSensitivity()
Solve sensibility problem.
double gradJ_L2norm
L2 norm of the gradient of J.
PtrList< volScalarField > Tfield
List of temperature solutions.
double JtolRel
Relative stopping criterion for the CG.
autoPtr< volScalarField > _deltaT
Sensibility temperature field.
void computeGradJ()
Computes the gradient of cost function J and its L2 norm.
void solveAdjoint()
Solve adjoint problem.
void computeSearchStep()
Compute the search step beta.
PtrList< volScalarField > deltaTfield
List of sensitivity solutions.
volScalarField assignAdjointBCandSource()
Assign the BC for the adjoint problem and returs the source field.
List< scalar > valueFractionAdj
Value fraction for the adjoint Robin BC.
autoPtr< volScalarField > _lambda
Adjoint field.
void searchDirection()
Computes the search direction P.
void differenceBetweenDirectAndMeasure()
Computes the difference between direct problem solution and measure.
int conjugateGradientConvergenceCheck()
Convergence cher for the conjugate gradient method.
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.
double H
Heat transfer coefficient [W/(m2 K)].
autoPtr< simpleControl > _simple
simpleControl
List< List< scalar > > gList
List of boundary heat fluxes.
List< scalar > g
Heat flux at hotSide [W/m2].
double J
Cost funtion [K^2].
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.
Eigen::VectorXd Tmeas
Vector of measured temperatures at the thermocouples locations [K].
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.
List< int > thermocouplesCellProc
List of incedes of the processors contining each thermocouple.
inverseLaplacianProblem()
Null constructor.
int thermocouplesNum
Number of thermocouples.
double k
Thermal diffusivity [W/(m K)].
void solveDirect()
Solve direct problem.
autoPtr< volScalarField > _T
Temperature field.
List< int > thermocouplesCellID
List of cells indices containing a thermocouple.
autoPtr< argList > _args
argList
volScalarField & T
Definition createT.H:46
Header file of the inverseLaplacianProblem_CG 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 ...
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.
void assignBC(GeometricField< scalar, fvPatchField, volMesh > &s, label BC_ind, double value)
Assign uniform Boundary Condition to a volScalarField.
Eigen::VectorXd boudaryFaceToCellDistance(fvMesh &mesh, label BC_ind)
Compute the distance between the boundary face center and the boundary cell center.
simpleControl simple(mesh)
label i
Definition pEqn.H:46