34 m_parameters(parameters),
36 runTime2(Foam::Time::controlDictName,
".", m_parameters->get_casenameData()),
37 meanU(new volVectorField(m_parameters->get_meanU())),
38 nModesU(m_parameters->get_nModes()[
"U"]),
39 interpolatedField(m_parameters->get_DEIMInterpolatedField()),
40 nModesHR(m_parameters->get_nModes()[interpolatedField]),
41 nMagicPoints(m_parameters->get_nMagicPoints()),
42 magicPoints(m_parameters->get_magicPoints()),
43 localMagicPoints(m_parameters->get_localMagicPoints()),
44 Ck(m_parameters->get_Ck()),
45 Ce(m_parameters->get_Ce())
49 cnpy::load(temporalModesUSimulation,
"./ITHACAoutput/temporalModesSimulation_" + std::to_string(nModesU) +
"modes/U.npy");
51 weightAtMg = Eigen::VectorXd(nMagicPoints);
52 for (
int i = 0; i < nMagicPoints; i++)
54 weightAtMg(i) = std::pow(m_parameters->get_submesh().V()[localMagicPoints[i]], 0.5);
60 meanSmagOnMagicNeighborhoods =
new volVectorField(m_parameters->get_meanVectorDEIMMagic());
61 for (
auto& defTensorOfMode:m_parameters->get_deformationTensorOfModesOnMagicNeighborhoods())
63 defTensorOfModesAtMg.push_back(defTensorOfMode);
69 meanNutOnMagicPoints =
new volScalarField(m_parameters->get_meanScalarDEIMMagic());
70 for (
auto& defTensorOfMode:m_parameters->get_deformationTensorOfModesOnMagicPoints())
72 defTensorOfModesAtMg.push_back(defTensorOfMode);
76 nut0 =
new volScalarField(
"nut", volScalarField(
77 IOobject(
"nut0", m_parameters->get_casenameData() +
"0", m_parameters->get_submesh(), IOobject::MUST_READ),
78 m_parameters->get_submesh()));
80 delta =
new volScalarField(m_parameters->get_magicDelta());
81 aaa =
new volScalarField(Ce/(*delta));
82 inv2aaa =
new volScalarField(1/(2*(*aaa)));
84 fullDefField =
new volTensorField(defTensorOfModesAtMg[0]);
85 bbb =
new volScalarField((2.0/3.0)*tr(*fullDefField));
86 ccc =
new volScalarField(2*Ck*(*delta)*(dev(*fullDefField) && (*fullDefField)));
87 sqrtk =
new volScalarField((-(*bbb) + sqrt(sqr(*bbb) + 4*(*aaa)*(*ccc)))*(*inv2aaa));
88 nut =
new volScalarField(Ck*(*delta)*(*sqrtk));
92void tutorial27_online::evaluateApproxNut(
const Eigen::VectorXd& reducedCoeffs)
94 *fullDefField = defTensorOfModesAtMg[0];
95 for (
int c = 0 ; c < reducedCoeffs.size() ; c++)
97 *fullDefField += reducedCoeffs(c)*defTensorOfModesAtMg[c+1];
99 *bbb = (2.0/3.0) * tr(*fullDefField);
100 *ccc = 2*Ck * (*delta) * ((dev(*fullDefField) && (*fullDefField)));
101 *sqrtk = mag(-(*bbb) + sqrt(sqr(*bbb) + 4*(*aaa) * (*ccc))) * (*inv2aaa);
102 *nut = Ck * (*delta) * (*sqrtk);
103 for (
int i = 0; i < nut0->size(); i++)
105 (*nut0)[i] = (*nut)[i];
107 nut0->correctBoundaryConditions();
110Eigen::VectorXd tutorial27_online::computeApproxSmagMg(
const Eigen::VectorXd& reducedCoeffs)
112 evaluateApproxNut(reducedCoeffs);
113 volVectorField stressField = fvc::div(2*(*nut0) * dev(*fullDefField)) - *meanSmagOnMagicNeighborhoods;
115 Eigen::VectorXd output = Eigen::VectorXd::Zero(d * (nMagicPoints + 1));
116 for (
int i = 0; i < nMagicPoints; i++)
118 vector stressVector = weightAtMg(i) * (stressField)[localMagicPoints[i]];
120 output(i * d) = stressVector.x();
121 output(i * d + 1) = stressVector.y();
122 output(i * d + 2) = stressVector.z();
124 output(d * nMagicPoints) = 1.0;
128Eigen::VectorXd tutorial27_online::computeApproxNutMg(
const Eigen::VectorXd& reducedCoeffs)
130 evaluateApproxNut(reducedCoeffs);
131 *nut0 -= *meanNutOnMagicPoints;
133 Eigen::VectorXd output(nMagicPoints + 1);
134 for (
int i = 0; i < nMagicPoints; i++)
136 output(i) = weightAtMg(i) * (*nut0)[localMagicPoints[i]];
138 output(nMagicPoints) = 1.0;
142Eigen::VectorXd tutorial27_online::predictSmagROMCoeffs(
const Eigen::VectorXd& reducedCoeffs)
146 Eigen::MatrixXd projected_K_DEIM = m_parameters->get_projected_K_DEIM();
147 Eigen::VectorXd smagVect(computeApproxSmagMg(reducedCoeffs));
149 return massMatrixInv*projected_K_DEIM*smagVect;
154 Eigen::VectorXd nutVect(computeApproxNutMg(reducedCoeffs));
155 Eigen::Tensor<double, 3 > xi_complete_onMagicPts(m_parameters->get_xi_onMagicPts());
156 Eigen::VectorXd b_extended(reducedCoeffs.size() + 1);
157 b_extended << 1.0,reducedCoeffs;
159 Eigen::VectorXd output(nModesU);
160 for (
int i = 0; i < nModesU; i++)
163 for (
int j = 0 ; j < nMagicPoints +1; j++)
165 for (
int q = 0 ; q < nModesU + 1 ; q++)
167 output(i) += xi_complete_onMagicPts(q,j,i) * b_extended(q) * nutVect(j);
171 return massMatrixInv*output;
176volVectorField tutorial27_online::computeROMproj_fromCoeffs(
const Eigen::VectorXd& reducedCoeffs,
bool stressUnit)
178 Eigen::MatrixXd reducedCoeffsMatrix(nModesU, 1);
179 for (label k = 0; k < nModesU; k++)
181 reducedCoeffsMatrix(k,0) = reducedCoeffs[k];
188 dimensionedScalar time_inv(
"time_inv", dimensionSet(0,0,-1,0,0), scalar(1.0));
189 return reconstruction[0]*time_inv;
193 return reconstruction[0];
198Eigen::VectorXd tutorial27_online::computeROMcoeffs_fromFullDim(volVectorField& f_full)
200 bool consider_volumes =
true;
203 return coeffsVelocityPOD.col(0);
207volVectorField tutorial27_online::computeSmagTerm_fromChronos(
const Eigen::VectorXd& reducedCoeffs)
209 return m_UnsteadyNSTurb->computeSmagTerm_fromU(*meanU + computeROMproj_fromCoeffs(reducedCoeffs));
213void tutorial27_online::prediction()
215 word folder_results =
"./ITHACAoutput/Online/" + m_parameters->get_HRMethod() +
"_" + interpolatedField.substr(7)
216 +
"U_" + std::to_string(nMagicPoints) +
"MgPts/";
217 mkDir(folder_results);
218 Eigen::MatrixXd predictedCoeffs(m_parameters->get_nSnapshotsSimulation(), nModesU);
219 Eigen::MatrixXd exactCoeffs(m_parameters->get_nSnapshotsSimulation(), nModesU);
220 Eigen::VectorXd relProjError(m_parameters->get_nSnapshotsSimulation());
222 for (label t = 0; t < m_parameters->get_nSnapshotsSimulation(); t++)
224 label index_time = t + m_parameters->get_startTime() + m_parameters->get_nSnapshots() - 1;
227 predictedCoeffs.row(t) = predictSmagROMCoeffs(temporalModesUSimulation.row(t));
228 volVectorField predictedSmagProj = computeROMproj_fromCoeffs(predictedCoeffs.row(t),
true);
231 volVectorField exactSmag = computeSmagTerm_fromChronos(temporalModesUSimulation.row(t));
232 exactCoeffs.row(t) = computeROMcoeffs_fromFullDim(exactSmag);
233 volVectorField exactSmagProj = computeROMproj_fromCoeffs(exactCoeffs.row(t),
true);
238 std::string idxTimeStr(runTime2.times()[index_time].name());
242 cnpy::save(predictedCoeffs, folder_results +
"predictedCoeffs.npy");
243 cnpy::save(exactCoeffs, folder_results +
"exactCoeffs.npy");
244 cnpy::save(relProjError, folder_results +
"relativeSmagProjError.npy");
Class that contains all parameters of the stochastic POD.
Implementation of a parametrized full order unsteady NS problem and preparation of the reduced matr...
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 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.
Eigen::VectorXd getCoeffs(GeometricField< Type, PatchField, GeoMesh > &snapshot, PtrList< GeometricField< Type, PatchField, GeoMesh > > &modes, label Nmodes, bool consider_volumes)
Projects a snapshot on a basis function and gets the coefficients of the projection.
PtrList< GeometricField< Type, PatchField, GeoMesh > > reconstructFromCoeff(PtrList< GeometricField< Type, PatchField, GeoMesh > > &modes, Eigen::MatrixXd &coeff_matrix, label Nmodes)
Exact reconstruction using a certain number of modes for a list of fields and the projection coeffici...
bool containsSubstring(std::string contain, std::string contained)
Returns true if contained is a substring of contain, false otherwise.
double errorL2Rel(GeometricField< T, fvPatchField, volMesh > &field1, GeometricField< T, fvPatchField, volMesh > &field2, List< label > *labels)
Computes the relative error between two geometric Fields in L2 norm.
Eigen::MatrixXd getMassMatrix(PtrList< GeometricField< Type, PatchField, GeoMesh > > &modes, label Nmodes, bool consider_volumes)
Gets the mass matrix using the eigen routine.