2#include "PODTemplate.H"
8PODTemplate<T>::PODTemplate(Parameters* myParameters,
9 const word& myfield_name,
const word& mySnapshots_path) :
10 m_parameters(static_cast<StoredParameters*>(myParameters)),
11 field_name(myfield_name),
12 casenameData(m_parameters->get_casenameData()),
13 l_nSnapshot(m_parameters->get_nSnapshots()),
14 snapshotsPath(mySnapshots_path),
15 l_nBlocks(m_parameters->get_nBlocks()),
16 l_nmodes(m_parameters->get_nModes()[field_name]),
17 l_hilbertSp(m_parameters->get_hilbertSpacePOD()[field_name]),
18 weightH1(m_parameters->get_weightH1()),
19 weightBC(m_parameters->get_weightPOD()),
20 patchBC(m_parameters->get_patchBC()),
21 l_startTime(m_parameters->get_startTime()),
22 l_endTime(m_parameters->get_endTime()),
23 l_nSnapshotSimulation(m_parameters->get_nSnapshotsSimulation()),
24 l_endTimeSimulation(m_parameters->get_endTimeSimulation()),
25 b_centeredOrNot(m_parameters->get_centeredOrNot()),
26 lambda(Eigen::VectorXd::Zero(l_nmodes)),
27 w_eigensolver(m_parameters->get_eigensolver()),
28 i_precision(m_parameters->get_precision()),
29 ios_outytpe(m_parameters->get_outytpe()),
30 runTime2(Foam::Time::controlDictName,
".",
31 m_parameters->get_casenameData())
33 if (snapshotsPath ==
"default_path")
35 snapshotsPath = casenameData;
38 word pathProcessor(
"");
39 if (Pstream::parRun())
41 pathProcessor =
"processor" + name(Pstream::myProcNo()) +
"/";
43 timeFolders = runTime2.findTimes(snapshotsPath + pathProcessor);
45 l_startTime = Time::findClosestTimeIndex(timeFolders,std::stoi(runTime2.times()[l_startTime].name()));
46 l_endTime = l_startTime + l_nSnapshot - 1;
52 snapshotsPath + timeFolders[1].name(),
53 m_parameters->get_mesh(),
56 m_parameters->get_mesh()
58 f_meanField =
new T(f_field->name(), *f_field);
77PODTemplate<T>::~PODTemplate()
85void PODTemplate<T>::define_paths()
87 word pathCentered(
"");
89 if (b_centeredOrNot && !(field_name ==
"U"))
91 pathCentered =
"_centered";
96 pathCentered +=
"Lifted";
99 word pathProcessor(
"");
100 if (Pstream::parRun())
102 pathProcessor =
"processor" + name(Pstream::myProcNo()) +
"/";
105 word pathHilbertSpace(m_parameters->get_pathHilbertSpace_fromHS(
109 name_covMatrix =
"covMatrix" + f_field->name();
110 folder_covMatrix =
"./ITHACAoutput/CovMatrices" + pathHilbertSpace
111 + pathCentered +
"/";
115 name_eigenValues =
"Eigenvalues_" + f_field->name();
116 name_eigenValuesNormalized =
"EigenvaluesNormalized_" + f_field->name();
117 name_cumEigenValues =
"/CumEigenvalues_" + f_field->name();
118 name_eigenVector =
"/Eigenvector_" + f_field->name() ;
119 folder_eigen =
"./ITHACAoutput/EigenValuesandVector"
120 + pathCentered +
"_" + std::to_string(l_nmodes) +
"modes/";
122 name_eigenValues +
".npy")
125 folder_spatialModes =
"./ITHACAoutput/spatialModes"
126 + pathCentered +
"_" + std::to_string(l_nmodes) +
"modes/";
130 folder_temporalModes =
"./ITHACAoutput/temporalModes"
131 + pathCentered +
"_" + std::to_string(l_nmodes) +
"modes/";
133 f_field->name() +
".npy");
135 folder_temporalModesSimulation =
"./ITHACAoutput/temporalModesSimulation"
136 + pathCentered +
"_" + std::to_string(l_nmodes) +
"modes/";
138 folder_temporalModesSimulation + f_field->name() +
".npy");
140 folder_mean =
"./ITHACAoutput/mean/";
142 std::to_string(1) +
"/" + f_field->name());
147void PODTemplate<T>::computeMeanField()
151 Info <<
"Loading lifting functions" << endl;
152 liftfield.resize(inletIndex.rows());
154 for (label k = 0; k < inletIndex.rows(); k++)
160 f_field->name() +
"lift" + std::to_string(k),
161 snapshotsPath + timeFolders[1].name(),
162 m_parameters->get_mesh(),
165 m_parameters->get_mesh()
167 liftfield.set(k, f_lift );
176 Info <<
"Computing the mean of " << f_field->name() <<
" field" << endl;
177 T snapshotj = *f_field;
178 b_centeredOrNot =
false;
180 for (label j = 0; j < l_nSnapshot; j++)
183 ITHACAstream::read_snapshot(snapshotj, timeFolders[l_startTime+j].name(), snapshotsPath);
189 b_centeredOrNot =
true;
191 PtrList<T> meanExport(1);
192 meanExport.set(0,
new T(f_meanField->name(), *f_meanField));
198 Info <<
"Reading the mean of " << f_field->name() <<
" field" << endl;
200 *f_meanField = meanRead[0];
205 *f_meanField, l_hilbertSp);
206 m_parameters->set_meanEnergy( f_meanField->name(), energyMean);
207 m_parameters->set_meanEnergy( f_meanField->name() +
"_" + l_hilbertSp,
220void PODTemplate<T>::appendMeanfieldtoSpatialModes(PtrList<T>& spatialModes)
224 spatialModes.set(l_nmodes, f_meanField);
229void PODTemplate<T>::findTempFile(Eigen::MatrixXd* covMat,
int* index1,
232 word pathTemp = name_covMatrix +
"_temp_";
234 struct dirent* entry;
235 dir = opendir(folder_covMatrix.c_str());
236 word extTemp =
".npy";
237 Info <<
"looking for " << pathTemp.c_str() <<
"*" << extTemp.c_str() <<
" in "
238 << folder_covMatrix.c_str() << endl;
242 int INDEX[2][2], N_INDEX = 0;
244 for (
int i = 0; i < 2; i++)
246 for (
int j = 0; j < 2; j++)
254 while ((entry = readdir(dir)) != NULL)
257 strncpy(ext_name,
" ", 4);
259 if ( strlen(entry->d_name) >= 4 )
261 for (
int i = 0; i < 4; i++)
263 ext_name[i] = entry->d_name[strlen(entry->d_name) - (4 - i)];
267 if ((strncmp(entry->d_name, pathTemp.c_str(), pathTemp.size()) == 0)
268 && (strncmp(ext_name, extTemp.c_str(), 4) == 0))
271 char endFileName[12];
272 strncpy(endFileName, entry->d_name+strlen(entry->d_name)-12, 12);
273 sscanf(endFileName,
"%*[^0-9]%d_%d", &num1, &num2);
279 INDEX[0][0] = *index1;
280 INDEX[0][1] = *index2;
281 INDEX[1][0] = *index1;
282 INDEX[1][1] = *index2;
287 if ( *index1 < INDEX[0][0] )
289 INDEX[0][0] = *index1;
290 INDEX[0][1] = *index2;
294 if (( *index1 == INDEX[0][0] ) && ( *index2 < INDEX[0][1] ))
296 INDEX[0][1] = *index2;
301 if ( *index1 > INDEX[1][0] )
303 INDEX[1][0] = *index1;
304 INDEX[1][1] = *index2;
308 if (( *index1 == INDEX[1][0] ) && ( *index2 > INDEX[1][1] ))
310 INDEX[1][1] = *index2;
315 N_INDEX = N_INDEX + 1;
316 Info <<
" " << entry->d_name <<
" FOUND => covMat can be updated" << endl;
327 *index1 = INDEX[0][0];
328 *index2 = INDEX[0][1];
329 Info <<
" -> RESTART from INDEX : " << *index1 <<
" " << *index2 <<
330 " (oldest *_temp_*.npy file)" << endl;
332 sprintf(str1,
"%d", *index1);
334 sprintf(str2,
"%d", *index2);
335 word suffix =
static_cast<word
>(str1) +
"_" +
static_cast<word
>(str2);
336 cnpy::load(*covMat, folder_covMatrix + pathTemp + suffix + extTemp);
337 Info <<
" with covMat size=(" << covMat->rows() <<
", " << covMat->cols()
343word PODTemplate<T>::nameTempCovMatrix(
int i,
int j)
346 sprintf(str1,
"%d", i);
348 sprintf(str2,
"%d", j);
349 word suffix =
"_temp_" +
static_cast<word
>(str1) +
"_" +
static_cast<word
>
351 word filename = folder_covMatrix + name_covMatrix + suffix +
".npy";
356void PODTemplate<T>::saveTempCovMatrix(Eigen::MatrixXd& covMatrix,
int i,
int j)
358 word filename = nameTempCovMatrix(i, j);
359 if (Pstream::master())
361 cnpy::save(covMatrix, filename);
366void PODTemplate<T>::deleteTempCovMatrix(
int i,
int j)
368 word filename = nameTempCovMatrix(i, j);
369 std::ifstream fileStr(filename.c_str());
373 remove(filename.c_str());
378void PODTemplate<T>::deletePreviousTempCovMatrix_N(
int* valI,
int* valJ,
int i,
384 int NUM = (1 + i) * i / 2 + j;
392 S = (1 + *valI)** valI / 2;
396 S = (1 + *valI)** valI / 2;
410 if ((*valI >= 0) && (*valJ >= 0))
412 deleteTempCovMatrix(*valI, *valJ);
419Eigen::MatrixXd PODTemplate<T>::buildCovMatrix()
422 double CovUnrealValue = 999999.999999;
423 Eigen::MatrixXd covMatrix;
424 covMatrix.setConstant(l_nSnapshot, l_nSnapshot, CovUnrealValue);
433 mkDir(folder_covMatrix);
436 if (!exist_covMatrix && !exist_covMatrix_bin)
439 findTempFile(&covMatrix, &etapeI, &etapeJ);
440 Info <<
"Computing the covariance matrix of the " << f_field->name() <<
" field"
443 label q = l_nSnapshot / l_nBlocks;
444 label r = l_nSnapshot % l_nBlocks;
445 Info <<
"q = " << q << endl;
446 Info <<
"r = " << r << endl;
447 Info <<
"nSnapshot = " << l_nSnapshot << endl;
448 Info <<
"nBlocks = " << l_nBlocks << endl;
450 PtrList<T> snapshots;
455 if (etapeJ == etapeI - 1)
473 int N_previous_temp_Mat = 3;
475 for (label i = etapeI; i < l_nBlocks; i++)
478 l_startTime - 2 + i * q, q);
481 indTri.index_start = i * q;
482 indTri.index_end = (i + 1) * q;
483 addCovMatrixTriCoeff(covMatrix, snapshots, indTri);
484 PtrList<T> snapshots2;
485 int valI = etapeI, valJ = etapeJ;
487 for (label j = etapeJ; j < i; j++)
490 l_startTime - 2 + j * q, q);
492 indexSquare indSquare;
493 indSquare.index1_start = i * q;
494 indSquare.index1_end = (i + 1) * q;
495 indSquare.index2_start = j * q;
496 indSquare.index2_end = (j + 1) * q;
497 addCovMatrixSquareCoeff(covMatrix, snapshots, snapshots2, indSquare);
501 saveTempCovMatrix(covMatrix, i, j);
503 deletePreviousTempCovMatrix_N(&valI, &valJ, i, j, N_previous_temp_Mat);
514 PtrList<T> snapshotsEnd;
516 l_startTime - 2 + l_nBlocks * q, r);
519 indTri.index_start = l_nBlocks * q;
520 indTri.index_end = l_nSnapshot;
521 addCovMatrixTriCoeff(covMatrix, snapshotsEnd, indTri);
522 PtrList<T> snapshotsEnd2;
524 for (label j = 0; j < l_nBlocks; j++)
527 l_startTime - 2 + j * q, q);
529 indexSquare indSquare;
530 indSquare.index1_start = l_nBlocks * q;
531 indSquare.index1_end = l_nSnapshot;
532 indSquare.index2_start = j * q;
533 indSquare.index2_end = (j + 1) * q;
534 addCovMatrixSquareCoeff(covMatrix, snapshotsEnd, snapshotsEnd2, indSquare);
535 snapshotsEnd2.clear();
537 saveTempCovMatrix(covMatrix, l_nBlocks, j);
539 deletePreviousTempCovMatrix_N(&valI, &valJ, l_nBlocks, j, N_previous_temp_Mat);
542 snapshotsEnd.clear();
545 covMatrix = covMatrix.selfadjointView<Eigen::Lower>();
546 if (Pstream::master())
548 cnpy::save(covMatrix, folder_covMatrix + name_covMatrix +
".npy");
554 deletePreviousTempCovMatrix_N(&valI, &valJ, l_nBlocks - 1, l_nBlocks - 1, 1);
559 deletePreviousTempCovMatrix_N(&valI, &valJ, l_nBlocks, l_nBlocks, 1);
563 else if (exist_covMatrix)
565 Info <<
"Reading the covariance matrix of the " << f_field->name() <<
" field"
567 cnpy::load(covMatrix, folder_covMatrix + name_covMatrix +
".npy");
572 Info <<
"Reading (binary) the covariance matrix of the " << f_field->name() <<
575 if (Pstream::master())
577 cnpy::save(covMatrix, folder_covMatrix + name_covMatrix +
".npy");
583 int NbCovUnrealValue = 0;
585 for (
int i = 0; i < l_nSnapshot; i++)
587 for (
int j = i; j < l_nSnapshot; j++)
589 if (covMatrix(i, j) == CovUnrealValue)
592 NbCovUnrealValue += 1;
597 if (covMatrixOK == 0)
599 Info <<
"\n!!! OUPS !!! Unreal value [" << CovUnrealValue <<
"] found " <<
600 NbCovUnrealValue <<
" times in triangular up part of " << name_covMatrix <<
605 double varyingEnergy = covMatrix.trace() / l_nSnapshot;
607 if (l_hilbertSp ==
"L2" || l_hilbertSp ==
"dL2")
609 m_parameters->set_varyingEnergy( f_field->name(), varyingEnergy);
612 Info <<
"Total varying " << l_hilbertSp <<
" energy for " << field_name <<
" : "
613 << varyingEnergy << endl;
620void PODTemplate<T>::addCovMatrixTriCoeff(Eigen::MatrixXd& covMatrix,
621 PtrList<T>& snapshots, indexTri& indTri)
623 Info <<
"Adding the triangular block [" << indTri.index_start <<
":" <<
624 indTri.index_end - 1 <<
"]x["
625 << indTri.index_start <<
":" << indTri.index_end - 1 <<
626 "] to the covariance matrix" << endl;
628 snapshots, l_hilbertSp, weightBC, patchBC));
630 for (label i = 0; i < indTri.index_end - indTri.index_start; i++)
632 for (label j = 0; j <= i; j++)
634 covMatrix(i + indTri.index_start, j + indTri.index_start) =
644void PODTemplate<T>::addCovMatrixSquareCoeff(Eigen::MatrixXd& covMatrix,
645 PtrList<T>& snapshots1,
646 PtrList<T>& snapshots2,
647 indexSquare& indSquare)
649 Info <<
"Adding the square block [" << indSquare.index1_start <<
":" <<
650 indSquare.index1_end - 1 <<
"]x["
651 << indSquare.index2_start <<
":" << indSquare.index2_end - 1 <<
652 "] to the covariance matrix" << endl;
654 snapshots2, l_hilbertSp, weightBC, patchBC));
656 for (label i = 0; i < indSquare.index1_end - indSquare.index1_start; i++)
658 for (label j = 0; j < indSquare.index2_end - indSquare.index2_start; j++)
660 covMatrix(i + indSquare.index1_start, j + indSquare.index2_start) =
670void PODTemplate<T>::diagonalisation(Eigen::MatrixXd& covMatrix,
671 Eigen::VectorXd& eigenValueseig, Eigen::MatrixXd& eigenVectoreig)
673 if (!exist_eigenDecomposition)
676 Info <<
"Performing the eigen decomposition" << endl;
678 if (w_eigensolver ==
"spectra")
680 Spectra::DenseSymMatProd<double> op(covMatrix);
681 Spectra::SymEigsSolver<Spectra::DenseSymMatProd<double>> es(op, l_nmodes, l_nSnapshot);
682 std::cout <<
"Using Spectra EigenSolver " << std::endl;
684 es.compute(Spectra::SortRule::LargestAlge);
685 M_Assert(es.info() == Spectra::CompInfo::Successful,
686 "The Eigenvalue Decomposition did not succeed");
687 eigenVectoreig = es.eigenvectors().real();
688 eigenValueseig = es.eigenvalues().real();
690 else if (w_eigensolver ==
"eigen")
692 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> esEg;
693 std::cout <<
"Using Eigen EigenSolver " << std::endl;
694 esEg.compute(covMatrix);
695 M_Assert(esEg.info() == Eigen::Success,
696 "The Eigenvalue Decomposition did not succeed");
697 eigenVectoreig = esEg.eigenvectors().real().rowwise().reverse().leftCols(
699 eigenValueseig = esEg.eigenvalues().real().reverse().head(l_nmodes);
706 eigenValueseigLam = eigenValueseig.real().array().abs().sqrt();
709 if (Pstream::master())
711 cnpy::save(eigenValueseig, folder_eigen + name_eigenValues +
".npy");
713 cnpy::save(eigenVectoreig,
714 folder_eigen +
"/Eigenvector_" + f_field->name() +
".npy");
716 cnpy::save(eigenValueseigLam,
717 folder_eigen +
"/EigenvectorLambda_" + f_field->name() +
".npy");
718 Eigen::VectorXd eigenValueseigNormalized = eigenValueseig /
719 eigenValueseig.sum();
720 Eigen::VectorXd cumEigenValues(eigenValueseigNormalized);
722 for (
int j = 1; j < cumEigenValues.size(); ++j)
724 cumEigenValues(j) += cumEigenValues(j - 1);
728 cnpy::save(eigenValueseigNormalized,
729 folder_eigen + name_eigenValuesNormalized +
".npy");
731 cnpy::save(cumEigenValues, folder_eigen + name_cumEigenValues +
".npy");
738 cnpy::load(eigenValueseig, folder_eigen + name_eigenValues +
".npy");
740 cnpy::load(eigenVectoreig,
741 folder_eigen +
"/Eigenvector_" + f_field->name() +
".npy");
743 cnpy::load(eigenValueseigLam,
744 folder_eigen +
"/EigenvectorLambda_" + f_field->name() +
".npy");
747 double resolvedVaryingEnergy = eigenValueseig.sum() / l_nSnapshot;
749 if (l_hilbertSp ==
"L2")
751 m_parameters->set_resolvedVaryingEnergy( f_field->name(),
752 resolvedVaryingEnergy);
756 m_parameters->set_resolvedVaryingEnergy( f_field->name() +
"_" +
757 l_hilbertSp, resolvedVaryingEnergy);
760 Info <<
"% of varying " << l_hilbertSp <<
" energy captures by the modes for "
762 <<
" : " << 100.0 * eigenValueseig.sum() / covMatrix.trace() <<
"%" << endl;
768PtrList<T> PODTemplate<T>::computeSpatialModes(Eigen::VectorXd& eigenValueseig,
769 Eigen::MatrixXd& eigenVectoreig)
771 PtrList<T> spatialModes;
774 if (!exist_spatialModes)
776 Info <<
"Computing the spatial modes of the " << f_field->name() <<
" field" <<
778 spatialModes.resize(l_nmodes);
780 for (
int k = 0; k < l_nmodes; k++)
782 spatialModes.set(k,
new T(f_field->name(), *f_field) );
786 for (label j = 0; j < l_nSnapshot; j++)
788 T snapshotj = *f_field;
789 ITHACAstream::read_snapshot(snapshotj, timeFolders[l_startTime+j].name(), snapshotsPath);
791 if ((m_parameters->get_DEIMInterpolatedField() ==
"nut"
793 && l_hilbertSp ==
"dL2")
800 for (label k = 0; k < l_nmodes; k++)
806 for (
int k = 0; k < l_nmodes; k++)
811 mkDir(folder_spatialModes);
817 Info <<
"Reading the spatial modes of the " << f_field->name() <<
" field" <<
828Eigen::MatrixXd PODTemplate<T>::computeTemporalModes(Eigen::VectorXd&
829 eigenValueseig, Eigen::MatrixXd& eigenVectoreig)
831 Eigen::MatrixXd temporalModes(l_nSnapshot, l_nmodes);
833 if (!exist_temporalModes)
835 Info <<
"Computing the temporal modes of the " << f_field->name() <<
" field" <<
837 mkDir( folder_temporalModes );
839 for (
int i = 0; i < l_nmodes; i++)
841 temporalModes.col(i) = eigenVectoreig.col(i) * eigenValueseigLam(i);
844 if (Pstream::master())
846 cnpy::save(temporalModes, folder_temporalModes + f_field->name() +
".npy");
851 Info <<
"Reading the temporal modes of the " << f_field->name() <<
" field" <<
853 cnpy::load(temporalModes, folder_temporalModes + f_field->name() +
".npy");
857 return temporalModes;
861void PODTemplate<T>::getModes(PtrList<T>& spatialModes,
862 Eigen::MatrixXd& temporalModes, Eigen::MatrixXd& temporalModesSimulation,
863 Eigen::MatrixXd& covMatrix)
865 Info <<
"-------------------------------------------------------------------------------------------"
867 Info <<
"The POD is performing with the following parameters :" << endl;
868 Info <<
"Field : " << f_field->name() << endl;
869 Info <<
"Number of modes : " << l_nmodes << endl;
870 Info <<
"POD Hilbert space : " << l_hilbertSp << endl;
871 Info <<
"Weight for the boundary conditions (0 for L2 POD Hilbert space) : " <<
873 Info <<
"Patch for the boundary conditions(inlet by default) used in L2wBC : "
875 Info <<
"start time : " << l_startTime << endl;
876 Info <<
"End time : " << l_endTime << endl;
877 Info <<
"Number of snapshots : " << l_nSnapshot << endl;
878 Info <<
"Number of test snapshots : " << l_nSnapshotSimulation << endl;
879 Info <<
"Number of blocks : " << l_nBlocks << endl;
880 Info <<
"Centered datas or not : " << b_centeredOrNot <<
881 " (1 centered, 0 not centered)" << endl;
882 Info <<
"Name of eigensolver used : " << w_eigensolver << endl;
883 Info <<
"Results folder : " <<
"ITHACAoutput" << endl;
885 covMatrix = this->buildCovMatrix();
887 Eigen::VectorXd eigenValueseig = Eigen::VectorXd::Zero(l_nmodes);
888 Eigen::MatrixXd eigenVectoreig = Eigen::MatrixXd::Zero(l_nSnapshot, l_nmodes);
889 diagonalisation(covMatrix, eigenValueseig, eigenVectoreig);
890 spatialModes = computeSpatialModes(eigenValueseig, eigenVectoreig);
891 temporalModes = computeTemporalModes(eigenValueseig, eigenVectoreig);
892 compute_lambda(temporalModes);
893 temporalModesSimulation = computeSimulationTemporalModes(spatialModes);
896 if (field_name ==
"U")
898 m_parameters->set_eigenValues_U(eigenValueseig);
899 m_parameters->set_lambda(lambda);
902 Info <<
"-------------------------------------------------------------------------------------------"
907Eigen::MatrixXd PODTemplate<T>::computeSimulationTemporalModes(
908 PtrList<T>& f_spatialModes)
910 Eigen::MatrixXd temporalModesSimulation(l_nSnapshotSimulation, l_nmodes);
912 if (!exist_temporalModesSimulation)
914 Info <<
"Computing the Simulation temporal modes of the " << f_field->name() <<
916 mkDir( folder_temporalModesSimulation );
917 label l_startTimeSimulation(l_endTime);
919 for (label j = 0; j < l_nSnapshotSimulation; j++)
921 T snapshotj = *f_field;
922 ITHACAstream::read_snapshot(snapshotj, timeFolders[l_startTimeSimulation+j].name(), snapshotsPath);
924 if ((m_parameters->get_DEIMInterpolatedField() ==
"nut"
926 && l_hilbertSp ==
"dL2")
933 for (label i = 0; i < l_nmodes; i++)
936 f_spatialModes[i], l_hilbertSp, weightBC, patchBC, weightH1);
940 if (Pstream::master())
942 cnpy::save(temporalModesSimulation,
943 folder_temporalModesSimulation + f_field->name() +
".npy");
948 Info <<
"Reading the Simulation temporal modes of the " << f_field->name() <<
950 cnpy::load(temporalModesSimulation,
951 folder_temporalModesSimulation + f_field->name() +
".npy");
955 return temporalModesSimulation;
959void PODTemplate<T>::compute_lambda(Eigen::MatrixXd& temporalModes)
961 for (
int p = 0; p < l_nmodes; p++)
963 for (
int i = 0; i < l_nSnapshot; i++)
965 lambda(p) += temporalModes(i, p) * temporalModes(i, p);
968 lambda(p) /= l_nSnapshot;
974void PODTemplate<T>::lift(PtrList<T>& snapshots)
979 computeLift(snapshots, liftfield, omfield, inletIndex);
985 for (label k = 0; k < snapshots.size(); k++)
993void PODTemplate<T>::lift(T& snapshot)
995 PtrList<T> snapshots(1);
996 snapshots.set(0,
new T(snapshot.name(), snapshot));
998 snapshot = snapshots[0];
1001 for (
int k = 0; k < snapshotsBC.size(); k++)
1008template PODTemplate<volTensorField>::PODTemplate(
Parameters*
1009 myParameters,
const word& myfield_name,
const word& mySnapshots_path);
1012template PODTemplate<volTensorField>::~PODTemplate();
1013template void PODTemplate<volTensorField>::define_paths();
1014template void PODTemplate<volTensorField>::computeMeanField();
1015template void PODTemplate<volTensorField>::appendMeanfieldtoSpatialModes(
1016 PtrList<volTensorField>& spatialModes);
1017template void PODTemplate<volTensorField>::findTempFile(Eigen::MatrixXd* covMat,
1018 int* index1,
int* index2);
1019template void PODTemplate<volTensorField>::deleteTempCovMatrix(
int i,
int j);
1021template word PODTemplate<volTensorField>::nameTempCovMatrix(
int i,
int j);
1022template void PODTemplate<volTensorField>::saveTempCovMatrix(
1023 Eigen::MatrixXd& covMatrix,
int i,
int j);
1024template void PODTemplate<volTensorField>::deletePreviousTempCovMatrix_N(
1025 int* valI,
int* valJ,
int i,
int j,
int N);
1027template Eigen::MatrixXd PODTemplate<volTensorField>::buildCovMatrix();
1028template void PODTemplate<volTensorField>::addCovMatrixTriCoeff(
1029 Eigen::MatrixXd& covMatrix,
1030 PtrList<volTensorField>& snapshots,
1032template void PODTemplate<volTensorField>::addCovMatrixSquareCoeff(
1033 Eigen::MatrixXd& covMatrix,
1034 PtrList<volTensorField>& snapshots1,
1035 PtrList<volTensorField>& snapshots2,
1036 indexSquare& indSquare);
1037template void PODTemplate<volTensorField>::diagonalisation(
1038 Eigen::MatrixXd& covMatrix, Eigen::VectorXd& eigenValueseig,
1039 Eigen::MatrixXd& eigenVectoreig);
1040template PtrList<volTensorField>
1041PODTemplate<volTensorField>::computeSpatialModes(Eigen::VectorXd&
1042 eigenValueseig, Eigen::MatrixXd& eigenVectoreig);
1044template Eigen::MatrixXd PODTemplate<volTensorField>::computeTemporalModes(
1045 Eigen::VectorXd& eigenValueseig, Eigen::MatrixXd& eigenVectoreig);
1046template void PODTemplate<volTensorField>::getModes(PtrList<volTensorField>&
1047 spatialModes, Eigen::MatrixXd& temporalModes,
1048 Eigen::MatrixXd& temporalModesSimulation, Eigen::MatrixXd& covMatrix);
1049template Eigen::MatrixXd
1050PODTemplate<volTensorField>::computeSimulationTemporalModes(
1051 PtrList<volTensorField>& spatialModes);
1052template void PODTemplate<volTensorField>::compute_lambda(
1053 Eigen::MatrixXd& temporalModes);
1054template void PODTemplate<volTensorField>::lift(PtrList<volTensorField>&
1056template void PODTemplate<volTensorField>::lift(volTensorField& snapshot);
1059template PODTemplate<volVectorField>::PODTemplate(
Parameters*
1060 myParameters,
const word& myfield_name,
const word& mySnapshots_path);
1063template PODTemplate<volVectorField>::~PODTemplate();
1064template void PODTemplate<volVectorField>::define_paths();
1065template void PODTemplate<volVectorField>::computeMeanField();
1066template void PODTemplate<volVectorField>::appendMeanfieldtoSpatialModes(
1067 PtrList<volVectorField>& spatialModes);
1068template Eigen::MatrixXd PODTemplate<volVectorField>::buildCovMatrix();
1069template void PODTemplate<volVectorField>::addCovMatrixTriCoeff(
1070 Eigen::MatrixXd& covMatrix,
1071 PtrList<volVectorField>& snapshots,
1073template void PODTemplate<volVectorField>::addCovMatrixSquareCoeff(
1074 Eigen::MatrixXd& covMatrix,
1075 PtrList<volVectorField>& snapshots1,
1076 PtrList<volVectorField>& snapshots2,
1077 indexSquare& indSquare);
1078template void PODTemplate<volVectorField>::diagonalisation(
1079 Eigen::MatrixXd& covMatrix, Eigen::VectorXd& eigenValueseig,
1080 Eigen::MatrixXd& eigenVectoreig);
1081template PtrList<volVectorField>
1082PODTemplate<volVectorField>::computeSpatialModes(Eigen::VectorXd&
1083 eigenValueseig, Eigen::MatrixXd& eigenVectoreig);
1085template Eigen::MatrixXd PODTemplate<volVectorField>::computeTemporalModes(
1086 Eigen::VectorXd& eigenValueseig, Eigen::MatrixXd& eigenVectoreig);
1087template void PODTemplate<volVectorField>::getModes(PtrList<volVectorField>&
1088 spatialModes, Eigen::MatrixXd& temporalModes,
1089 Eigen::MatrixXd& temporalModesSimulation, Eigen::MatrixXd& covMatrix);
1090template Eigen::MatrixXd
1091PODTemplate<volVectorField>::computeSimulationTemporalModes(
1092 PtrList<volVectorField>& spatialModes);
1093template void PODTemplate<volVectorField>::compute_lambda(
1094 Eigen::MatrixXd& temporalModes);
1095template void PODTemplate<volVectorField>::lift(PtrList<volVectorField>&
1097template void PODTemplate<volVectorField>::lift(volVectorField& snapshot);
1100template PODTemplate<volScalarField>::PODTemplate(
Parameters*
1101 myParameters,
const word& myfield_name,
const word& mySnapshots_path);
1104template PODTemplate<volScalarField>::~PODTemplate();
1105template void PODTemplate<volScalarField>::define_paths();
1106template void PODTemplate<volScalarField>::computeMeanField();
1107template void PODTemplate<volScalarField>::appendMeanfieldtoSpatialModes(
1108 PtrList<volScalarField>& spatialModes);
1109template Eigen::MatrixXd PODTemplate<volScalarField>::buildCovMatrix();
1110template void PODTemplate<volScalarField>::addCovMatrixTriCoeff(
1111 Eigen::MatrixXd& covMatrix,
1112 PtrList<volScalarField>& snapshots,
1114template void PODTemplate<volScalarField>::addCovMatrixSquareCoeff(
1115 Eigen::MatrixXd& covMatrix,
1116 PtrList<volScalarField>& snapshots1,
1117 PtrList<volScalarField>& snapshots2,
1118 indexSquare& indSquare);
1119template void PODTemplate<volScalarField>::diagonalisation(
1120 Eigen::MatrixXd& covMatrix, Eigen::VectorXd& eigenValueseig,
1121 Eigen::MatrixXd& eigenVectoreig);
1122template PtrList<volScalarField>
1123PODTemplate<volScalarField>::computeSpatialModes(Eigen::VectorXd&
1124 eigenValueseig, Eigen::MatrixXd& eigenVectoreig);
1126template Eigen::MatrixXd PODTemplate<volScalarField>::computeTemporalModes(
1127 Eigen::VectorXd& eigenValueseig, Eigen::MatrixXd& eigenVectoreig);
1128template void PODTemplate<volScalarField>::getModes(PtrList<volScalarField>&
1129 spatialModes, Eigen::MatrixXd& temporalModes,
1130 Eigen::MatrixXd& temporalModesSimulation, Eigen::MatrixXd& covMatrix);
1131template Eigen::MatrixXd
1132PODTemplate<volScalarField>::computeSimulationTemporalModes(
1133 PtrList<volScalarField>& spatialModes);
1134template void PODTemplate<volScalarField>::compute_lambda(
1135 Eigen::MatrixXd& temporalModes);
1136template void PODTemplate<volScalarField>::lift(PtrList<volScalarField>&
1138template void PODTemplate<volScalarField>::lift(volScalarField& snapshot);
1142void computeLift(PtrList<volTensorField>& Lfield,
1143 PtrList<volTensorField>& liftfield, PtrList<volTensorField>& omfield,
1144 Eigen::MatrixXi inletIndex)
1150 for (label k = 0; k < inletIndex.rows(); k++)
1152 label p = inletIndex(k, 0);
1153 label l = inletIndex(k, 1);
1154 area = gSum(Lfield[0].mesh().magSf().boundaryField()[p]);
1155 u_lf = gSum(liftfield[k].mesh().magSf().boundaryField()[p] *
1156 liftfield[k].boundaryField()[p]).component(l) / area;
1157 M_Assert(std::abs(u_lf) > 1e-5,
1158 "The lift cannot be computed. Please, check your inletIndex definition");
1160 for (label j = 0; j < Lfield.size(); j++)
1164 u_bc = gSum(Lfield[j].mesh().magSf().boundaryField()[p] *
1165 Lfield[j].boundaryField()[p]).component(l) / area;
1166 volTensorField C(Lfield[0].name(), Lfield[j] - liftfield[k]*u_bc / u_lf);
1167 omfield.append(C.clone());
1171 u_bc = gSum(omfield[j].mesh().magSf().boundaryField()[p] *
1172 omfield[j].boundaryField()[p]).component(l) / area;
1173 volTensorField C(Lfield[0].name(), omfield[j] - liftfield[k]*u_bc / u_lf);
1174 omfield.set(j, C.clone());
1180void computeLift(PtrList<volVectorField>& Lfield,
1181 PtrList<volVectorField>& liftfield, PtrList<volVectorField>& omfield,
1182 Eigen::MatrixXi inletIndex)
1188 for (label k = 0; k < inletIndex.rows(); k++)
1190 label p = inletIndex(k, 0);
1191 label l = inletIndex(k, 1);
1192 area = gSum(Lfield[0].mesh().magSf().boundaryField()[p]);
1193 u_lf = gSum(liftfield[k].mesh().magSf().boundaryField()[p] *
1194 liftfield[k].boundaryField()[p]).component(l) / area;
1195 M_Assert(std::abs(u_lf) > 1e-5,
1196 "The lift cannot be computed. Please, check your inletIndex definition");
1198 for (label j = 0; j < Lfield.size(); j++)
1202 u_bc = gSum(Lfield[j].mesh().magSf().boundaryField()[p] *
1203 Lfield[j].boundaryField()[p]).component(l) / area;
1204 volVectorField C(Lfield[0].name(), Lfield[j] - liftfield[k]*u_bc / u_lf);
1205 omfield.append(C.clone());
1209 u_bc = gSum(omfield[j].mesh().magSf().boundaryField()[p] *
1210 omfield[j].boundaryField()[p]).component(l) / area;
1211 volVectorField C(Lfield[0].name(), omfield[j] - liftfield[k]*u_bc / u_lf);
1212 omfield.set(j, C.clone());
1218void computeLift(PtrList<volScalarField>& Lfield,
1219 PtrList<volScalarField>& liftfield, PtrList<volScalarField>& omfield,
1220 Eigen::MatrixXi inletIndex)
1226 for (label k = 0; k < inletIndex.rows(); k++)
1228 label p = inletIndex(k, 0);
1229 area = gSum(Lfield[0].mesh().magSf().boundaryField()[p]);
1230 t_lf = gSum(liftfield[k].mesh().magSf().boundaryField()[p] *
1231 liftfield[k].boundaryField()[p]) / area;
1233 for (label j = 0; j < Lfield.size(); j++)
1237 t_bc = gSum(Lfield[j].mesh().magSf().boundaryField()[p] *
1238 Lfield[j].boundaryField()[p]) / area;
1239 volScalarField C(Lfield[0].name(), Lfield[j] - liftfield[k]*t_bc / t_lf);
1240 omfield.append(C.clone());
1244 t_bc = gSum(omfield[j].mesh().magSf().boundaryField()[p] *
1245 omfield[j].boundaryField()[p]) / area;
1246 volScalarField C(Lfield[0].name(), omfield[j] - liftfield[k]*t_bc / t_lf);
1247 omfield.set(j, C.clone());
static List< Eigen::VectorXd > field2EigenBC(GeometricField< scalar, PatchField, GeoMesh > &field)
Convert an OpenFOAM scalar field to a List of Eigen Vectors, one for each boundary.
namespace for the computation of the POD, it exploits bot the method of snapshots and SVD.
void ReadDenseMatrix(MatrixType &Matrix, word folder, word MatrixName)
Read a dense matrix from a binary format file.
void exportFields(PtrList< GeometricField< Type, PatchField, GeoMesh > > &field, word folder, word fieldname)
Function to export a scalar of vector field.
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.
bool containsSubstring(std::string contain, std::string contained)
Returns true if contained is a substring of contain, false otherwise.
void multField(T &f1, double alpha)
Multiplication between a field of type vol[Scalar|Vector|Tensor]Field and a double.
void setToZero(T &f1)
Set a field of type vol[Scalar|Vector|Tensor]Field to 0.
Eigen::MatrixXd dot_product_POD(PtrList< T > &v, PtrList< T > &w, const word &hilbertSpacePOD, const double &weightBC, const word &patchBC, const double &weightH1)
Perform the dot product of two PtrList of type T.
void addFields(T &f1, const T &f2c, double alpha)
Perform the following operation f1 + f2 * alpha with f1 and f2 being of type vol[Scalar|Vector|Tensor...
double dot_product_L2(const volVectorField &v, const volVectorField &w)
Perform the L2 dot product of v and w.
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.
void subtractFields(T &f1, const T &f2)
Perform the substraction (f1 - f2) between two fields of type vol[Scalar|Vector|Tensor]Field and alph...