31#ifndef hyperReduction_templates_H
32#define hyperReduction_templates_H
39template <
typename... SnapshotsLists>
44 SnapshotsLists &&...snapshotsLists)
52 Info <<
"Init HyperReduction class with vectorial dim: " <<
vectorial_dim <<
62 std::apply([
this](
auto & ...snapList)
68 std::apply([
this](
auto & ...snapList)
74 std::apply([
this](
auto & ...snapList)
79 Info <<
"Fields names: ";
81 for (
unsigned int ith_field = 0; ith_field <
fieldNames.size(); ith_field++)
88 Info <<
"The number of snapshots is: " <<
n_snapshots << endl;
90 Info <<
"The number of cells is: " <<
n_cells << endl;
91 Info <<
"Initial seeds length: " <<
initialSeeds.rows() << endl;
97 for (
unsigned int ith_boundary_patch = 0;
110template <
typename... SnapshotsLists>
113 unsigned int vectorialDim,
124 Info <<
"Init HyperReduction class with vectorial dim: " <<
vectorial_dim <<
129 Info <<
"Initial seeds length: " <<
initialSeeds.rows() << endl;
132template <
typename... SnapshotsLists>
135 Eigen::VectorXd& fieldWeights,
bool saveModesFlag)
139 word folderSVD =
"ITHACAoutput/" +
problemName +
"/ModesSVD/";
145 Eigen::MatrixXd snapMatrix;
147 word dimensionReductionMethod =
148 para->ITHACAdict->lookupOrDefault<word>(
"DimensionReductionMethod",
"SVD");
149 Eigen::MatrixXd eigenVectoreig;
151 if (dimensionReductionMethod ==
"RSVD")
153 Info <<
"####### Performing RSVD for " <<
problemName <<
" #######" << endl;
154 unsigned int r_modeSVD =
155 para->ITHACAdict->lookupOrDefault<
unsigned int>(
"RSVDdim", snapMatrix.cols());
156 RedSVD::RedSVD
svd(fieldWeights.array().cwiseInverse().matrix().asDiagonal() *
157 snapMatrix, r_modeSVD);
158 Info <<
"####### End of RSVD for " <<
problemName <<
" #######" <<
161 eigenVectoreig =
svd.matrixU().real();
165 Info <<
"####### Performing SVD for " <<
problemName <<
" #######" << endl;
166 Eigen::JacobiSVD<Eigen::MatrixXd>
svd(
167 fieldWeights.array().cwiseInverse().matrix().asDiagonal() * snapMatrix,
168 Eigen::ComputeThinU | Eigen::ComputeThinV);
169 Info <<
"####### End of SVD for " <<
problemName <<
" #######" <<
172 eigenVectoreig =
svd.matrixU().real();
175 modesSVD = eigenVectoreig;
178 "ITHACAoutput/" +
problemName +
"/ModesSVD/eigenvalues.npy");
182 for (label j = 1; j < cumEigenValues.size(); ++j)
184 cumEigenValues(j) += cumEigenValues(j - 1);
197 "ITHACAoutput/" +
problemName +
"/ModesSVD/normalizingWeights.npy");
201 unsigned int rowIndex{0};
203 for (
unsigned int modeIndex = 0; modeIndex < modesSVD.cols(); modeIndex++)
205 std::apply([
this, & modesSVD, & rowIndex, & modeIndex,
206 & folderSVD](
auto & ...snapList)
208 (...,
saveModes(snapList, modesSVD, rowIndex, modeIndex, folderSVD));
217 Info <<
"Reading the existing modes" << endl;
219 cnpy::load(fieldWeights, folderSVD +
"/normalizingWeights.npy");
223template <
typename... SnapshotsLists>
226 Eigen::VectorXd& fieldWeights, Eigen::MatrixXd& modesSVDBoundary,
227 Eigen::VectorXd& fieldWeightsBoundary,
bool saveModesFlag)
231 word folderSVD =
"ITHACAoutput/" +
problemName +
"/ModesSVD/";
237 Eigen::MatrixXd snapMatrix;
238 List<Eigen::MatrixXd> snapMatrixBoundary;
239 List<Eigen::VectorXd> fieldWeightsBoundaryList;
241 fieldWeightsBoundaryList);
245 snapMatrix.conservativeResize(snapMatrix.rows() + snapMatrixBoundary[
id].rows(),
247 snapMatrix.bottomRows(snapMatrixBoundary[
id].rows()) = snapMatrixBoundary[id];
248 fieldWeightsBoundary.conservativeResize(fieldWeightsBoundary.rows() +
249 snapMatrixBoundary[
id].rows());
250 fieldWeightsBoundary.tail(fieldWeightsBoundaryList[
id].rows()) =
251 fieldWeightsBoundaryList[id];
255 "ITHACAoutput/" + problemName +
"/ModesSVD/normalizingWeights.npy");
257 "ITHACAoutput/" + problemName +
"/ModesSVD/normalizingWeightsBoundary.npy");
258 fieldWeights.conservativeResize(fieldWeights.rows() +
259 fieldWeightsBoundary.rows());
260 fieldWeights.tail(fieldWeightsBoundary.rows()) = fieldWeightsBoundary;
261 word dimensionReductionMethod =
262 para->ITHACAdict->lookupOrDefault<word>(
"DimensionReductionMethod",
"SVD");
263 Eigen::MatrixXd eigenVectoreig;
265 if (dimensionReductionMethod ==
"RSVD")
267 Info <<
"####### Performing RSVD for " <<
problemName <<
" #######" << endl;
268 unsigned int r_modeSVD =
269 para->ITHACAdict->lookupOrDefault<
unsigned int>(
"RSVDdim", snapMatrix.cols());
270 RedSVD::RedSVD
svd(fieldWeights.array().cwiseInverse().matrix().asDiagonal() *
271 snapMatrix, r_modeSVD);
272 Info <<
"####### End of RSVD for " <<
problemName <<
" #######" << endl;
274 eigenVectoreig =
svd.matrixU().real();
278 Info <<
"####### Performing SVD for " << problemName <<
" #######" << endl;
279 Eigen::JacobiSVD<Eigen::MatrixXd>
svd(
280 fieldWeights.array().cwiseInverse().matrix().asDiagonal() * snapMatrix,
281 Eigen::ComputeThinU | Eigen::ComputeThinV);
282 Info <<
"####### End of SVD for " << problemName <<
" #######" <<
285 eigenVectoreig =
svd.matrixU().real();
288 modesSVD = eigenVectoreig.bottomRows(vectorial_dim * n_cells);
289 modesSVDBoundary = eigenVectoreig.topRows(n_boundary_cells);
290 fieldWeights.conservativeResize(fieldWeights.rows() -
291 fieldWeightsBoundary.rows());
297 for (label j = 1; j < cumEigenValues.size(); ++j)
299 cumEigenValues(j) += cumEigenValues(j - 1);
303 "ITHACAoutput/" + problemName +
"/ModesSVD/Eigenvalues_" + problemName,
312 "ITHACAoutput/" +
problemName +
"/ModesSVD/modesBoundary.npy");
316 unsigned int rowIndex{0};
317 unsigned int rowIndexBoundary{0};
319 for (
unsigned int modeIndex = 0; modeIndex < modesSVD.cols(); modeIndex++)
321 std::apply([
this, & modesSVD, & modesSVDBoundary, & rowIndex, & modeIndex,
322 & rowIndexBoundary, & folderSVD](
auto & ...snapList)
324 (...,
saveModes(snapList, modesSVD, modesSVDBoundary, rowIndex,
325 rowIndexBoundary, modeIndex, folderSVD));
334 Info <<
"Reading the existing modes" << endl;
335 cnpy::load(modesSVD, folderSVD +
"/modes.npy");
337 "ITHACAoutput/" + problemName +
"/ModesSVD/modesBoundary.npy");
338 cnpy::load(fieldWeights, folderSVD +
"/normalizingWeights.npy");
340 "ITHACAoutput/" + problemName +
"/ModesSVD/normalizingWeightsBoundary.npy");
344template <
typename... SnapshotsLists>
346 snapMatrix, Eigen::VectorXd& fieldWeights)
348 std::apply([
this, & fieldWeights, & snapMatrix](
auto & ...snapList)
354template <
typename... SnapshotsLists>
356 snapMatrix, Eigen::VectorXd& fieldWeights,
357 List<Eigen::MatrixXd>& snapMatrixBoundary,
358 List<Eigen::VectorXd>& fieldWeightsBoundary)
362 std::apply([
this, & fieldWeights, & snapMatrix, & fieldWeightsBoundary,
363 & snapMatrixBoundary](
auto & ...snapList)
367 fieldWeightsBoundary));
373template <
typename... SnapshotsLists>
374template <
typename SnapshotsList>
376 Eigen::MatrixXd& snapshotsMatrix,
unsigned int& rowIndex,
377 unsigned int& modeIndex, word folder)
380 auto fieldName = sList[0].name();
381 unsigned int fieldSize = field_dim * sList[0].size();
382 Eigen::VectorXd fieldBlock = snapshotsMatrix.block(rowIndex, modeIndex,
385 rowIndex += fieldSize;
389template <
typename... SnapshotsLists>
390template <
typename SnapshotsList>
392 Eigen::MatrixXd& snapshotsMatrix, Eigen::MatrixXd& snapshotsMatrixBoundary,
393 unsigned int& rowIndex,
unsigned int& rowIndexBoundary,
394 unsigned int& modeIndex, word folder)
397 auto fieldName = sList[0].name();
398 unsigned int fieldSize = field_dim * sList[0].size();
399 Eigen::VectorXd fieldBlock = snapshotsMatrix.block(rowIndex, modeIndex,
401 List<Eigen::VectorXd> fieldBlockBoundary;
407 fieldBlockBoundary[id] = snapshotsMatrixBoundary.block(rowIndexBoundary,
408 modeIndex, bfieldDim, 1);
409 rowIndexBoundary += bfieldDim;
414 rowIndex += fieldSize;
418template <
typename... SnapshotsLists>
420 Eigen::MatrixXd& snapshotsModes, Eigen::VectorXd& weights,
421 word folderMethodName)
427 nodePoints = autoPtr<IOList<label >> (
new IOList<label>(
428 IOobject(
"nodePoints",
para->runTime.time().constant(),
"../" +
folderMethod,
429 para->mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE)));
430 auto greedyMetric =
para->ITHACAdict->lookupOrDefault<word>(
"GreedyMetric",
440 std::set<label> nodePointsSet;
452 Eigen::SparseMatrix<double> reshapeMat;
455 if (greedyMetric ==
"L2")
457 Info <<
"####### Begin Greedy-L2 GappyDEIM #######" << endl;
458 Info <<
"####### Modes=" <<
n_modes
459 <<
", nodePoints=" <<
n_nodes <<
" #######"
462 int nit = std::min(
n_modes, na);
463 int ncimin = std::floor(
n_modes / nit);
464 int naimin = std::floor(na /
n_modes);
472 for (
int i = 1;
i <= nit;
i++)
495 V = snapshotsModes.leftCols(nci);
499 for (
int q = 1; q <= nci; q++)
502 b =
P.transpose() * snapshotsModes.col(nb + q - 1);
503 c =
A.fullPivLu().solve(b);
504 r = snapshotsModes.col(nb + q - 1) -
basisMatrix * c;
505 V.conservativeResize(snapshotsModes.rows(), q);
510 for (
int j = 1; j <= nai; j++)
514 max = (reshapeMat * (mp_not_mask.asDiagonal() * V)
516 .lpNorm<2>().array().square().matrix())
517 .maxCoeff(& ind_max, & c1);
521 max = (reshapeMat * V.rowwise().lpNorm<2>().array().square().matrix()).maxCoeff(
525 updateNodes(P, ind_max, mp_not_mask);
529 basisMatrix = snapshotsModes.leftCols(nb);
532 Info <<
"####### End of greedy GappyDEIM #######\n";
534 else if (greedyMetric ==
"SOPT")
536 Info <<
"####### Begin SOPT GappyDEIM #######" << endl;
537 Info <<
"####### Modes=" << n_modes
538 <<
", nodePoints=" << n_nodes <<
" #######"
542 Eigen::MatrixXd V = snapshotsModes.leftCols(n_modes);
544 for (
unsigned int ith_node = 0; ith_node < na; ith_node++)
549 Eigen::MatrixXd tmp = P.transpose() * V;
550 Eigen::MatrixXd R = mp_not_mask.asDiagonal() * V;
551 Eigen::MatrixXd inv = (tmp.transpose() * tmp).fullPivLu().inverse();
552 Eigen::VectorXd num = 1 + (reshapeMat * ((R * inv).array() *
553 R.array()).rowwise().sum().matrix()).array();
554 Eigen::VectorXd norma = (tmp.array().square()).colwise().sum();
555 Eigen::MatrixXd adding = reshapeMat * R.array().square().matrix();
556 adding.rowwise() += norma.transpose();
557 Eigen::VectorXd denom = (adding.array().pow(1. /
558 V.cols()).matrix()).rowwise().prod();
559 max = ((mp_not_mask.head(n_cells).asDiagonal() * num).array() /
560 denom.array()).maxCoeff(& ind_max, & c1);
564 max = (reshapeMat * V.rowwise().lpNorm<2>().array().square().matrix()).maxCoeff(
568 updateNodes(P, ind_max, mp_not_mask);
572 Info <<
"####### End of SOPT GappyDEIM #######\n";
574 else if (greedyMetric ==
"SOPTE")
576 Info <<
"####### Begin SOPT-exact GappyDEIM #######" << endl;
577 Info <<
"####### Modes=" << n_modes
578 <<
", nodePoints=" << n_nodes <<
" #######"
586 Eigen::MatrixXd V = snapshotsModes.col(0);
587 max = (reshapeMat * (mp_not_mask.asDiagonal() * snapshotsModes.leftCols(
588 n_modes)).rowwise().lpNorm<2>().array().square().matrix()).maxCoeff(& ind_max,
590 updateNodes(P, ind_max, mp_not_mask);
592 for (
unsigned int ith_node = 1; ith_node < na; ith_node++)
594 if (ith_node < n_modes)
596 A = P.transpose() * V;
597 b = P.transpose() * snapshotsModes.col(ith_node);
598 c =
A.fullPivLu().solve(b);
599 r = snapshotsModes.col(ith_node) - V * c;
600 V.conservativeResize(snapshotsModes.rows(), ith_node + 1);
601 V.col(ith_node) = snapshotsModes.col(ith_node);
602 max = (reshapeMat * r.rowwise().lpNorm<2>().array().square().matrix()).maxCoeff(
608 Eigen::MatrixXd tmp = P.transpose() * snapshotsModes.leftCols(n_modes);
609 Info <<
"SOPT: " << s_optimality(tmp) << endl;
610 tmp.conservativeResize(tmp.rows() + vectorial_dim, tmp.cols());
611 Eigen::MatrixXd masked = mp_not_mask.asDiagonal() * snapshotsModes.leftCols(
613 Eigen::VectorXd results(n_cells);
615 for (
unsigned int ith_cell = 0; ith_cell < n_cells; ith_cell++)
617 for (
unsigned int ith_field = 0; ith_field < vectorial_dim; ith_field++)
619 tmp.row(tmp.rows() - vectorial_dim + ith_field) = masked.row(
620 ith_cell + ith_field * n_cells);
623 results(ith_cell) = s_optimality(tmp);
626 max = results.maxCoeff(& ind_max, & c1);
629 updateNodes(P, ind_max, mp_not_mask);
632 basisMatrix = snapshotsModes.leftCols(n_modes);
633 Info <<
"####### End of SOPTE GappyDEIM #######\n";
638 basisMatrix = snapshotsModes.leftCols(n_modes);
639 Info <<
"####### InitialSeeds equal to n_nodes #######\n";
642 evaluatePinv(P, basisMatrix, normalizingWeights);
643 renormalizedBasisMatrix = normalizingWeights.asDiagonal() * basisMatrix;
644 MatrixOnline = renormalizedBasisMatrix * pinvPU;
646 cnpy::save(basisMatrix, folderMethod +
"/basisMatrix.npy");
647 cnpy::save(P, folderMethod +
"/projectionMatrix.npz");
648 cnpy::save(normalizingWeights, folderMethod +
"/normalizingWeights.npy");
650 cnpy::save(pinvPU, folderMethod +
"/pinvPU.npy");
651 cnpy::save(MatrixOnline, folderMethod +
"/MatrixOnline.npy");
652 nodePoints().write();
653 Info <<
"Projection Matrix shape: " << P.rows() <<
" " << P.cols() << endl;
654 Info <<
"Basis Matrix shape: " << basisMatrix.rows() <<
" " <<
655 basisMatrix.cols() << endl;
656 Info <<
"Pseudo Inverse Matrix shape: " << pinvPU.rows() <<
" " << pinvPU.cols()
661 Info <<
"Read GappyDEIM\n";
662 cnpy::load(basisMatrix, folderMethod +
"/basisMatrix.npy");
663 cnpy::load(MatrixOnline, folderMethod +
"/MatrixOnline.npy");
664 cnpy::load(normalizingWeights, folderMethod +
"/normalizingWeights.npy");
665 cnpy::load(P, folderMethod +
"/projectionMatrix.npz");
667 cnpy::load(pinvPU, folderMethod +
"/pinvPU.npy");
668 renormalizedBasisMatrix = normalizingWeights.asDiagonal() * basisMatrix;
669 Info <<
"Projection Matrix shape: " << P.rows() <<
" " << P.cols() << endl;
670 Info <<
"Basis Matrix shape: " << basisMatrix.rows() <<
" " <<
671 basisMatrix.cols() << endl;
672 Info <<
"Pseudo Inverse Matrix shape: " << pinvPU.rows() <<
" " << pinvPU.cols()
677template <
typename... SnapshotsLists>
679 snapshotsModes, Eigen::VectorXd& weights, word folderMethodName)
686 Info <<
"####### Begin ECP #######" << endl;
687 Info <<
"####### Modes=" <<
n_modes
688 <<
", nodePoints=" <<
n_nodes <<
" #######"
690 nodePoints = autoPtr<IOList<label >> (
new IOList<label>(
691 IOobject(
"nodePoints",
para->runTime.time().constant(),
"../" +
folderMethod,
692 para->mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE)));
708 double volume = volumes.array().sum();
710 for (
unsigned int ith_field = 0; ith_field <
vectorial_dim; ith_field++)
712 Eigen::MatrixXd block = snapshotsModes.block(ith_field *
n_cells, 0,
n_cells,
714 q.segment(ith_field * (
n_modes + 1),
n_modes) = block.rowwise().sum();
717 Jwhole.row(ith_field * (
n_modes + 1) +
n_modes) = Eigen::VectorXd::Constant(
719 Eigen::VectorXd mean = block.rowwise().mean();
720 block.colwise() -= mean;
721 Eigen::VectorXd Anorm = block.colwise().lpNorm<2>();
723 if (Anorm.minCoeff() > 0)
725 block.array().rowwise() /= Anorm.transpose().array();
733 std::set<label> nodePointsSet;
743 Eigen::SparseMatrix<double> reshapeMat;
751 for (
unsigned int ith_node = 0; ith_node < na; ith_node++)
753 max = ((b.transpose() *
A * mp_not_mask.head(
754 n_cells).asDiagonal()).colwise().sum()).maxCoeff(& r1, & ind_max);
760 Info <<
"####### End ECP #######" << endl;
772 Info <<
"Read ECP\n";
781template<
typename... SnapshotsLists>
783 std::set<label> nodePointsSet)
788 unsigned int trueSeeds{0};
795 if (nodePointsSet.find(index) == nodePointsSet.end())
797 nodePointsSet.insert(index);
800 for (
unsigned int ith_field = 0; ith_field <
vectorial_dim; ith_field++)
802 P.insert(index + ith_field *
n_cells,
804 mp_not_mask(index + ith_field *
n_cells) = 0;
814 "Size of 'initialSeeds' is greater than 'n_nodes'");
817template <
typename... SnapshotsLists>
819 &
P, label& ind, Eigen::VectorXd& mp_not_mask)
824 unsigned int last_col{0};
838 for (
int ith_node = 0; ith_node <= step; ith_node++)
840 for (
unsigned int ith_field = 0; ith_field <
vectorial_dim; ith_field++)
843 ith_node + ith_field * (step + 1)) = 1;
847 for (
unsigned int ith_field = 0; ith_field <
vectorial_dim; ith_field++)
849 mp_not_mask(ind + ith_field *
n_cells) = 0;
853template<
typename... SnapshotsLists>
855 Eigen::MatrixXd& Jwhole, Eigen::VectorXd& b, Eigen::VectorXd& q)
859 J = Jwhole(Eigen::indexing::all,
nodes);
862 for (
unsigned int ith_field = 0; ith_field <
vectorial_dim; ith_field++)
866 n_modes + 1).colPivHouseholderQr().solve(q.segment(ith_field * (
n_modes + 1),
874 b = b / b.lpNorm<2>();
877template<
typename... SnapshotsLists>
879 Eigen::SparseMatrix<double>& reshapeMat)
887 for (
unsigned int ith_field = 0; ith_field <
vectorial_dim; ith_field++)
889 reshapeMat.insert(
i,
i +
n_cells * ith_field) = 1;
893 reshapeMat.makeCompressed();
896template <
typename... SnapshotsLists>
897template <
typename SnapshotsList>
899 Eigen::MatrixXd& snapshotsMatrix, Eigen::VectorXd& fieldWeights)
905 double maxVal = std::sqrt(tmpSnapshots.colwise().lpNorm<2>().maxCoeff());
906 fieldWeights.conservativeResize(fieldWeights.rows() + field_dim *
n_cells);
907 fieldWeights.tail(
n_cells * field_dim) = V.array().sqrt().cwiseInverse() *
909 snapshotsMatrix.conservativeResize(snapshotsMatrix.rows() +
n_cells * field_dim,
911 snapshotsMatrix.bottomRows(
n_cells * field_dim) = tmpSnapshots;
914template <
typename... SnapshotsLists>
915template <
typename SnapshotsList>
917 SnapshotsList sList, List<Eigen::MatrixXd>& snapshotsMatrixBoundary,
918 List<Eigen::VectorXd>& fieldWeightsBoundary)
927 maxVal[id] = std::sqrt(
928 tmpBoundarySnapshots[
id].colwise().lpNorm<2>().maxCoeff());
931 sList[0].
mesh().magSf().boundaryField()[
id]);
932 S =
S.replicate(field_dim, 1);
934 fieldWeightsBoundary[id].conservativeResize(fieldWeightsBoundary[
id].rows() +
936 fieldWeightsBoundary[id].tail(bSize) =
S.array().pow(3 / 4) * maxVal[id];
937 snapshotsMatrixBoundary[id].conservativeResize(
938 snapshotsMatrixBoundary[
id].rows() + bSize,
n_snapshots);
939 snapshotsMatrixBoundary[id].bottomRows(bSize) = tmpBoundarySnapshots[id];
943template<
typename... SnapshotsLists>
945 & Projector, Eigen::MatrixXd&
Modes, Eigen::VectorXd& fieldWeights)
947 assert(Projector.cols() > 0);
948 Eigen::MatrixXd restricted = Projector.transpose() *
Modes;
949 Info <<
"S-Optimalty: " <<
s_optimality(restricted) << endl;
951 para->ITHACAdict->lookupOrDefault<word>(
"InversionMethod",
952 "completeOrthogonalDecomposition"));
954 fieldWeights.array().cwiseInverse().matrix()).asDiagonal();
957template<
typename... SnapshotsLists>
959 & Projector, Eigen::MatrixXd&
Modes, Eigen::VectorXd& fieldWeights,
962 assert(Projector.cols() > 0);
965 unsigned int reorderIndex{0};
967 for (
unsigned int ith_field = 0; ith_field <
vectorial_dim; ith_field++)
969 for (
unsigned int ith_weight = 0; ith_weight < n_weightsPerField; ith_weight++)
972 ith_weight + ith_field * n_weightsPerField);
977 wPU = quadratureWeightsOrderedAsProjector.transpose() *
978 (Projector.transpose() *
979 fieldWeights.array().cwiseInverse().matrix()).asDiagonal();
982template<
typename... SnapshotsLists>
986 Info <<
"####### Extract submesh #######\n";
988 totalNodePoints = autoPtr<IOList<labelList >> (
new IOList<labelList>(IOobject(
990 para->mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE)));
993 para->mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE)));
994 volScalarField Indici
999 mesh.time().timeName(),
1006 dimensionSet(0, 0, 0, 0, 0, 0, 0), 0.0));
1007 submesh = autoPtr<fvMeshSubset>(
new fvMeshSubset(
mesh));
1012 List<label> indices;
1021 accessOp<labelList>());
1022 inplaceUniqueSort(a);
1024 scalar zerodot25 = 0.25;
1033 submesh->subMesh().fvSchemes::readOpt() =
mesh.fvSchemes::readOpt();
1034 submesh->subMesh().fvSolution::readOpt() =
mesh.fvSolution::readOpt();
1035 submesh->subMesh().fvSchemes::read();
1036 submesh->subMesh().fvSolution::read();
1043 Info <<
"####### End create masks #######\n";
1046template<
typename... SnapshotsLists>
1055 for (
unsigned int ith_subCell{0} ; ith_subCell <
submesh().cellMap().size();
1058 for (
unsigned int ith_field = 0; ith_field <
vectorial_dim; ith_field++)
1073 for (
unsigned int ith_node{0} ; ith_node <
nodePoints().size(); ith_node++)
1075 for (
unsigned int ith_subCell{0} ; ith_subCell <
submesh().cellMap().size();
1080 for (
unsigned int ith_field = 0; ith_field <
vectorial_dim; ith_field++)
1083 index_col + ith_field *
submesh().cellMap().size()) = 1;
1085 ith_field *
submesh().cellMap().size();
1112template<
typename... SnapshotsLists>
1114 List<label>& points, fvMeshSubset&
submesh)
1116 List<label> localPoints;
1118 for (label
i = 0;
i < points.size();
i++)
1120 for (label j = 0; j <
submesh.cellMap().size(); j++)
1122 if (
submesh.cellMap()[j] == points[
i])
1124 localPoints.append(j);
#define M_Assert(Expr, Msg)
static GeometricField< scalar, PatchField, GeoMesh > Eigen2field(GeometricField< scalar, PatchField, GeoMesh > &field, Eigen::VectorXd &eigen_vector, bool correctBC=true)
Convert a vector in Eigen format into an OpenFOAM scalar GeometricField.
static Eigen::VectorXd field2Eigen(GeometricField< tensor, PatchField, GeoMesh > &field)
Convert a vector OpenFOAM field into an Eigen Vector.
static List< Eigen::MatrixXd > PtrList2EigenBC(PtrList< GeometricField< scalar, PatchField, GeoMesh > > &fields, label Nfields=-1)
Convert an OpenFOAM scalar field to a List of Eigen Vectors, one for each boundary.
static Eigen::MatrixXd PtrList2Eigen(PtrList< GeometricField< Type, PatchField, GeoMesh > > &fields, label Nfields=-1)
Convert a PtrList of snapshots to Eigen matrix (only internal field)
Eigen::VectorXi submesh2nodesMask
void stackSnapshotsBoundary(SnapshotsList sList, List< Eigen::MatrixXd > &snapshotsMatrixBoundary, List< Eigen::VectorXd > &fieldWeightsBoundary)
SnapshotsListTuple snapshotsListTuple
The snapshots matrix containing the nonlinear function or operator.
label n_modes
The maximum number of modes to be considered.
void evaluateWPU(Eigen::SparseMatrix< double > &Projector, Eigen::MatrixXd &Modes, Eigen::VectorXd &fieldWeights, Eigen::VectorXd &quadratureWeights)
Compute the pseudo-inverse of the matrix M restricted with the projector P.
label n_nodes
The maximum number of modes to be considered.
word folderMethod
Folder for the selected HR method.
void stackNames(SnapshotsList sList)
TODO.
void generateSubmesh(label layers, const fvMesh &mesh)
Compute the submesh common to all fields in SnapshotsLists.
autoPtr< fvMeshSubset > submesh
Submesh of the HyperReduction method.
List< label > n_boundary_cells_list
void offlineGappyDEIM(Eigen::MatrixXd &snapshotsModes, Eigen::VectorXd &normalizingWeights)
Methods implemented: 'GappyDEIM' from "DEIM, Chaturantabut, Saifon, and Danny C. Sorensen....
void updateNodes(Eigen::SparseMatrix< double > &P, label &ind_max, Eigen::VectorXd &mp_not_mask)
TODO.
unsigned int sumFieldsDim
void evaluatePinv(Eigen::SparseMatrix< double > &Projector, Eigen::MatrixXd &Modes, Eigen::VectorXd &fieldWeights)
Compute the pseudo-inverse of the matrix M restricted with the projector P.
Eigen::VectorXd quadratureWeights
Quadrature weights. Ordered in the same order of matrix P.
autoPtr< IOList< labelList > > totalNodePoints
List of label lists of the nodes and corresponding surrounding nodes.
void sumDimensions(double sum, SnapshotsList sList)
TODO.
List< label > global2local(List< label > &points, fvMeshSubset &submesh)
Get local indices in the submesh from indices in the global ones.
Eigen::SparseMatrix< double > submesh2nodes
void stackDimensions(SnapshotsList sList)
TODO.
constexpr unsigned int compute_vectorial_dim(LastList x)
TODO.
void getSnapMatrix(Eigen::MatrixXd &snapMatrix, Eigen::VectorXd &fieldWeights)
TODO.
Eigen::VectorXi initialSeeds
List< label > localNodePoints
Indices of the local node points in the subMesh.
constexpr unsigned int get_field_dim()
Eigen::VectorXd normalizingWeights
void offlineECP(Eigen::MatrixXd &snapshotsModes, Eigen::VectorXd &normalizingWeights)
Methods implemented: 'ECP' from "ECP, Hernandez, Joaquin Alberto, Manuel Alejandro Caicedo,...
word problemName
The name of the non-linear function e.g. HR_method/residual.
HyperReduction(label n_modes, label n_nodes, Eigen::VectorXi initialSeeds, word problemName, SnapshotsLists &&...snapshotsLists)
Construct HyperReduction class, interpolation-based.
std::tuple< std::decay_t< SnapshotsLists >... > SnapshotsListTuple
Eigen::VectorXd eigenValueseig
Eigen::SparseMatrix< double > P
unsigned int vectorial_dim
label n_cells
Int Number of Cells;.
void initReshapeMat(Eigen::SparseMatrix< double > &reshapeMat)
TODO.
void initSeeds(Eigen::VectorXd mp_not_mask, std::set< label > nodePointsSet)
TODO.
autoPtr< IOList< label > > nodePoints
Nodes in the case of the a nonlinear function.
static double s_optimality(Eigen::MatrixXd &A)
TODO.
void getModesSVD(SnapshotsListTuple &SnapshotsListTuple, Eigen::MatrixXd &modesSVD, Eigen::VectorXd &fieldWeights, bool saveModesFlag=false)
TODO.
label n_snapshots
The length of the snapshots lists.
autoPtr< IOList< label > > uniqueNodePoints
List of the unique indices of the nodes that define the submesh.
Eigen::SparseMatrix< double > field2submesh
List< unsigned int > fieldDims
void saveModes(SnapshotsList sList, Eigen::MatrixXd &snapshotsMatrix, unsigned int &rowIndex, unsigned int &modeIndex, word folder)
TODO.
word folderProblem
Folder for the HR problem.
void stackSnapshots(SnapshotsList sList, Eigen::MatrixXd &snapshotsMatrix, Eigen::VectorXd &fieldWeights)
TODO.
Eigen::MatrixXd basisMatrix
label n_cellsSubfields
Int Number of Cells in submeshes;.
void createMasks(bool offlineStage=true)
TODO.
void computeLS(Eigen::MatrixXd &J, Eigen::MatrixXd &JWhole, Eigen::VectorXd &b, Eigen::VectorXd &q)
TODO.
Class for the definition of some general parameters, the parameters must be defined from the file ITH...
static ITHACAparameters * getInstance(fvMesh &mesh, Time &localTime)
Gets an instance of ITHACAparameters, to be used if the instance is not existing.
static ITHACAparameters * getInstance()
Gets an instance of ITHACAparameters, to be used if the instance is already existing.
Implementation of a container class derived from PtrList.
T max(Eigen::SparseMatrix< T > &mat, label &ind_row, label &ind_col)
Find the maximum of a sparse Matrix (Useful for DEIM)
bool saveMarketVector(const VectorType &vec, const std::string &filename, label prec, std::_Ios_Fmtflags outytpe=std::ios_base::scientific)
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 assignIF(GeometricField< Type, fvPatchField, volMesh > &s, Type value)
Assign internal field.
List< label > getIndices(const fvMesh &mesh, int index, int layers)
Gets the indices of the cells around a certain cell.
Eigen::MatrixXd invertMatrix(Eigen::MatrixXd &matrixToInvert, const word inversionMethod)
Invert a matrix given the method name in the ITHACAdict.
void assignONE(volScalarField &s, List< label > &L)
Assign one to volScalarField.
Eigen::VectorXd getMassMatrixFV(GeometricField< Type, PatchField, GeoMesh > &snapshot)
Gets a vector containing the volumes of each cell of the mesh.
bool check_folder(word folder)
Checks if a folder exists.
void save(const Eigen::Matrix< T, -1, dim > &mat, const std::string fname)
Eigen::Matrix< T, -1, dim > load(Eigen::Matrix< T, -1, dim > &mat, const std::string fname)
Info<< endl;Info<< "*********************************************************"<< endl;Info<< "Performing test for the parameterized BC inverse solver"<< endl;Info<< endl;word outputFolder="./ITHACAoutput/parameterizedBCtest_RBFparameter/";volScalarField gTrueField=example_paramBC.list2Field(example_paramBC.gTrue);ITHACAstream::exportSolution(gTrueField, "1", outputFolder, "gTrue");Eigen::VectorXd rbfWidth=EigenFunctions::ExpSpaced(0.001, 100, rbfWidthTest_size);ITHACAstream::exportMatrix(rbfWidth, "rbfShapeParameters", "eigen", outputFolder);Eigen::VectorXd residualNorms;residualNorms.resize(rbfWidthTest_size);Eigen::VectorXd heatFluxL2norm(rbfWidthTest_size);Eigen::VectorXd heatFluxLinfNorm=heatFluxL2norm;Eigen::VectorXd condNumber=heatFluxL2norm;Eigen::MatrixXd singVal;for(int i=0;i< rbfWidthTest_size;i++){ Info<< "*********************************************************"<< endl;Info<< "RBF parameter "<< rbfWidth(i)<< endl;Info<< "Test "<< i+1<< endl;Info<< endl;example_paramBC.set_gParametrized("rbf", rbfWidth(i));example_paramBC.parameterizedBCoffline(1);example_paramBC.parameterizedBC("fullPivLU");volScalarField gParametrizedField=example_paramBC.list2Field(example_paramBC.g);ITHACAstream::exportSolution(gParametrizedField, std::to_string(i+1), outputFolder, "gParametrized");volScalarField &T(example_paramBC._T());ITHACAstream::exportSolution(T, std::to_string(i+1), outputFolder, "T");residualNorms(i)=Foam::sqrt(example_paramBC.residual.squaredNorm());Eigen::MatrixXd A=example_paramBC.Theta.transpose() *example_paramBC.Theta;Eigen::JacobiSVD< Eigen::MatrixXd > svd(A, Eigen::ComputeThinU|Eigen::ComputeThinV)
volScalarField S(IOobject("S", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE), T.mesh(), dimensionedScalar("zero", dimensionSet(0, 0, -1, 1, 0, 0, 0), 0))