122 if (fieldToCompute.substr(0,HRInterpField.size()) == HRInterpField)
132 if (ECPAlgo ==
"Global")
134 string pathCentered =
"";
135 if (interpFieldCenteredOrNot) {pathCentered =
"_centered";}
136 snapshotsFolder =
"./ITHACAoutput/Hyperreduction/" + HRSnapshotsField.substr(0, HRSnapshotsField.find(
"_"))
137 +
"/Global" + pathCentered +
"/";
145 POD_nSnapshot = nTotalSnapshots;
147 POD_endTime = POD_startTime + POD_nSnapshot - 1;
151 snapshotsFolder =
"./ITHACAoutput/Hyperreduction/" + HRSnapshotsField.substr(0, HRSnapshotsField.find(
"_")) +
"/EachMode/";
156 word pathProcessor(
"");
157 if (Pstream::parRun())
159 pathProcessor =
"processor" + name(Pstream::myProcNo()) +
"/";
165 for (label j = 0; j < nTotalSnapshots ; j++)
169 +
"/" + fieldToCompute;
173 string pathCentered =
"";
174 if (interpFieldCenteredOrNot) {pathCentered =
"_centered";}
176 + pathCentered +
"/covMatrix" + fieldToCompute +
".npy")
178 exist_precomputed_fields = exist_precomputed_fields || exist_covMatrix;
180 if (!exist_precomputed_fields)
183 if (fieldToCompute == HRInterpField || fieldToCompute ==
"fullStressFunction" || fieldToCompute ==
"nut")
185 Info <<
"Evaluating " << fieldToCompute <<
" term" << endl;
188 if (fieldToCompute ==
"fullStressFunction"
195 else if(fieldToCompute ==
"nut")
205 Info <<
"Error : HRInterpolatedField not valid : " << HRInterpField << endl;
206 Info <<
"HR is available for fullStressFunction and nut only." << endl;
210 for (label j = offset_1; j < nTotalSnapshots; j++)
234 int currentModeU = 0;
240 if (ECPAlgo ==
"Global")
245 meanHRInterpField = meanRead[0];
251 currentModeU = intInFieldName[intInFieldName.size()-1]-1;
254 Info <<
"Evaluating " << fieldToCompute <<
" term" << endl;
258 for (label c = 0; c < nUsedModesU; c++)
260 if (ECPAlgo ==
"Global")
263 if (interpFieldCenteredOrNot)
271 for (label j = 0; j < nTotalSnapshots/nUsedModesU; j++)
287 std::vector<int> currentModesU;
293 PtrList<volVectorField> f_mean_and_spatialModesU(
f_spatialModesU.size() + 1);
298 f_mean_and_spatialModesU.set(0,
new volF(*
f_meanU));
300 if (ECPAlgo ==
"Global")
304 meanHRInterpField = meanRead[0];
311 Info <<
"Evaluating " << fieldToCompute <<
" term" << endl;
317 for (label k = 0; k <= c+1; k++)
319 if (ECPAlgo ==
"EachMode")
321 c = currentModesU[currentModesU.size()-2] - 1;
322 k = currentModesU[currentModesU.size()-1];
324 else if (ECPAlgo ==
"Global" && interpFieldCenteredOrNot)
327 ithacaUnsteadyNSTurb->computeProjSmagFromNut_fromNut_fromModes(meanECPModeck, meanHRInterpField,
335 + k*
l_nSnapshot)*(ECPAlgo==
"Global") + j)*saveTime);
341 *(ECPAlgo==
"Global") + j) / (nTotalSnapshots-1));
344 if (ECPAlgo ==
"EachMode")
356 Info <<
"Error : Unexpected field for precomputeNonPolynomialFunction : " << fieldToCompute << endl;
363 if (fieldToCompute == HRInterpField || fieldToCompute ==
"fullStressFunction" || fieldToCompute ==
"nut")
365 if (interpFieldCenteredOrNot)
370 Info <<
"Reading the mean of " << fieldToCompute <<
" field" << endl;
373 meanField = meanRead[0];
378 ithacaFVPOD_interp_field.set_b_centeredOrNot(1);
379 ithacaFVPOD_interp_field.computeMeanField();
380 meanField = ithacaFVPOD_interp_field.get_mean();
383 if (fieldToCompute ==
"fullStressFunction" || fieldToCompute ==
"nut")
403 word nameNotReduced = HRInterpField.substr(7, HRInterpField.find(
"_")-7);
404 nameNotReduced[0] = tolower(nameNotReduced[0]);
406 snapshotsFolder =
"./ITHACAoutput/Hyperreduction/" + HRInterpField.substr(0, HRInterpField.find(
"_")) +
"/";
412 std::vector<word> HRPODFields;
414 if (HRMethod ==
"DEIM")
416 HRPODFields.push_back(HRInterpField);
418 else if (HRMethod ==
"ECP")
420 word HRSnapshotsField_copy = HRSnapshotsField;
421 std::vector<word> HRFields_temp{std::begin(
m_parameters->get_field_name()),
423 HRFields_temp.erase(std::remove_if(HRFields_temp.begin(), HRFields_temp.end(),
424 [HRSnapshotsField_copy](
const word x) {return !ITHACAutilities::containsSubstring(x,HRSnapshotsField_copy);}),
425 HRFields_temp.end());
426 HRPODFields = HRFields_temp;
428 for (
auto fieldIterator: HRPODFields)
434 for (
auto fieldIterator: HRPODFields)
437 PtrList<S> f_subsetSpatialModesHR;
439 ithacaFVPOD_template_field.set_snapFolderParams(POD_nSnapshot,
l_nSnapshotSimulation,POD_startTime,POD_endTime);
440 ithacaFVPOD_template_field.set_b_centeredOrNot(interpFieldCenteredOrNot);
441 ithacaFVPOD_template_field.getModes(f_subsetSpatialModesHR, m_temporalModesHR,
442 m_temporalModesHRSimulation, covMatrixHR);
443 forAll(f_subsetSpatialModesHR, i){f_spatialModesHR.append(tmp<S>(f_subsetSpatialModesHR[i]));}
446 if (Pstream::parRun())
448 bool waitMaster =
false;
449 if (Pstream::master()){ waitMaster =
true; }
450 Pstream::scatter(waitMaster);
452 Info <<
"Hyperreduction POD done in parallel. Magic points selection must run sequentially. Aborting." << endl << endl;
459 Eigen::VectorXi initSeeds(0);
465 std::is_same<S, volScalarField>::value ? 1 : 3,
466 f_spatialModesHR[0].size(),
469 weights.array().square().matrix()));
472 List<Eigen::VectorXd> quadWeights(HRPODFields.size());
475 if (HRMethod ==
"DEIM")
480 else if (HRMethod ==
"ECP")
483 spatialModesHR = weights.asDiagonal() * spatialModesHR;
485 bool weightModesWithEigenval = 0;
487 if (weightModesWithEigenval)
489 for (
unsigned int c = 0; c < HRPODFields.size(); c++)
491 label nModesSubspace =
m_parameters->get_nModes()[HRInterpField];
492 Eigen::VectorXd eigenValuesModesHR;
493 std::string pathCentered =
"";
494 if (interpFieldCenteredOrNot){pathCentered =
"_centered";}
495 std::string folder_eigen =
"./ITHACAoutput/EigenValuesandVector" + pathCentered +
"_" +
496 std::to_string(nModesSubspace) +
"modes/";
497 std::string eigen_name =
"EigenvectorLambda_" + HRPODFields[c];
498 cnpy::load(eigenValuesModesHR, folder_eigen + eigen_name +
".npy");
499 spatialModesHR.middleCols(nModesSubspace*c, nModesSubspace).array().rowwise() *=
500 (eigenValuesModesHR.transpose()/eigenValuesModesHR(0)).array();
504 if (ECPAlgo ==
"Global")
513 else if (ECPAlgo ==
"EachMode")
515 List<Eigen::MatrixXd> listspatialModesHR(HRPODFields.size());
516 label nModesSubspace =
m_parameters->get_nModes()[HRInterpField];
517 for (
unsigned int c = 0; c < HRPODFields.size(); c++)
519 listspatialModesHR[c] = spatialModesHR.middleCols(nModesSubspace*c, nModesSubspace);
527 if (HRMethod ==
"DEIM")
531 double cond = svd.singularValues()(0) / svd.singularValues()(svd.singularValues().size() - 1);
532 Info <<
"Condition number of P^T U = " << cond << endl;
535 word folder_K_DEIM =
folder_HR +
"K_DEIM/";
536 mkDir(folder_K_DEIM);
548 Eigen::MatrixXd K_DEIM = spatialModesU.transpose() * P;
553 K_DEIM(c, 3*m) *= quadWeights[c][m];
554 K_DEIM(c, 3*m + 1) *= quadWeights[c][m];
555 K_DEIM(c, 3*m + 2) *= quadWeights[c][m];
558 cnpy::save(K_DEIM,
folder_HR +
"/K_DEIM.npy");
566 for (
unsigned int c = 0; c < HRPODFields.size(); c++)
568 K_DEIM.row(c) = (sparseWeights.array() * quadWeights[c].array()).matrix();
570 cnpy::save(K_DEIM,
folder_HR +
"/K_DEIM.npy");