40sequentialIHTP::sequentialIHTP() {}
42sequentialIHTP::sequentialIHTP(
int argc,
char* argv[])
44 DT(
"DT", dimensionSet(0, 2, -1, 0, 0, 0, 0), 1.0)
46 _args = autoPtr<argList>
48 new argList(argc, argv)
51 if (!
_args->checkRootCase())
53 Foam::FatalError.exit();
56 argList& args =
_args();
57#include "createTime.H"
58#include "createMesh.H"
59 _simple = autoPtr<simpleControl>
66#include "createFields.H"
67#include "createThermocouples.H"
68 thermocouplesPos = TCpos;
69#include "createFvOptions.H"
81#include "createRegularization.H"
86 deltaTime = runTime.deltaTValue();
87 endTime = runTime.endTime().value();
88 Ntimes = (endTime -
startTime) / deltaTime;
89 timeSteps.resize( Ntimes + 1 );
90 forAll(timeSteps, timeI)
92 timeSteps[timeI] =
startTime + (timeI) * deltaTime;
114 volScalarField& T =
_T();
115 fvMesh& mesh =
_mesh();
121 para1->
ITHACAdict->lookupOrDefault<label>(
"sizeOfTheParameter",
127 List<scalar> thermocoupleXList =
128 para1->
ITHACAdict->subDict(
"thermocoupleCoordinates").lookup(
"XValues");
129 List<scalar> thermocoupleZList =
130 para1->
ITHACAdict->subDict(
"thermocoupleCoordinates").lookup(
"ZValues");
131 List<scalar> thermocoupleYList =
132 para1->
ITHACAdict->subDict(
"thermocoupleCoordinates").lookup(
"YValues");
137 thermocoupleXValues(i) = thermocoupleXList[i];
138 thermocoupleZValues(i) = thermocoupleZList[i];
139 thermocoupleYValues(i) = thermocoupleYList[i];
145 Info <<
"\nRadial Basis Functions are used." << endl;
146 Info <<
"The center of each function is at the projection " << endl;
147 Info <<
"of some selected thermocouple on the boundary hotSide." << endl;
148 Info <<
"RBFs must be less than measurements or at least are equal to measurements."
150 Info <<
"If RBFs = measurements it means that we have one basis function in front of each thermocouples.\n\n";
155 int thermocouplesCounter =
168 scalar thermocoupleX = thermocoupleXValues(funcI);
169 scalar thermocoupleZ = thermocoupleZValues(funcI);
170 scalar thermocoupleY = thermocoupleYValues(funcI);
176 mesh.boundaryMesh()[
hotSide_ind].faceCentres()[faceI].x();
177 scalar faceZ = mesh.boundaryMesh()[
hotSide_ind].faceCentres()[faceI].z();
179 scalar radius = Foam::sqrt((faceX - thermocoupleX) * (faceX - thermocoupleX) /
180 maxX / maxX + (faceZ - thermocoupleZ) * (faceZ - thermocoupleZ) / maxZ / maxZ);
184 radius_kb(funcI, faceI) = radius;
187 (shapeParameter * radius));
193 thermocouplesCounter++;
196 cnpy::save(radius_kb,
"radius_kb.npy");
197 cnpy::save(thermocoupleXValues,
"thermocoupleXValues.npy");
198 cnpy::save(thermocoupleZValues,
"thermocoupleZValues.npy");
199 cnpy::save(thermocoupleYValues,
"thermocoupleYValues.npy");
202 std::string heat_flux_space_basis =
"heat_flux_space_basis";
203 std::string folderNamePrRb =
"HeatFluxSpaceRBF";
204 std::string folderPathPrRb =
"ITHACAoutput/projection/" + folderNamePrRb;
211 heatFluxSpaceBasisMatrix.row(i) = Eigen::Map<Eigen::VectorXd>
216 "eigen", folderPathPrRb);
222 Info <<
"POD basis are not yet implemented, exiting" << endl;
253 scalar shapeParameter_space)
255 volScalarField& T =
_T();
257 Info <<
"Using CONSTANT basis in time" << endl;
272 g.resize(timeSteps.size());
278 forAll(timeSteps, timeI)
280 g[timeI].resize(T.boundaryField()[
hotSide_ind].size(), 0.0);
287 M_Assert(Wold.size() == Wnew.size(),
288 "Input weights vectors must have the same size");
291 List<List<scalar>> Wout;
292 Wout.resize(Wold.size());
299 double time = (timeI + 1) * deltaTime;
300 double a = Wold[wI] - (Wnew[wI] - Wold[wI]) / (t1 - t0) * t0;
301 double b = (Wnew[wI] - Wold[wI]) / (t1 - t0);
302 Wout[wI][timeI] = a + b * time;
310 M_Assert(weights.size() ==
Nbasis,
311 "weigths size different from basis functions size");
312 volScalarField& T =
_T();
314 List<List<scalar>> interpolatedWeights;
316 if (interpolationFlag && !offlineFlag)
327 for (
int timeI = firstTimeI; timeI < lastTimeStep; timeI++)
331 g[timeI][faceI] = 0.0;
332 forAll (weights, weightI)
334 if (interpolationFlag && !offlineFlag)
338 g[timeI][faceI] += interpolatedWeights[weightI][shortTime] *
343 g[timeI][faceI] += weights[weightI] *
349 g[timeI][faceI] += weights[weightI] *
361 volScalarField& T =
_T();
362 fvMesh& mesh =
_mesh();
363 volScalarField field(T);
366 const polyPatch& cPatch = mesh.boundaryMesh()[
hotSide_ind];
368 const labelUList& faceCells = cPatch.faceCells();
369 forAll(cPatch, faceI)
372 label faceOwner = faceCells[faceI] ;
373 field[faceOwner] = list[faceI];
380 fvMesh& mesh =
_mesh();
383 M_Assert(
diffusivity > 0.0,
"Call setDiffusivity to set up the diffusivity");
389 Info <<
"\nOffline already computed." << endl;
390 Info <<
"Check that the basis used for the parameterized BC are correct (RBF, POD, etc.)"
396 for (label baseI = 0; baseI < Theta.cols(); baseI++)
401 Tbasis.append(Ttime.clone());
406 Info <<
"\nComputing offline" << endl;
409 Info <<
"Theta size = " << Theta.rows() <<
", " << Theta.cols() << endl;
412 for (label baseI = 0; baseI < Theta.cols(); baseI++)
414 Info <<
"\n--------------------------------------\n" << endl;
415 Info <<
"Base " << baseI + 1 <<
" of " << Theta.cols() << endl;
416 Info <<
"\n--------------------------------------\n" << endl;
427 volScalarField& T = Ttime[timeI];
429 volScalarField gParametrizedField =
list2Field(
g[timeI]);
431 std::to_string(timeSteps[timeI + 1]),
433 "g" + std::to_string(baseI + 1));
436 "T" + std::to_string(baseI + 1));
439 Tbasis.append(Ttime.clone());
441 M_Assert(Tcomp.size() == addSol.size(),
442 "Something wrong in reading values at the observations points");
444 for (
int i = 0; i < Tcomp.size(); i++)
446 Theta(i, baseI) = Tcomp(i) + addSol(i);
454 Eigen::MatrixXd A = Theta;
455 Eigen::JacobiSVD<Eigen::MatrixXd> svd(A,
456 Eigen::ComputeThinU | Eigen::ComputeThinV);
457 Eigen::MatrixXd singularValues = svd.singularValues();
458 double conditionNumber = singularValues.maxCoeff() / singularValues.minCoeff();
459 Info <<
"Theta Condition number = " << conditionNumber << endl;
462 Eigen::MatrixXd ThetaTI = Theta * Eigen::MatrixXd::Identity(Theta.rows(),
467 Info <<
"\nOffline ENDED" << endl;
472 Info <<
"Reconstructing field T" << endl;
474 Info <<
"\nExporting solution in the time domain (" <<
485 volScalarField gParametrizedField =
list2Field(
g[0]);
487 std::to_string(timeSteps[0]),
494 volScalarField T =
_T.clone();
496 forAll(Tbasis, baseI)
498 T +=
gWeights[baseI] * (Tbasis[baseI][timeI] + Tad_time[timeI]);
500 T += - Tad_time[timeI] + T0_time[timeI];
505 volScalarField gParametrizedField =
list2Field(
g[realTimeStep - 1]);
507 std::to_string(timeSteps[realTimeStep]),
510 Ttime.append(T.clone());
516 Eigen::VectorXd Tout(cells.size());
519 for (
int cellI = 0; cellI < cells.size(); cellI++)
521 forAll(Tbasis, baseI)
523 Tout(cellI) +=
gWeights[baseI] * (Tbasis[baseI][timeI].internalField()[cellI]
524 + Tad_time[timeI].internalField()[cellI]);
526 Tout(cellI) += - Tad_time[timeI].internalField()[cellI] +
527 T0_time[timeI].internalField()[cellI];
533void sequentialIHTP::parameterizedBC(word outputFolder,
534 volScalarField initialField)
536 Info << endl <<
"Using quasilinearity of direct problem ::" << endl;
537 Info <<
"Using " << linSys_solver <<
" to solve the linear system" << endl;
539 List<Eigen::MatrixXd> linSys;
541 linSys[0] = Theta.transpose() * Theta;
545 Info <<
"\nTime sample " <<
timeSampleI + 1 << endl;
546 auto t_start = std::chrono::high_resolution_clock::now();
558 linSys[1] = Theta.transpose() * (TmeasShort + addSol - T0_vector);
559 Eigen::VectorXd weigths;
561 if (linSys_solver ==
"fullPivLU")
563 weigths = linSys[0].fullPivLu().solve(linSys[1]);
565 else if (linSys_solver ==
"jacobiSvd")
567 Eigen::JacobiSVD<Eigen::MatrixXd> svd(linSys[0],
568 Eigen::ComputeThinU | Eigen::ComputeThinV);
569 weigths = svd.solve(linSys[1]);
571 else if (linSys_solver ==
"householderQr")
573 weigths = linSys[0].householderQr().solve(linSys[1]);
575 else if (linSys_solver ==
"ldlt")
577 weigths = linSys[0].ldlt().solve(linSys[1]);
579 else if (linSys_solver ==
"inverse")
581 weigths = linSys[0].inverse() * linSys[1];
583 else if (linSys_solver ==
"TSVD")
585 Info <<
"Using TSVD" << endl;
589 else if (linSys_solver ==
"Tikhonov")
592 linSys[1] = (TmeasShort + addSol - T0_vector);
593 Eigen::JacobiSVD<Eigen::MatrixXd> svd(linSys[0],
594 Eigen::ComputeThinU | Eigen::ComputeThinV);
599 Info <<
"Select a linear system solver in this list:" << endl
600 <<
"fullPivLU, jacobiSvd, householderQr, ldlt, TSVD, Tikhonov, conjugateGradient"
609 gWeights[weightI] = weigths(weightI);
611 Info <<
"Weights = \n" <<
gWeights << endl;
614 parameterizedBC_postProcess(linSys, weigths, outputFolder, verbose);
616 auto t_end = std::chrono::high_resolution_clock::now();
617 double elapsed_time_ms = std::chrono::duration<double, std::milli>
618 (t_end - t_start).count();
619 Info <<
"CPU time = " << elapsed_time_ms <<
" milliseconds" << endl << endl;
623 Info <<
"End" << endl;
629 fvMesh& mesh =
_mesh();
630 valueFraction.resize(mesh.boundaryMesh()[
"coldSide"].size());
631 homogeneousBCcoldSide.resize(mesh.boundaryMesh()[
"coldSide"].size());
632 Eigen::VectorXd faceCellDist =
634 forAll (valueFraction, faceI)
636 valueFraction[faceI] = 1 / (1 + (
thermalCond /
HTC / faceCellDist(faceI)));
637 homogeneousBCcoldSide[faceI] = 0;
639 refGrad = homogeneousBCcoldSide;
644 fvMesh& mesh =
_mesh();
645 volScalarField& T =
_T();
647 forAll(mesh.boundaryMesh(), patchI)
649 if (patchI == mesh.boundaryMesh().findPatchID(
"coldSide"))
653 else if (patchI == mesh.boundaryMesh().findPatchID(
"hotSide"))
666 Info <<
"\nSolving FULL T0 problem" << endl;
668 fvMesh& mesh =
_mesh();
669 simpleControl& simple =
_simple();
671 volScalarField T0 =
_T.clone();
674 List<scalar> RobinBC = Tf * 0.0;
675 word outputFolder =
"./ITHACAoutput/debugT0/";
680 forAll(mesh.boundaryMesh(), patchI)
682 if (patchI == mesh.boundaryMesh().findPatchID(
"coldSide"))
693 while (runTime.loop())
695 Info <<
"Time = " << runTime.timeName() << nl << endl;
698 while (simple.correctNonOrthogonal())
704 fvOptions.constrain(TEqn);
706 fvOptions.correct(T0);
709 T0_time.append(T0.clone());
713 timeI]), outputFolder,
"T0");
714 runTime.printExecutionTime(Info);
719 Info <<
"SolveT0 ENDED\n" << endl;
724 word outputFolder =
"./ITHACAoutput/modes/";
725 Info <<
"Computing " <<
NmodesT0 <<
" T0 modes" << endl;
729 PtrList<volScalarField> modes =
T0modes.toPtrList();
733 outputFolder,
"T0modes");
735 Info <<
"T0 modes COMPUTED\n" << endl;
740 Info <<
"\n*****************************************************" << endl;
741 Info <<
"Computing projection matrices" << endl;
742 fvMesh& mesh =
_mesh();
743 simpleControl& simple =
_simple();
745 volScalarField T0 =
_T.clone();
748 List<scalar> RobinBC = Tf * 0.0;
749 forAll(mesh.boundaryMesh(), patchI)
751 if (patchI == mesh.boundaryMesh().findPatchID(
"coldSide"))
761 Eigen::SparseMatrix<double> T0implicitMatrix;
762 Eigen::SparseMatrix<double> T0explicitMatrix;
764 fvScalarMatrix Teq(fvm::ddt(T0) - fvm::laplacian(
DT *
diffusivity, T0));
769 * T0implicitMatrix *
T0modes.EigenModes[0];
771 * b.asDiagonal() *
T0modes.EigenModes[0];
772 Info <<
"Projection matrices COMPUTED\n" << endl;
779 Info <<
"Computing direct problem projection matrices" << endl;
780 int internalFieldSize = Tbasis[0][0].internalField().size();
781 Eigen::MatrixXd Tbasis_Eigen(internalFieldSize,
Nbasis);
782 Eigen::VectorXd Tad_Eigen =
784 PtrList<volScalarField> Tbasis_lastTime;
786 "The basis for the direct problem have wrong dimention in time");
787 forAll(Tbasis, baseI)
791 Tbasis_lastTime.append(temp.clone());
800 M_Assert(Ncells > 0,
"Set the number of magic points");
804 for (
int cellI = 0; cellI < Ncells; cellI++)
817 Info <<
"Computing the offline part for the projection error" << endl;
822 word outputFolder =
"./ITHACAoutput/projectionError";
823 forAll(Tbasis, baseI)
825 volScalarField base = Tbasis[baseI][lastTimestepID];
826 volScalarField baseProj(base);
828 volScalarField temp = base - baseProj;
831 std::to_string(baseI + 1),
832 outputFolder,
"projectionErrorTbasis");
835 volScalarField TadProj(Tbasis[0][lastTimestepID]);
837 volScalarField temp(Tad_time[lastTimestepID] - TadProj);
840 outputFolder,
"projectionErrorTad");
869 Info <<
"Solving additional problem" << endl;
871 fvMesh& mesh =
_mesh();
872 simpleControl& simple =
_simple();
874 volScalarField Tad =
_T.clone();
881 List<scalar> RobinBC = - Tf;
882 forAll(mesh.boundaryMesh(), patchI)
884 if (patchI == mesh.boundaryMesh().findPatchID(
"coldSide"))
894 while (runTime.loop())
896 Info <<
"Time = " << runTime.timeName() << nl << endl;
900 forAll(mesh.boundaryMesh(), patchI)
902 if (patchI == mesh.boundaryMesh().findPatchID(
"coldSide"))
912 while (simple.correctNonOrthogonal())
918 fvOptions.constrain(TEqn);
920 fvOptions.correct(Tad);
923 Tad_time.append(Tad.clone());
927 runTime.printExecutionTime(Info);
931 Info <<
"Tad_time.size = " << Tad_time.size() << endl;
932 Info <<
"Ntime = " << Ntimes << endl;
934 Info <<
"END \n" << endl;
948 M_Assert(
diffusivity > 1e-36,
"Set the diffusivity value");
949 volScalarField& T =
_T();
957 simpleControl& simple =
_simple();
963 while (runTime.loop())
965 Info <<
"Time = " << runTime.timeName() << nl << endl;
969 while (simple.correctNonOrthogonal())
975 fvOptions.constrain(TEqn);
977 fvOptions.correct(T);
980 Ttime.append(T.clone());
981 runTime.printExecutionTime(Info);
985 Info <<
"Direct computation ENDED" << endl;
990 Info <<
"Defining positions of thermocouples" << endl;
994 word fileName =
"./thermocouplesCellsID";
998 Info <<
"Reading thermocouples cells from file" << endl;
1005 Info <<
"Defining positions of thermocouples" << endl;
1006 fvMesh& mesh =
_mesh();
1007 volScalarField& T =
_T();
1008 thermocouplesCellID.resize(thermocouplesPos.size());
1009 forAll(thermocouplesPos, tcI)
1011 thermocouplesCellID[tcI] = mesh.findCell(thermocouplesPos[tcI]);
1013 volScalarField thermocouplesField(T);
1015 forAll(thermocouplesCellID, tcI)
1017 thermocouplesField.ref()[thermocouplesCellID[tcI]] = 1;
1020 "./ITHACAoutput/thermocouplesField/",
1021 "thermocouplesField,");
1023 thermocouplesCellID);
1040 WarningInFunction <<
"readThermocouples function called twice." << endl;
1041 WarningInFunction <<
"I am not doing the second reading." << endl;
1046 volScalarField& field)
1053 fvMesh& mesh =
_mesh();
1054 dictionary interpolationDict =
1055 mesh.solutionDict().subDict(
"interpolationSchemes");
1056 autoPtr<Foam::interpolation<scalar>> fieldInterp =
1057 Foam::interpolation<scalar>::New(interpolationDict, field);
1058 Eigen::VectorXd fieldInt;
1059 fieldInt.resize(thermocouplesPos.size());
1060 forAll(thermocouplesPos, tcI)
1062 fieldInt(tcI) = fieldInterp->interpolate(thermocouplesPos[tcI],
1063 thermocouplesCellID[tcI]);
1069 PtrList<volScalarField> fieldList, label fieldI)
1076 PtrList<volScalarField> fieldList)
1078 Eigen::VectorXd fieldInt;
1080 if ( fieldList.size() == Ntimes + 1 )
1082 Info <<
"\n Sampling for ALL sampling times \n\n" << endl;
1092 Info <<
"\nField size = " << fieldList.size() <<
1093 ".\nSampling ONLY the last timestep\n\n" << endl;
1099 Info <<
"The input fieldList of sequentialIHTP::fieldValueAtThermocouples can have size Ntimes + 1 (="
1100 << Ntimes + 1 <<
") or\n";
1102 ") but has size " << fieldList.size() << endl;
1103 Info <<
"Exiting." << endl;
1107 Info <<
"\nSampling done \n" << endl;
1115 instantList Times = runTime.times();
1116 runTime.setTime(Times[1], 0);
1119 Foam::fvMesh& mesh =
_mesh();
1120 _simple = autoPtr<simpleControl>
1127 _T = autoPtr<volScalarField>
1136 IOobject::MUST_READ,
1137 IOobject::AUTO_WRITE
1142 Info <<
"Ready for new computation" << endl;
1147 Info <<
"Setting endTime to offlineEndTime" << endl;
1150 instantList Times = runTime.times();
1151 runTime.setTime(0.0, 0);
1153 Info <<
"Ready for new offline computation" << endl;
1158 Info <<
"Setting endTime to offlineEndTime" << endl;
1161 instantList Times = runTime.times();
1162 runTime.setTime(0.0, 0);
1164 Info <<
"Ready for new T0 computation" << endl;
1169 scalar EPSILON = 2e-16;
1176 "timeSamplesDeltaT should be a multiple of deltaTime");
1178 M_Assert(n0 > 0,
"First sampling step cannot be 0");
1181 M_Assert(std::fabs(n0 * deltaTime -
timeSamplesT0) < EPSILON,
1182 "The first sampling time must coincide with a simulation timestep");
1187 M_Assert(!(endTime + EPSILON < samplingEndTime
1188 && std::fabs(endTime - samplingEndTime) > EPSILON),
1189 "The samplingEndTime cannot be later than the symulation endTime");
1198void sequentialIHTP::parameterizedBC_postProcess(
1199 List<Eigen::MatrixXd> linSys, Eigen::VectorXd weigths, word outputFolder,
1202 Eigen::JacobiSVD<Eigen::MatrixXd> svd(Theta,
1203 Eigen::ComputeThinU | Eigen::ComputeThinV);
1204 Eigen::MatrixXd singVal = svd.singularValues();
1210 Info <<
"Singular values of Theta.transpose() * Theta are " << endl;
1211 Info << svd.singularValues() << endl;
1212 Info <<
"weigths = " << endl;
1213 Info << weigths << endl;
1214 Info <<
"linSys[1] = " << endl;
1215 Info << linSys[1] << endl;
1216 Info <<
"Theta = " << endl;
1217 Info << Theta << endl;
1218 residual = linSys[0] * weigths - linSys[1];
1221 Info <<
"Residual 2-norm = " << endl;
1222 Info << residual.squaredNorm() << endl;
1223 Info <<
"\n addSol = " << endl;
1224 Info << addSol << endl;
1225 Info <<
"T0_vector = " << endl;
1226 Info << T0_vector << endl;
1227 Info <<
"Tmeas = " << endl;
1228 Info << Tmeas << endl;
1233 Info <<
"Tcomp = \n" << Tcomp.transpose() << endl;
1234 Info <<
"TmeasShort = \n" << TmeasShort.transpose() << endl;
1235 J = 0.5 * Foam::sqrt((Tcomp - TmeasShort).dot(Tcomp - TmeasShort));
1236 Info <<
"J = " <<
J << endl;
1243 M_Assert(NmagicPoints > 0,
"Set number of magic points");
1246 "Number of magic points bigger than number of modes");
1251 Eigen::VectorXd rho(1);
1252 Eigen::MatrixXd MatrixModes =
T0modes.toEigen()[0];
1254 double max = MatrixModes.cwiseAbs().col(0).maxCoeff(&ind_max, &c1);
1257 Eigen::MatrixXd U = MatrixModes.col(0);
1258 Eigen::SparseMatrix<double> P;
1259 P.resize(MatrixModes.rows(), 1);
1260 P.insert(ind_max, 0) = 1;
1262 for (label i = 1; i < NmagicPoints; i++)
1264 A = P.transpose() * U;
1265 b = P.transpose() * MatrixModes.col(i);
1266 c = A.fullPivLu().solve(b);
1267 r = MatrixModes.col(i) - U * c;
1268 max = r.cwiseAbs().maxCoeff(&ind_max, &c1);
1269 P.conservativeResize(MatrixModes.rows(), i + 1);
1270 P.insert(ind_max, i) = 1;
1271 U.conservativeResize(MatrixModes.rows(), i + 1);
1272 U.col(i) = MatrixModes.col(i);
1273 rho.conservativeResize(i + 1);
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 Eigen::MatrixXd field2Eigen(GeometricField< Type, PatchField, GeoMesh > &field)
Convert a vector OpenFOAM field into an Eigen Vector.
static void fvMatrix2Eigen(fvMatrix< type_foam_matrix > foam_matrix, type_A &A, type_B &b)
Convert a FvMatrix OpenFOAM matrix (Linear System) into a Eigen Matrix A and a source vector b.
Class for the definition of some general parameters, the parameters must be defined from the file ITH...
IOdictionary * ITHACAdict
Dictionary for input objects from file.
static ITHACAparameters * getInstance()
Gets an instance of ITHACAparameters, to be used if the instance is already existing.
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.
virtual void readThermocouples()
Identifies in the mesh the cells corresponding to the termocouples locations.
void parameterizedBCoffline(bool force=0)
Performs offline computation for the parameterized BC method, if the offline directory "".
Eigen::MatrixXd T0explicitMatrix_red
T0 reduced explicit matrix.
label timeSamplesNum
Number of time samples (filled in createThermocouples.H).
label NbasisInTime
Number of basis in time.
label coldSide_ind
Index of the coldSide patch.
Eigen::VectorXd pointTad_reconstructed
Reconstruction of Tsd at the magic points.
scalar diffusivity
Diffusivity value.
double HTC
Heat transfer coefficient [W/(m2 K)].
scalar timeSamplesDeltaT
Time interval in between samples (read from thermocouplesDict).
void restartT0()
Restart fields.
int NmodesT0
Number of POD modes.
void restartOffline()
Restart fields.
int thermocouplesNum
Number of thermocouples.
void T0offline(int NmagicPoints)
Assemble all the matrices required in the online phase.
dimensionedScalar DT
Dummy thermal diffusivity with unitary value.
volScalarModes T0modes
List of POD modes.
Eigen::VectorXd Jlist
List of cost funtions [K^2].
label hotSide_ind
Index of the hotSide patch.
Eigen::MatrixXd Tbasis_projectionMat
Projection of the Tbasis on the reduced space.
label timeSampleI
Time sample index.
Eigen::VectorXd Tad_projected
Projection of Tad on the reduced space.
Eigen::MatrixXd pointsReconstructMatrix
Matrix that reconstruct some points into the full order space.
label NtimestepsInSequence
Number of timesteps considered in each acquisition sequence.
List< scalar > gWeightsOld
Weights of the parameterization.
void reconstrucT(word outputFolder)
Reconstructs the temperature field using superposition of effects.
PtrList< volScalarField > projectionErrorTad
L2 norm of the projection error of Tad on the T0 modes.
Eigen::MatrixXd T0implicitMatrix_red
T0 reduced implicit matrix.
List< List< scalar > > interpolateWeights(List< scalar > Wold, List< scalar > Wnew)
double thermalCond
Thermal conductivity [W/(m K)].
PtrList< volScalarField > projectionErrorTbasis
L2 norm of the projection error of Tbasis on the T0 modes.
void findMagicPoints(int NmagicPoints)
Find the points at with the projection error is computed.
List< List< scalar > > heatFluxSpaceBasis
Heat flux space basis.
PtrList< volScalarField > T0field
List of snapshots for the T0 solutions.
word folderOffline
Folder where the offline solutions are saved.
List< List< List< scalar > > > gBaseFunctions
Bases of the heat flux.
scalar startTime
Time discretization (filled in the constructor).
void solveAdditional()
Set BC and IF of the additional problem for the parameterized heat flux.
void projectionErrorOffline()
Compute the L2 norm of the projection error for each Tbasis and Tad.
autoPtr< volScalarField > _T
Temperature field.
List< label > magicPoints
Magic points for the T0 projection error estimation.
void update_gParametrized(List< scalar > weights)
Update the boundary condition g when g is parameterized.
virtual void solveT0(volScalarField initialField)
Solve the T0 problem.
void sampling2symulationTime()
Fills the vector samplingSteps which contains the timesteps at which the measurements are taken.
label NbasisInSpace
Number of basis in space.
List< scalar > samplingTime
List of times at which the measurements are acquired (this List is filled by readThermocouples()).
bool thermocouplesRead
1 if readThermocouples() was called, 0 elsewise
double J
Cost funtion [K^2].
autoPtr< Time > _runTime
Time.
void set_gParametrized(word spaceBaseFuncType, scalar shapeParameter_space)
Set parameterized heat flux defining the basis.
Eigen::VectorXd residual
Parametrized BC.
volScalarField list2Field(List< scalar > list, scalar innerField=0.0)
Convert list of boundary heat flux into field.
scalar offlineEndTime
End time for the ofline computation.
void setDiffusivity(scalar _diff)
Set diffusivity.
void projectT0()
Project T0 matrices onto the reduced spaced.
void projectDirectOntoT0()
Assemble the matrices to go from the gWeights to the T0 reduced space.
autoPtr< fvMesh > _mesh
Mesh.
scalar timeSamplesT0
First sampling time (read from thermocouplesDict).
List< List< scalar > > g
Heat flux at hotSide.
List< label > samplingSteps
List of timesteps at which measurements are available.
Eigen::VectorXd fieldValueAtThermocouples(volScalarField &field)
Interpolates the field value at the thermocouples points NOTE: do NOT call whe field is an element of...
label NtimeStepsBetweenSamples
Number of timesteps between two samples.
label offlineTimestepsSize
Number of timestep to solve for during offline phase.
autoPtr< simpleControl > _simple
simpleControl
label Nbasis
Number of basis.
autoPtr< fv::options > _fvOptions
fvOptions
virtual void assignDirectBC(label timeI)
Set BC of the direct problem.
Eigen::MatrixXd pointTbasis_reconstructionMat
Matrix that reconstructs the Tbasis at the magic points.
void solveDirect()
Solve direct problem.
label NsamplesWindow
Number of samples considered in the offline phase.
void set_valueFraction()
Set valueFraction list values for Robin condition.
void pointProjectionOffline()
Assemble the matrix pointsProjectionMatrix to project some points on the reduced basis space.
List< scalar > gWeights
Weights of the parameterization.
void setSpaceBasis(word type, scalar shapeParameter, label Npod=0)
Define the base functions used for the parametrization of g.
void getT0modes()
Compute T0 modes prome snapshots.
void restart()
Restart temperature field.
void getModes(PtrList< GeometricField< Type, PatchField, GeoMesh > > &snapshots, PtrList< GeometricField< Type, PatchField, GeoMesh > > &modes, word fieldName, bool podex, bool supex, bool sup, label nmodes, bool correctBC)
Computes the bases or reads them for a field.
Eigen::VectorXd Tikhonov(Eigen::MatrixXd A, Eigen::MatrixXd b, double regularizationParameter)
Truncated Singular Value regularization.
Eigen::VectorXd TSVD(Eigen::MatrixXd A, Eigen::MatrixXd b, int filter)
Truncated Singular Value regularization.
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 read_fields(PtrList< GeometricField< Type, PatchField, GeoMesh > > &Lfield, word Name, fileName casename, int first_snap, int n_snap)
Function to read a list of fields from the name of the field and casename.
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.
Header file of the sequentialIHTP class.