Loading...
Searching...
No Matches
TurbDiffusionHyperreduction.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ██╗████████╗██╗ ██╗ █████╗ ██████╗ █████╗ ███████╗██╗ ██╗
3 ██║╚══██╔══╝██║ ██║██╔══██╗██╔════╝██╔══██╗ ██╔════╝██║ ██║
4 ██║ ██║ ███████║███████║██║ ███████║█████╗█████╗ ██║ ██║
5 ██║ ██║ ██╔══██║██╔══██║██║ ██╔══██║╚════╝██╔══╝ ╚██╗ ██╔╝
6 ██║ ██║ ██║ ██║██║ ██║╚██████╗██║ ██║ ██║ ╚████╔╝
7 ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚═══╝
8
9 * In real Time Highly Advanced Computational Applications for Finite Volumes
10 * Copyright (C) 2017 by the ITHACA-FV authors
11-------------------------------------------------------------------------------
12
13 License
14 This file is part of ITHACA-FV
15
16 ITHACA-FV is free software: you can redistribute it and/or modify
17 it under the terms of the GNU Lesser General Public License as published by
18 the Free Software Foundation, either version 3 of the License, or
19 (at your option) any later version.
20
21 ITHACA-FV is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU Lesser General Public License for more details.
25
26 You should have received a copy of the GNU Lesser General Public License
27 along with ITHACA-FV. If not, see <http://www.gnu.org/licenses/>.
28
29\*---------------------------------------------------------------------------*/
30
32
35
36
37
38template<typename volF, typename T, typename S>
41 S& template_HRSnapshotsField, volF*& meanU, PtrList<volF>& spatialModesU):
42 m_parameters(static_cast<StoredParameters*>(myParameters)),
44 l_nSnapshot(m_parameters->get_nSnapshots()),
45 l_startTime(m_parameters->get_startTime()),
46 l_nSnapshotSimulation(m_parameters->get_nSnapshotsSimulation()),
49 f_spatialModesU(spatialModesU),
50 f_meanU(meanU),
51 folder_HR(m_parameters->get_folder_DEIM()),
52 runTime2(Foam::Time::controlDictName, ".", m_parameters->get_casenameData()),
53 snapshotsFolder(m_parameters->get_casenameData()),
55 HRMethod(m_parameters->get_HRMethod()),
56 HRInterpField(m_parameters->get_DEIMInterpolatedField()),
57 HRSnapshotsField(m_parameters->get_HRSnapshotsField()),
58 ECPAlgo(m_parameters->get_ECPAlgo()),
59 interpFieldCenteredOrNot(m_parameters->get_interpFieldCenteredOrNot())
60{
61 //
62}
63
64
65
66template<typename volF, typename T, typename S>
71
72
73template<typename volF, typename T, typename S>
74template<typename volGradF>
76{
77 int nModesU = f_spatialModesU.size();
78 PtrList<volGradF> defTensorOfModesOnMgPointsORMgNeighborhoods;
79 defTensorOfModesOnMgPointsORMgNeighborhoods.setSize(nModesU + 1);
80
81 volGradF temp = ithacaHyperreduction->interpolateField(tensorMeanU);
82 defTensorOfModesOnMgPointsORMgNeighborhoods.set(0, new volGradF(temp));
83
84 for (int c=0 ; c<nModesU ; c++)
85 {
86 volGradF defTensorMode(UnsteadyNSTurb::computeS_fromU(f_spatialModesU[c]));
87 volGradF temp = ithacaHyperreduction->interpolateField(defTensorMode);
88 defTensorOfModesOnMgPointsORMgNeighborhoods.set(c+1, new volGradF(temp));
89 }
91 {
92 m_parameters->set_deformationTensorOfModesOnMagicPoints(defTensorOfModesOnMgPointsORMgNeighborhoods);
93 }
94 else
95 {
96 m_parameters->set_deformationTensorOfModesOnMagicNeighborhoods(defTensorOfModesOnMgPointsORMgNeighborhoods);
97 }
98}
99
100template<typename volF, typename T, typename S>
102{
104 if (interpFieldCenteredOrNot)
105 {
106 PtrList<T> meanRead;
107 ITHACAstream::read_fields(meanRead, HRInterpField, "./ITHACAoutput/mean/");
108 meanHR = meanRead[0];
109 }
110 else
111 {
113 }
114 T meanHRMagic = ithacaHyperreduction->interpolateField(meanHR);
115 m_parameters->set_meanDEIMMagic(meanHRMagic);
116}
117
118template<typename volF, typename T, typename S>
120{
121 label nTotalSnapshots = l_nSnapshot;
122 if (fieldToCompute.substr(0,HRInterpField.size()) == HRInterpField)
123 {
124 nTotalSnapshots += (l_nSnapshotSimulation-1);
125 }
126
127 double startingTime = std::stod(runTime2.times()[l_startTime].name());
128 double saveTime = m_parameters->get_saveTime();
129
130 if (HRMethod == "ECP" && ITHACAutilities::containsSubstring(fieldToCompute, HRSnapshotsField))
131 {
132 if (ECPAlgo == "Global")
133 {
134 string pathCentered = "";
135 if (interpFieldCenteredOrNot) {pathCentered = "_centered";}
136 snapshotsFolder = "./ITHACAoutput/Hyperreduction/" + HRSnapshotsField.substr(0, HRSnapshotsField.find("_"))
137 + "/Global" + pathCentered + "/";
138 nTotalSnapshots = f_spatialModesU.size()*(l_nSnapshot);
139 if (HRInterpField == "nut" || ITHACAutilities::containsSubstring(HRInterpField, "reducedNut"))
140 {
141 nTotalSnapshots = (f_spatialModesU.size()*(f_spatialModesU.size() + 1)/2 + f_spatialModesU.size()) * l_nSnapshot;
142 }
143 startingTime = 1;
144 saveTime = 1;
145 POD_nSnapshot = nTotalSnapshots;
146 POD_startTime = 2; // Subfolders indices are 0:constant, 1:0, 2:1
147 POD_endTime = POD_startTime + POD_nSnapshot - 1;
148 }
149 else
150 {
151 snapshotsFolder = "./ITHACAoutput/Hyperreduction/" + HRSnapshotsField.substr(0, HRSnapshotsField.find("_")) + "/EachMode/";
152 }
154 }
155
156 word pathProcessor("");
157 if (Pstream::parRun())
158 {
159 pathProcessor = "processor" + name(Pstream::myProcNo()) + "/";
160 }
161
162 string local_file = snapshotsFolder + pathProcessor + runTime2.times()[1].name() + "/" + fieldToCompute;
163 bool exist_precomputed_fields = ITHACAutilities::check_file(local_file);
164
165 for (label j = 0; j < nTotalSnapshots ; j++)
166 {
167 // Read the j-th field
168 local_file = snapshotsFolder + pathProcessor + ITHACAutilities::double2ConciseString(startingTime + j*saveTime)
169 + "/" + fieldToCompute;
170 exist_precomputed_fields = exist_precomputed_fields && ITHACAutilities::check_file(local_file);
171 }
172
173 string pathCentered = "";
174 if (interpFieldCenteredOrNot) {pathCentered = "_centered";}
175 bool exist_covMatrix = ITHACAutilities::check_file("./ITHACAoutput/CovMatrices"
176 + pathCentered + "/covMatrix" + fieldToCompute + ".npy")
177 && ITHACAutilities::check_file("./ITHACAoutput/mean/1/" + fieldToCompute);
178 exist_precomputed_fields = exist_precomputed_fields || exist_covMatrix;
179
180 if (!exist_precomputed_fields)
181 {
182 label offset_1 = 0;
183 if (fieldToCompute == HRInterpField || fieldToCompute == "fullStressFunction" || fieldToCompute == "nut")
184 {
185 Info << "Evaluating " << fieldToCompute << " term" << endl;
186 T nonLinearSnapshotsj = template_HRInterpField;
187
188 if (fieldToCompute == "fullStressFunction"
189 || ITHACAutilities::containsSubstring(fieldToCompute, "reducedFullStressFunction")
190 || ITHACAutilities::containsSubstring(fieldToCompute, "reducedNut"))
191 {
192 ITHACAstream::exportSolution(nonLinearSnapshotsj, "0", snapshotsFolder, fieldToCompute);
193 ITHACAstream::exportSolution(nonLinearSnapshotsj, "0", m_parameters->get_casenameData(), fieldToCompute);
194 }
195 else if(fieldToCompute == "nut")
196 {
197 // /!\ Nut requires Snapshot at time 0 to be initialized, not fullStressFunction field
198 if (l_startTime == 1)
199 {
200 offset_1 = 1;
201 }
202 }
203 else
204 {
205 Info << "Error : HRInterpolatedField not valid : " << HRInterpField << endl;
206 Info << "HR is available for fullStressFunction and nut only." << endl;
207 abort();
208 }
209
210 for (label j = offset_1; j < nTotalSnapshots; j++)
211 {
212 word snap_time = runTime2.times()[l_startTime + j].name();
213 string idxTimeStr = ITHACAutilities::double2ConciseString(startingTime + j*saveTime);
214 if (!ITHACAutilities::containsSubstring(fieldToCompute, "reduced"))
215 {
216 ithacaUnsteadyNSTurb->computeNonLinearSnapshot_at_time(snap_time, nonLinearSnapshotsj) ;
217 }
218 else
219 {
220 ithacaUnsteadyNSTurb->computeNonLinearSnapshot_at_time(snap_time, nonLinearSnapshotsj, f_spatialModesU) ;
221 }
222 ITHACAstream::exportSolution(nonLinearSnapshotsj, idxTimeStr, snapshotsFolder, fieldToCompute);
223 }
224
225 }
226
227 // Compute snapshots field if ECP, ie projected field
228 else if (ITHACAutilities::containsSubstring(fieldToCompute, HRSnapshotsField))
229 {
230 if(ITHACAutilities::containsSubstring(HRSnapshotsField, "projFullStressFunction")
231 || ITHACAutilities::containsSubstring(HRSnapshotsField, "projReducedFullStressFunction"))
232 {
233 int nUsedModesU = 0;
234 int currentModeU = 0;
235 T meanHRInterpField = template_HRInterpField;
236 S snapshotECPcj(fieldToCompute, template_HRSnapshotsField);
237 S meanECPModec = template_HRSnapshotsField;
238 ITHACAutilities::setToZero(meanECPModec);
239
240 if (ECPAlgo == "Global")
241 {
242 nUsedModesU = f_spatialModesU.size();
243 PtrList<T> meanRead;
244 ITHACAstream::read_fields(meanRead, HRInterpField, "./ITHACAoutput/mean/");
245 meanHRInterpField = meanRead[0];
246 }
247 else
248 {
249 nUsedModesU = 1;
250 std::vector<int> intInFieldName = ITHACAutilities::extractIntFromString(fieldToCompute);
251 currentModeU = intInFieldName[intInFieldName.size()-1]-1;
252 }
253
254 Info << "Evaluating " << fieldToCompute << " term" << endl;
255 ITHACAstream::exportSolution(snapshotECPcj, "0", snapshotsFolder, fieldToCompute);
256 ITHACAstream::exportSolution(snapshotECPcj, "0", m_parameters->get_casenameData(), fieldToCompute);
257
258 for (label c = 0; c < nUsedModesU; c++)
259 {
260 if (ECPAlgo == "Global")
261 {
262 currentModeU = c;
263 if (interpFieldCenteredOrNot)
264 {
265 // Computing the mean of projFullStressFunction for mode c
266 ithacaUnsteadyNSTurb->computeProjSmagTerm_fromSmag_fromMode
267 (meanECPModec, meanHRInterpField, f_spatialModesU[currentModeU]);
268 }
269 }
270
271 for (label j = 0; j < nTotalSnapshots/nUsedModesU; j++)
272 {
273 word snap_time = runTime2.times()[l_startTime + j].name();
274 string idxStr = ITHACAutilities::double2ConciseString(startingTime + (c*l_nSnapshot + j)*saveTime);
275 ithacaUnsteadyNSTurb->computeNonLinearSnapshot_at_time(snap_time, snapshotECPcj, f_spatialModesU[currentModeU]);
276 ITHACAutilities::subtractFields(snapshotECPcj, meanECPModec);
277 ITHACAstream::exportSolution(snapshotECPcj, idxStr, snapshotsFolder, fieldToCompute);
278 ITHACAstream::printProgress(double(c*l_nSnapshot + j) / (nTotalSnapshots-1));
279 }
280 }
281 Info << endl;
282 }
283
284 else if(ITHACAutilities::containsSubstring(HRSnapshotsField, "projSmagFromNut")
285 || ITHACAutilities::containsSubstring(HRSnapshotsField, "projSmagFromReducedNut"))
286 {
287 std::vector<int> currentModesU;
288 T meanHRInterpField = template_HRInterpField;
289 S snapshotECPckj(fieldToCompute, template_HRSnapshotsField);
290 S meanECPModeck = template_HRSnapshotsField;
291 ITHACAutilities::setToZero(meanECPModeck);
292
293 PtrList<volVectorField> f_mean_and_spatialModesU(f_spatialModesU.size() + 1);
294 for (label c = 0; c < f_spatialModesU.size(); c++)
295 {
296 f_mean_and_spatialModesU.set(c+1, new volF(f_spatialModesU[c]));
297 }
298 f_mean_and_spatialModesU.set(0, new volF(*f_meanU));
299
300 if (ECPAlgo == "Global")
301 {
302 PtrList<T> meanRead;
303 ITHACAstream::read_fields(meanRead, HRInterpField, "./ITHACAoutput/mean/");
304 meanHRInterpField = meanRead[0];
305 }
306 else
307 {
308 currentModesU = ITHACAutilities::extractIntFromString(fieldToCompute);
309 }
310
311 Info << "Evaluating " << fieldToCompute << " term" << endl;
312 ITHACAstream::exportSolution(snapshotECPckj, "0", snapshotsFolder, fieldToCompute);
313 ITHACAstream::exportSolution(snapshotECPckj, "0", m_parameters->get_casenameData(), fieldToCompute);
314
315 for (label c = 0; c < f_spatialModesU.size(); c++)
316 {
317 for (label k = 0; k <= c+1; k++)
318 {
319 if (ECPAlgo == "EachMode")
320 {
321 c = currentModesU[currentModesU.size()-2] - 1;
322 k = currentModesU[currentModesU.size()-1];
323 }
324 else if (ECPAlgo == "Global" && interpFieldCenteredOrNot)
325 {
326 // Computing the mean of projSmagFromNut for modes c,k
327 ithacaUnsteadyNSTurb->computeProjSmagFromNut_fromNut_fromModes(meanECPModeck, meanHRInterpField,
328 f_spatialModesU[c], f_mean_and_spatialModesU[k]);
329 }
330
331 for (label j = 0; j < l_nSnapshot; j++)
332 {
333 word snap_time = runTime2.times()[l_startTime + j].name();
334 string idxStr = ITHACAutilities::double2ConciseString(startingTime + (((c*(c+1)/2 + c)*l_nSnapshot
335 + k*l_nSnapshot)*(ECPAlgo=="Global") + j)*saveTime);
336 ithacaUnsteadyNSTurb->computeNonLinearSnapshot_at_time(snap_time, snapshotECPckj,
337 f_spatialModesU[c], f_mean_and_spatialModesU[k]);
338 ITHACAutilities::subtractFields(snapshotECPckj, meanECPModeck);
339 ITHACAstream::exportSolution(snapshotECPckj, idxStr, snapshotsFolder, fieldToCompute);
340 ITHACAstream::printProgress(double(((c*(c+1)/2 + c)*l_nSnapshot + k*l_nSnapshot)
341 *(ECPAlgo=="Global") + j) / (nTotalSnapshots-1));
342 }
343
344 if (ECPAlgo == "EachMode")
345 {
346 goto endloops;
347 }
348 }
349 }
350 endloops:
351 Info << endl;
352 }
353 }
354 else
355 {
356 Info << "Error : Unexpected field for precomputeNonPolynomialFunction : " << fieldToCompute << endl;
357 abort();
358 }
359 }
360
361
362 // Compute/Read and store in m_parameters the mean of the non polynomial field from high-fidelity velocity
363 if (fieldToCompute == HRInterpField || fieldToCompute == "fullStressFunction" || fieldToCompute == "nut")
364 {
365 if (interpFieldCenteredOrNot)
366 {
367 T meanField = template_HRInterpField;
368 if (ITHACAutilities::check_file("./ITHACAoutput/mean/" + pathProcessor + "1/" + fieldToCompute))
369 {
370 Info << "Reading the mean of " << fieldToCompute << " field" << endl;
371 PtrList<T> meanRead;
372 ITHACAstream::read_fields(meanRead, fieldToCompute, "./ITHACAoutput/mean/");
373 meanField = meanRead[0];
374 }
375 else // Computing the mean
376 {
377 ITHACAPOD::PODTemplate<T> ithacaFVPOD_interp_field(m_parameters, fieldToCompute, snapshotsFolder);
378 ithacaFVPOD_interp_field.set_b_centeredOrNot(1);
379 ithacaFVPOD_interp_field.computeMeanField();
380 meanField = ithacaFVPOD_interp_field.get_mean();
381 }
382
383 if (fieldToCompute == "fullStressFunction" || fieldToCompute == "nut")
384 {
385 m_parameters->set_meanDEIM(meanField);
386 }
387 }
388 else
389 {
390 T meanZero(fieldToCompute, template_HRInterpField);
392 m_parameters->set_meanDEIM(meanZero);
393 }
394 }
395}
396
397template<typename volF, typename T, typename S>
399{
400 // Compute the mean of the nonpolynomial field from high-fidelity velocity if HR learnt from reduced velocity
401 if (ITHACAutilities::containsSubstring(HRInterpField, "reduced"))
402 {
403 word nameNotReduced = HRInterpField.substr(7, HRInterpField.find("_")-7);
404 nameNotReduced[0] = tolower(nameNotReduced[0]);
405 precomputeTurbDiffusionFunctions(nameNotReduced);
406 snapshotsFolder = "./ITHACAoutput/Hyperreduction/" + HRInterpField.substr(0, HRInterpField.find("_")) + "/";
407 }
408
409 // Evaluate and save the nonpolynomial field for HR learning
411
412 std::vector<word> HRPODFields;
413 // Evaluate and save the projected nonpolynomial field if ECP
414 if (HRMethod == "DEIM")
415 {
416 HRPODFields.push_back(HRInterpField);
417 }
418 else if (HRMethod == "ECP")
419 {
420 word HRSnapshotsField_copy = HRSnapshotsField;
421 std::vector<word> HRFields_temp{std::begin(m_parameters->get_field_name()),
422 std::end(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;
427
428 for (auto fieldIterator: HRPODFields)
429 {
431 }
432 }
433
434 for (auto fieldIterator: HRPODFields)
435 {
436 // POD of nonpolynomial fields
437 PtrList<S> f_subsetSpatialModesHR;
438 ITHACAPOD::PODTemplate<S> ithacaFVPOD_template_field(m_parameters, fieldIterator, snapshotsFolder);
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]));}
444 }
445
446 if (Pstream::parRun())
447 {
448 bool waitMaster = false;
449 if (Pstream::master()){ waitMaster = true; }
450 Pstream::scatter(waitMaster);
451
452 Info << "Hyperreduction POD done in parallel. Magic points selection must run sequentially. Aborting." << endl << endl;
453 std::exit(111);
454 }
455
456 // Convertion to Eigen and weight of the HR modes
457 Eigen::VectorXd weights = ITHACAutilities::getMassMatrixFV(f_spatialModesHR[0]).array().sqrt();
458 Eigen::MatrixXd spatialModesHR = weights.asDiagonal() * Foam2Eigen::PtrList2Eigen(f_spatialModesHR);
459 Eigen::VectorXi initSeeds(0);
460
461 // Constructor of the hyperReduction object
462 ithacaHyperreduction = autoPtr<HyperReduction<PtrList<S>>>(
463 new HyperReduction<PtrList<S>>(f_spatialModesHR.size(),
464 m_parameters->get_nMagicPoints(),
465 std::is_same<S, volScalarField>::value ? 1 : 3,
466 f_spatialModesHR[0].size(),
467 initSeeds,
468 folder_HR,
469 weights.array().square().matrix()));
470
471 Eigen::VectorXd fieldWeightsOnes = Eigen::VectorXd::Ones(ithacaHyperreduction->n_cells * ithacaHyperreduction->vectorial_dim);
472 List<Eigen::VectorXd> quadWeights(HRPODFields.size());
473
474
475 if (HRMethod == "DEIM")
476 {
477 ithacaHyperreduction->offlineGappyDEIM(spatialModesHR, fieldWeightsOnes, folder_HR);
478 }
479
480 else if (HRMethod == "ECP")
481 {
482 // ECP snapshots are weighted by cells' volume not sqrt
483 spatialModesHR = weights.asDiagonal() * spatialModesHR;
484
485 bool weightModesWithEigenval = 0;
486
487 if (weightModesWithEigenval)
488 {
489 for (unsigned int c = 0; c < HRPODFields.size(); c++)
490 {
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();
501 }
502 }
503
504 if (ECPAlgo == "Global")
505 {
506 quadWeights.resize(f_spatialModesU.size());
507 ithacaHyperreduction->offlineECP(spatialModesHR, fieldWeightsOnes, folder_HR);
508 for (label c = 0; c < f_spatialModesU.size(); c++)
509 {
510 quadWeights[c] = ithacaHyperreduction->quadratureWeights;
511 }
512 }
513 else if (ECPAlgo == "EachMode")
514 {
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++)
518 {
519 listspatialModesHR[c] = spatialModesHR.middleCols(nModesSubspace*c, nModesSubspace);
520 }
521 ithacaHyperreduction->offlineECP(listspatialModesHR, fieldWeightsOnes, folder_HR);
522 quadWeights = ithacaHyperreduction->quadratureWeightsSubspaces;
523 }
524 }
525
526
527 if (HRMethod == "DEIM")
528 {
529 // Condition number
530 Eigen::JacobiSVD<Eigen::MatrixXd> svd(ithacaHyperreduction->pinvPU);
531 double cond = svd.singularValues()(0) / svd.singularValues()(svd.singularValues().size() - 1);
532 Info << "Condition number of P^T U = " << cond << endl;
533
534 // Saves
535 word folder_K_DEIM = folder_HR + "K_DEIM/";
536 mkDir(folder_K_DEIM);
537 cnpy::save(ithacaHyperreduction->pinvPU, folder_K_DEIM + "/P_U_inv.npy");
538 cnpy::save(ithacaHyperreduction->MatrixOnline, folder_K_DEIM + "/MatrixOnline.npy");
539
540 m_parameters->set_K_DEIM(ithacaHyperreduction->MatrixOnline);
541 }
542
543 else if (HRMethod == "ECP" && ITHACAutilities::containsSubstring(HRInterpField, "fullStressFunction"))
544 {
545 Eigen::VectorXd vectorWeights = ITHACAutilities::getMassMatrixFV(f_spatialModesU[0]).array().sqrt();
546 Eigen::MatrixXd spatialModesU = vectorWeights.asDiagonal() * Foam2Eigen::PtrList2Eigen(f_spatialModesU);
547 Eigen::SparseMatrix<double> P = ithacaHyperreduction->maskToOtherDim(3);
548 Eigen::MatrixXd K_DEIM = spatialModesU.transpose() * P;
549 for (label m = 0; m < ithacaHyperreduction->n_nodes; m++)
550 {
551 for (label c = 0; c < f_spatialModesU.size(); c++)
552 {
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];
556 }
557 }
558 cnpy::save(K_DEIM, folder_HR + "/K_DEIM.npy");
559 m_parameters->set_K_DEIM(K_DEIM);
560 }
561
562 else if (HRMethod == "ECP" && ITHACAutilities::containsSubstring(HRInterpField, "nut"))
563 {
564 Eigen::MatrixXd K_DEIM(HRPODFields.size(), ithacaHyperreduction->n_nodes);
565 Eigen::VectorXd sparseWeights = weights.transpose() * ithacaHyperreduction->P;
566 for (unsigned int c = 0; c < HRPODFields.size(); c++)
567 {
568 K_DEIM.row(c) = (sparseWeights.array() * quadWeights[c].array()).matrix();
569 }
570 cnpy::save(K_DEIM, folder_HR + "/K_DEIM.npy");
571 m_parameters->set_K_DEIM(K_DEIM);
572 }
573
574
575 // Generate submeshes
576 m_parameters->set_magicPoints(ithacaHyperreduction->nodePoints);
577 ithacaHyperreduction->problemName = HRInterpField;
578 ithacaHyperreduction->generateSubmesh(2, m_parameters->get_mesh());
579
580 m_parameters->set_localMagicPoints(ithacaHyperreduction->localNodePoints);
581 m_parameters->set_submesh(ithacaHyperreduction->submesh->subMesh());
582
583 // Set delta on submesh
584 m_parameters->set_magicDelta(ithacaHyperreduction->interpolateField(m_parameters->get_delta()));
585
586 // Get deformation tensor on submesh
588
589 // Get temporal mean of interpolated nonpolynomial fields on mesh and submesh
591}
592
593
595 Parameters* myParameters,
596 bool mgPoints_0_Neighborhoods_1,
597 volVectorField& template_HRInterpField,
598 volVectorField& template_HRSnapshotsField,
599 volVectorField*& meanU, PtrList<volVectorField>& spatialModesU);
601 Parameters* myParameters,
602 bool mgPoints_0_Neighborhoods_1,
603 volVectorField& template_HRInterpField,
604 volScalarField& template_HRSnapshotsField,
605 volVectorField*& meanU, PtrList<volVectorField>& spatialModesU);
607 Parameters* myParameters,
608 bool mgPoints_0_Neighborhoods_1,
609 volScalarField& template_HRInterpField,
610 volScalarField& template_HRSnapshotsField,
611 volVectorField*& meanU, PtrList<volVectorField>& spatialModesU);
612
616
620
624
628
632
633
Header file of the TurbDiffusionHyperreduction class.
static Eigen::MatrixXd PtrList2Eigen(PtrList< GeometricField< Type, PatchField, GeoMesh > > &fields, label Nfields=-1)
Convert a PtrList of snapshots to Eigen matrix (only internal field).
Definition Foam2Eigen.C:665
Class that contains all parameters of the stochastic POD.
void computeTurbDiffusionHyperreduction()
Compute the hyperreduction by callng other methods.
PtrList< volF > f_spatialModesU
Pointer list of POD Modes of U.
label l_nSnapshotSimulation
Number of Simulation snapshot, also number of time steps.
S template_HRSnapshotsField
Snapshots field template.
autoPtr< UnsteadyNSTurb > ithacaUnsteadyNSTurb
Parameter object to evaluate interpolated functions.
Foam::Time runTime2
Dummy Foam::Time object for mesh and submesh management.
autoPtr< HyperReduction< PtrList< S > > > ithacaHyperreduction
Hyperreduction objects to choose magic points.
word snapshotsFolder
Path to snapshots, number, start and end time indices for each HR POD. If -1, set automatically by th...
label l_startTime
start time of the POD decomposition
~TurbDiffusionHyperreduction()
Class TurbDiffusionHyperreduction Destructor.
bool mgPoints_0_Neighborhoods_1
Boolean to include or not magic points' neighbourhood in the submesh 0 if only magicPoints and 1 if i...
word folder_HR
Export folder for HR operators.
label l_nSnapshot
Number of snapshot, also number of time step.
StoredParameters * m_parameters
Parameter object containing main information.
volF * f_meanU
Pointer of mean of U.
void precomputeTurbDiffusionFunctions(word &fieldToCompute)
Precompute and save non polynomial field.
void common_MeanHRInterpField()
Compute the interpolated field's mean on the magic points submesh.
T template_HRInterpField
Interpolated field template.
TurbDiffusionHyperreduction(Parameters *myParameters, bool mgPoints_0_Neighborhoods_1, T &template_HRInterpField, S &template_HRSnapshotsField, volF *&meanU, PtrList< volF > &spatialModesU)
Class TurbDiffusionHyperreduction Constructor.
void computeDefTensor(volGradF tensorMeanU)
Compute the symmetric tensor of the velocity modes on the magic points submesh.
Implementation of a parametrized full order unsteady NS problem and preparation of the reduced matr...
static volTensorField computeS_fromU(const volVectorField &snapshotj)
Compute S deformation tensor for a given vector field U.
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.
void printProgress(double percentage)
Print progress bar given the percentage.
bool containsSubstring(std::string contain, std::string contained)
Returns true if contained is a substring of contain, false otherwise.
void setToZero(T &f1)
Set a field of type vol[Scalar|Vector|Tensor]Field to 0.
std::string double2ConciseString(const double &d)
Returns the double d in string format without keeping all the extra 0.
Eigen::VectorXd getMassMatrixFV(GeometricField< Type, PatchField, GeoMesh > &snapshot)
Gets a vector containing the volumes of each cell of the mesh.
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...
std::vector< int > extractIntFromString(std::string input)
Returns an array storing all the integers in the input string.