Loading...
Searching...
No Matches
DEIM.C
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
13License
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
31#include "DEIM.H"
32// Template function constructor
33template<typename T>
34DEIM<T>::DEIM (PtrList<T>& s, label MaxModes, word FunctionName,
35 word FieldName)
36 :
40{
42 Folder = "ITHACAoutput/DEIM/" + FunctionName;
43 magicPoints = autoPtr<IOList<label >>
44 (
45 new IOList<label>
46 (
47 IOobject
48 (
49 "magicPoints",
50 para->runTime.time().constant(),
51 "../" + Folder,
52 para->mesh,
53 IOobject::READ_IF_PRESENT,
54 IOobject::NO_WRITE
55 )
56 )
57 );
58 xyz = autoPtr<IOList<label >>
59 (
60 new IOList<label>
61 (
62 IOobject
63 (
64 "xyz",
65 para->runTime.time().constant(),
66 "../" + Folder,
67 para->mesh,
68 IOobject::READ_IF_PRESENT,
69 IOobject::NO_WRITE
70 )
71 )
72 );
74 FieldName);
75
76 if (!(magicPoints().headerOk() && xyz().headerOk()))
77 {
78 Eigen::MatrixXd A;
79 Eigen::VectorXd b;
80 Eigen::VectorXd c;
81 Eigen::VectorXd r;
82 Eigen::VectorXd rho(1);
84 Ncells = modes[0].size();
85 label ind_max, c1, xyz_in;
86 double max = MatrixModes.cwiseAbs().col(0).maxCoeff(& ind_max, & c1);
87 check3DIndices(ind_max, xyz_in);
88 rho(0) = max;
89 magicPoints().append(ind_max);
90 xyz().append(xyz_in);
91 U = MatrixModes.col(0);
92 P.resize(MatrixModes.rows(), 1);
93 P.insert(ind_max, 0) = 1;
94
95 for (label i = 1; i < MaxModes; i++)
96 {
97 A = P.transpose() * U;
98 b = P.transpose() * MatrixModes.col(i);
99 c = A.fullPivLu().solve(b);
100 r = MatrixModes.col(i) - U * c;
101 max = r.cwiseAbs().maxCoeff(& ind_max, & c1);
102 P.conservativeResize(MatrixModes.rows(), i + 1);
103 P.insert(ind_max, i) = 1;
104 U.conservativeResize(MatrixModes.rows(), i + 1);
105 U.col(i) = MatrixModes.col(i);
106 rho.conservativeResize(i + 1);
107 rho(i) = max;
108 check3DIndices(ind_max, xyz_in);
109 magicPoints().append(ind_max);
110 xyz().append(xyz_in);
111 }
112
113 MatrixOnline = U * ((P.transpose() * U).fullPivLu().inverse());
114 mkDir(Folder);
115 cnpy::save(MatrixOnline, Folder + "/MatrixOnline.npy");
116 magicPoints().write();
117 xyz().write();
118 }
119 else
120 {
121 cnpy::load(MatrixOnline, Folder + "/MatrixOnline.npy");
122 }
123}
124
125// constructor for matrix DEIM
126template<typename T>
127DEIM<T>::DEIM (PtrList<T>& s, label MaxModesA, label MaxModesB,
128 word MatrixName)
129 :
131 MaxModesA(MaxModesA),
132 MaxModesB(MaxModesB),
134 runSubMesh(false),
135 runSubMeshA(false),
136 runSubMeshB(false)
137
138{
140 FolderM = "ITHACAoutput/DEIM/" + MatrixName;
141 magicPointsArow = autoPtr<IOList<label >>
142 (
143 new IOList<label>
144 (
145 IOobject
146 (
147 "magicPointsArow",
148 para->runTime.time().constant(),
149 "../" + FolderM,
150 para->mesh,
151 IOobject::READ_IF_PRESENT,
152 IOobject::NO_WRITE
153 )
154 )
155 );
156 magicPointsAcol = autoPtr<IOList<label >>
157 (
158 new IOList<label>
159 (
160 IOobject
161 (
162 "magicPointsAcol",
163 para->runTime.time().constant(),
164 "../" + FolderM,
165 para->mesh,
166 IOobject::READ_IF_PRESENT,
167 IOobject::NO_WRITE
168 )
169 )
170 );
171 magicPointsB = autoPtr<IOList<label >>
172 (
173 new IOList<label>
174 (
175 IOobject
176 (
177 "magicPointsB",
178 para->runTime.time().constant(),
179 "../" + FolderM,
180 para->mesh,
181 IOobject::READ_IF_PRESENT,
182 IOobject::NO_WRITE
183 )
184 )
185 );
186 xyz_Arow = autoPtr<IOList<label >>
187 (
188 new IOList<label>
189 (
190 IOobject
191 (
192 "xyz_Arow",
193 para->runTime.time().constant(),
194 "../" + FolderM,
195 para->mesh,
196 IOobject::READ_IF_PRESENT,
197 IOobject::NO_WRITE
198 )
200 );
201 xyz_Acol = autoPtr<IOList<label >>
202 (
203 new IOList<label>
204 (
205 IOobject
206 (
207 "xyz_Acol",
208 para->runTime.time().constant(),
209 "../" + FolderM,
210 para->mesh,
211 IOobject::READ_IF_PRESENT,
212 IOobject::NO_WRITE
213 )
214 )
215 );
216 xyz_B = autoPtr<IOList<label >>
217 (
218 new IOList<label>
219 (
220 IOobject
221 (
222 "xyz_B",
223 para->runTime.time().constant(),
224 "../" + FolderM,
225 para->mesh,
226 IOobject::READ_IF_PRESENT,
227 IOobject::NO_WRITE
228 )
229 )
230 );
231
232 if (!(magicPointsArow().headerOk() && magicPointsAcol().headerOk() &&
233 magicPointsB().headerOk() && xyz_Arow().headerOk() &&
234 xyz_Acol().headerOk() && xyz_B().headerOk()))
235 {
236 Eigen::MatrixXd AA;
237 Eigen::VectorXd bA;
238 Eigen::MatrixXd cA;
239 Eigen::SparseMatrix<double> rA;
240 Eigen::VectorXd rhoA(1);
241 Matrix_Modes = ITHACAPOD::DEIMmodes(SnapShotsMatrix, MaxModesA, MaxModesB,
242 MatrixName);
243 Ncells = getNcells(std::get<1>(Matrix_Modes)[0].rows());
244 label ind_rowA, ind_colA, xyz_rowA, xyz_colA;
245 ind_rowA = ind_colA = xyz_rowA = xyz_colA = 0;
246 double maxA = EigenFunctions::max(std::get<0>(Matrix_Modes)[0], ind_rowA,
247 ind_colA);
248 label ind_rowAOF = ind_rowA;
249 label ind_colAOF = ind_colA;
250 check3DIndices(ind_rowAOF, ind_colAOF, xyz_rowA, xyz_colA);
251 xyz_Arow().append(xyz_rowA);
252 xyz_Acol().append(xyz_colA);
253 rhoA(0) = maxA;
254 magicPointsArow().append(ind_rowAOF);
255 magicPointsAcol().append(ind_colAOF);
256 UA.append(std::get<0>(Matrix_Modes)[0]);
257 Eigen::SparseMatrix<double> Pnow(std::get<0>(Matrix_Modes)[0].rows(),
258 std::get<0>(Matrix_Modes)[0].cols());
259 Pnow.insert(ind_rowA, ind_colA) = 1;
260 PA.append(Pnow);
261
262 for (label i = 1; i < MaxModesA; i++)
263 {
265 bA = EigenFunctions::innerProduct(PA, std::get<0>(Matrix_Modes)[i]);
266 cA = AA.fullPivLu().solve(bA);
267 rA = std::get<0>(Matrix_Modes)[i] - EigenFunctions::MVproduct(UA, cA);
268 double maxA = EigenFunctions::max(rA, ind_rowA, ind_colA);
269 rhoA.conservativeResize(i + 1);
270 rhoA(i) = maxA;
271 label ind_rowAOF = ind_rowA;
272 label ind_colAOF = ind_colA;
273 check3DIndices(ind_rowAOF, ind_colAOF, xyz_rowA, xyz_colA);
274 xyz_Arow().append(xyz_rowA);
275 xyz_Acol().append(xyz_colA);
276 magicPointsArow().append(ind_rowAOF);
277 magicPointsAcol().append(ind_colAOF);
278 UA.append(std::get<0>(Matrix_Modes)[i]);
279 Eigen::SparseMatrix<double> Pnow(std::get<0>(Matrix_Modes)[0].rows(),
280 std::get<0>(Matrix_Modes)[0].cols());
281 Pnow.insert(ind_rowA, ind_colA) = 1;
282 PA.append(Pnow);
283 }
284
285 Eigen::MatrixXd Aaux = EigenFunctions::innerProduct(PA,
286 UA).fullPivLu().inverse();
288 Eigen::MatrixXd AB;
289 Eigen::VectorXd bB;
290 Eigen::VectorXd cB;
291 Eigen::VectorXd rB;
292 Eigen::VectorXd rhoB(1);
293 label ind_rowB, xyz_rowB, c1;
294 double maxB = std::get<1>(Matrix_Modes)[0].cwiseAbs().maxCoeff(& ind_rowB,
295 & c1);
296 label ind_rowBOF = ind_rowB;
297 check3DIndices(ind_rowBOF, xyz_rowB);
298 rhoB(0) = maxB;
299 xyz_B().append(xyz_rowB);
300 magicPointsB().append(ind_rowBOF);
301 UB = std::get<1>(Matrix_Modes)[0];
302 PB.resize(UB.rows(), 1);
303 PB.insert(ind_rowB, 0) = 1;
304
305 for (label i = 1; i < MaxModesB; i++)
306 {
307 AB = PB.transpose() * UB;
308 bB = PB.transpose() * std::get<1>(Matrix_Modes)[i];
309 cB = AB.fullPivLu().solve(bB);
310 rB = std::get<1>(Matrix_Modes)[i] - UB * cB;
311 maxB = rB.cwiseAbs().maxCoeff(& ind_rowB, & c1);
312 ind_rowBOF = ind_rowB;
313 check3DIndices(ind_rowBOF, xyz_rowB);
314 xyz_B().append(xyz_rowB);
315 PB.conservativeResize((std::get<1>(Matrix_Modes)[i]).size(), i + 1);
316 PB.insert(ind_rowB, i) = 1;
317 UB.conservativeResize((std::get<1>(Matrix_Modes)[i]).size(), i + 1);
318 UB.col(i) = std::get<1>(Matrix_Modes)[i];
319 rhoB.conservativeResize(i + 1);
320 rhoB(i) = maxB;
321 magicPointsB().append(ind_rowBOF);
322 }
323
324 if (MaxModesB == 1 && std::get<1>(Matrix_Modes)[0].norm() < 1e-8)
325 {
326 MatrixOnlineB = Eigen::MatrixXd::Zero(std::get<1>(Matrix_Modes)[0].rows(), 1);
327 }
328 else if (MaxModesB != 1)
329 {
330 MatrixOnlineB = UB * ((PB.transpose() * UB).fullPivLu().inverse());
331 }
332 else
333 {
334 Eigen::MatrixXd aux = PB.transpose() * UB;
335 MatrixOnlineB = UB * 1 / aux(0, 0);
336 }
337
338 mkDir(FolderM + "/lhs");
339 mkDir(FolderM + "/rhs");
340 ITHACAstream::save(MatrixOnlineA, FolderM, "/lhs/MatrixOnlineA");
341 cnpy::save(MatrixOnlineB, FolderM + "/rhs/MatrixOnlineB.npy");
342 magicPointsArow().write();
343 magicPointsAcol().write();
344 magicPointsB().write();
345 xyz_Arow().write();
346 xyz_Acol().write();
347 xyz_B().write();
348 }
349 else
350 {
351 ITHACAstream::load(MatrixOnlineA, FolderM, "/lhs/MatrixOnlineA");
352 cnpy::load(MatrixOnlineB, FolderM + "/rhs/MatrixOnlineB.npy");
353 }
354}
355
356
357template<typename T>
358template<typename S>
359S DEIM<T>::generateSubmesh(label layers, const fvMesh& mesh, S field,
360 label secondTime)
361{
363 totalMagicPoints = autoPtr<IOList<labelList >>
364 (
365 new IOList<labelList>
366 (
367 IOobject
368 (
369 "totalMagicPoints",
370 para->runTime.time().constant(),
371 "../" + Folder,
372 para->mesh,
373 IOobject::READ_IF_PRESENT,
374 IOobject::NO_WRITE
375 )
376 )
377 );
378 uniqueMagicPoints = autoPtr<IOList<label >>
379 (
380 new IOList<label>
381 (
382 IOobject
383 (
384 "uniqueMagicPoints",
385 para->runTime.time().constant(),
386 "../" + Folder,
387 para->mesh,
388 IOobject::READ_IF_PRESENT,
389 IOobject::NO_WRITE
390 )
391 )
392 );
393 volScalarField Indici
394 (
395 IOobject
396 (
397 FunctionName + "_indices",
398 mesh.time().timeName(),
399 mesh,
400 IOobject::NO_READ,
401 IOobject::NO_WRITE
402 ),
403 mesh,
404 dimensionedScalar(FunctionName + "_indices", dimensionSet(0, 0, 0, 0, 0, 0, 0),
405 0.0)
406 );
407 submesh = autoPtr<fvMeshSubset>(new fvMeshSubset(mesh));
408
409 if (!totalMagicPoints().headerOk())
410 {
411 List<label> indices;
412
413 for (label i = 0; i < magicPoints().size(); i++)
414 {
415 indices = ITHACAutilities::getIndices(mesh, magicPoints()[i], layers);
416 totalMagicPoints().append(indices);
417 }
418
420 }
421
422#if OPENFOAM >= 1812
423 submesh->setCellSubset(uniqueMagicPoints());
424#else
425 submesh->setLargeCellSubset(uniqueMagicPoints());
426#endif
427 submesh->subMesh().fvSchemes::readOpt() = mesh.fvSchemes::readOpt();
428 submesh->subMesh().fvSolution::readOpt() = mesh.fvSolution::readOpt();
429 submesh->subMesh().fvSchemes::read();
430 submesh->subMesh().fvSolution::read();
431 std::cout.clear();
432 S f = submesh->interpolate(field).ref();
433 scalar zerodot25 = 0.25;
434 ITHACAutilities::assignIF(Indici, zerodot25,
435 uniqueMagicPoints().List<label>::clone()());
437
438 if (!secondTime)
439 {
441 ITHACAstream::exportSolution(Indici, "1", "./ITHACAoutput/DEIM/" + FunctionName
442 );
443 }
444
445 totalMagicPoints().write();
446 uniqueMagicPoints().write();
447 return f;
448}
449
450template<typename T>
451template<typename S>
452S DEIM<T>::generateSubmeshMatrix(label layers, const fvMesh& mesh, S field,
453 label secondTime)
454{
456 totalMagicPointsA = autoPtr<IOList<labelList >>
457 (
458 new IOList<labelList>
459 (
460 IOobject
461 (
462 "totalMagicPointsA",
463 para->runTime.time().constant(),
464 "../" + FolderM,
465 para->mesh,
466 IOobject::READ_IF_PRESENT,
467 IOobject::NO_WRITE
468 )
469 )
470 );
471 uniqueMagicPointsA = autoPtr<IOList<label >>
472 (
473 new IOList<label>
474 (
475 IOobject
476 (
477 "uniqueMagicPointsA",
478 para->runTime.time().constant(),
479 "../" + FolderM,
480 para->mesh,
481 IOobject::READ_IF_PRESENT,
482 IOobject::NO_WRITE
483 )
484 )
485 );
486 List<label> indices;
487 volScalarField Indici
488 (
489 IOobject
490 (
491 MatrixName + "_A_indices",
492 mesh.time().timeName(),
493 mesh,
494 IOobject::NO_READ,
495 IOobject::NO_WRITE
496 ),
497 mesh,
498 dimensionedScalar(MatrixName + "_A_indices", dimensionSet(0, 0, 0, 0, 0, 0, 0),
499 Foam::scalar(0))
500 );
501 submeshA = autoPtr<fvMeshSubset>(new fvMeshSubset(mesh));
502
503 for (label i = 0; i < magicPointsArow().size(); i++)
504 {
505 indices = ITHACAutilities::getIndices(mesh, magicPointsArow()[i], layers);
506 indices.append(ITHACAutilities::getIndices(mesh, magicPointsAcol()[i],
507 layers));
508 totalMagicPointsA().append(indices);
509 }
510
512#if OPENFOAM >= 1812
513 submeshA->setCellSubset(uniqueMagicPointsA());
514#else
515 submeshA->setLargeCellSubset(uniqueMagicPointsA());
516#endif
517 submeshA->subMesh().fvSchemes::readOpt() = mesh.fvSchemes::readOpt();
518 submeshA->subMesh().fvSolution::readOpt() = mesh.fvSolution::readOpt();
519 submeshA->subMesh().fvSchemes::read();
520 submeshA->subMesh().fvSolution::read();
521 std::cout.clear();
522 S f = submeshA->interpolate(field).ref();
523 scalar zerodot25 = 0.25;
524 ITHACAutilities::assignIF(Indici, zerodot25,
525 uniqueMagicPointsA().List<label>::clone()());
528
529 if (!secondTime)
530 {
533 ITHACAstream::exportSolution(Indici, "1", "./ITHACAoutput/DEIM/" + MatrixName
534 );
535 totalMagicPointsA().write();
536 uniqueMagicPointsA().write();
537 }
538
539 runSubMeshA = true;
540 return f;
541}
542
543template<typename T>
544template<typename S>
545S DEIM<T>::generateSubmeshVector(label layers, const fvMesh& mesh, S field,
546 label secondTime)
547{
549 totalMagicPointsB = autoPtr<IOList<labelList >>
550 (
551 new IOList<labelList>
552 (
553 IOobject
554 (
555 "totalMagicPointsB",
556 para->runTime.time().constant(),
557 "../" + FolderM,
558 para->mesh,
559 IOobject::READ_IF_PRESENT,
560 IOobject::NO_WRITE
561 )
562 )
563 );
564 uniqueMagicPointsB = autoPtr<IOList<label >>
565 (
566 new IOList<label>
567 (
568 IOobject
569 (
570 "uniqueMagicPointsB",
571 para->runTime.time().constant(),
572 "../" + FolderM,
573 para->mesh,
574 IOobject::READ_IF_PRESENT,
575 IOobject::NO_WRITE
576 )
577 )
578 );
579 List<label> indices;
580 volScalarField Indici
581 (
582 IOobject
583 (
584 MatrixName + "_B_indices",
585 mesh.time().timeName(),
586 mesh,
587 IOobject::NO_READ,
588 IOobject::NO_WRITE
589 ),
590 mesh,
591 dimensionedScalar(MatrixName + "_B_indices", dimensionSet(0, 0, 0, 0, 0, 0, 0),
592 Foam::scalar(0))
593 );
594 submeshB = autoPtr<fvMeshSubset>(new fvMeshSubset(mesh));
595
596 for (label i = 0; i < magicPointsB().size(); i++)
597 {
598 indices = ITHACAutilities::getIndices(mesh, magicPointsB()[i], layers);
599 totalMagicPointsB().append(indices);
600
601 if (!secondTime)
602 {
603 ITHACAutilities::assignONE(Indici, indices);
604 }
605 }
606
608 std::cout.setstate(std::ios_base::failbit);
609#if OPENFOAM >= 1812
610 submeshB->setCellSubset(uniqueMagicPointsB());
611#else
612 submeshB->setLargeCellSubset(uniqueMagicPointsB());
613#endif
614 submeshB->subMesh().fvSchemes::readOpt() = mesh.fvSchemes::readOpt();
615 submeshB->subMesh().fvSolution::readOpt() = mesh.fvSolution::readOpt();
616 submeshB->subMesh().fvSchemes::read();
617 submeshB->subMesh().fvSolution::read();
618 std::cout.clear();
619 S f = submeshB->interpolate(field).ref();
620 scalar zerodot25 = 0.25;
621 ITHACAutilities::assignIF(Indici, zerodot25,
622 uniqueMagicPointsB().List<label>::clone()());
624
625 if (!secondTime)
626 {
628 ITHACAstream::exportSolution(Indici, "1", "./ITHACAoutput/DEIM/" + MatrixName
629 );
630 totalMagicPointsB().write();
631 uniqueMagicPointsB().write();
632 }
633
634 runSubMeshB = true;
635 return f;
636}
637
638
639template<typename T>
640List<label> DEIM<T>::global2local(List<label>& points,
641 fvMeshSubset& submesh)
642{
643 List<label> localPoints;
644
645 for (label i = 0; i < points.size(); i++)
646 {
647 for (label j = 0; j < submesh.cellMap().size(); j++)
648 {
649 if (submesh.cellMap()[j] == points[i])
650 {
651 localPoints.append(j);
652 break;
653 }
654 }
655 }
656
657 return localPoints;
658}
659
660template<typename T>
661void DEIM<T>::check3DIndices(label& ind_rowA, label& ind_colA, label& xyz_rowA,
662 label& xyz_colA)
663{
664 if (ind_rowA < Ncells)
665 {
666 xyz_rowA = 0;
667 }
668 else if (ind_rowA < Ncells * 2)
669 {
670 xyz_rowA = 1;
671 ind_rowA = ind_rowA - Ncells;
672 }
673 else
674 {
675 xyz_rowA = 2;
676 ind_rowA = ind_rowA - 2 * Ncells;
677 }
678
679 if (ind_colA < Ncells )
680 {
681 xyz_colA = 0;
682 }
683 else if (ind_colA < Ncells * 2)
684 {
685 xyz_colA = 1;
686 ind_colA = ind_colA - Ncells;
687 }
688 else
689 {
690 xyz_colA = 2;
691 ind_colA = ind_colA - 2 * Ncells;
692 }
693};
694
695template<typename T>
696void DEIM<T>::check3DIndices(label& ind_rowA, label& xyz_rowA)
697{
698 if (ind_rowA < Ncells)
699 {
700 xyz_rowA = 0;
701 }
702 else if (ind_rowA < Ncells * 2)
703 {
704 xyz_rowA = 1;
705 ind_rowA = ind_rowA - Ncells;
706 }
707 else
708 {
709 xyz_rowA = 2;
710 ind_rowA = ind_rowA - 2 * Ncells;
711 }
712};
713
714template<class T>
715template <class F>
717{
718 M_Assert(runSubMesh == true,
719 "You have to compute the magicPoints before calling this function, try to rerun generateSubmesh");
720 F f = submesh().interpolate(field).ref();
721 return f;
722}
723
724template<class T>
725template <class F>
727{
728 M_Assert(runSubMeshA == true,
729 "You have to compute the magicPointsA before calling this function, try to rerun generateSubmeshMatrix");
730 F f = submeshA().interpolate(field).ref();
731 return f;
732}
733
734template<typename T>
735template <class F>
737{
738 M_Assert(runSubMeshB == true,
739 "You have to compute the magicPointsB before calling this function, try to rerun generateSubmeshVector");
740 F f = submeshB().interpolate(field).ref();
741 return f;
742}
743
744
745template<> label DEIM<fvScalarMatrix>::getNcells(label sizeM)
746{
747 label Ncells = sizeM;
748 return Ncells;
749}
750
751template<> label DEIM<fvVectorMatrix>::getNcells(label sizeM)
752{
753 label Ncells = sizeM / 3;
754 return Ncells;
755}
756
757template<typename T>
758void DEIM<T>::setMagicPoints(labelList& newMagicPoints, labelList& newxyz)
759{
760 Folder = "ITHACAoutput/DEIM/" + FunctionName;
762 word command = "rm -r " + Folder + "/magicPoints";
763 system(command);
764 command = "rm -r " + Folder + "/xyz";
765 system(command);
766 command = "rm -r " + Folder + "/totalMagicPoints";
767 system(command);
768 command = "rm -r " + Folder + "/uniqueMagicPoints";
769 system(command);
770 magicPoints.reset
771 (
772 autoPtr<IOList<label >>
773 (
774 new IOList<label>
775 (
776 IOobject
777 (
778 "magicPoints",
779 para->runTime.time().constant(),
780 "../" + Folder,
781 para->mesh,
782 IOobject::READ_IF_PRESENT,
783 IOobject::NO_WRITE
784 )
785 )
786 )
787 );
788
789 for (label i = 0; i < newMagicPoints.size(); ++i)
790 {
791 magicPoints().append(newMagicPoints[i]);
792 }
793
794 xyz.reset
795 (
796 autoPtr<IOList<label >>
797 (
798 new IOList<label>
799 (
800 IOobject
801 (
802 "xyz",
803 para->runTime.time().constant(),
804 "../" + Folder,
805 para->mesh,
806 IOobject::READ_IF_PRESENT,
807 IOobject::NO_WRITE
808 )
809 )
810 )
811 );
812
813 for (label i = 0; i < newMagicPoints.size(); ++i)
814 {
815 xyz().append(newxyz[i]);
816 }
817
818 magicPoints().write();
819 xyz().write();
820}
821
822// Specialization of the constructor
823template DEIM<fvScalarMatrix>::DEIM (PtrList<fvScalarMatrix>& s,
824 label MaxModesA,
825 label MaxModesB, word MatrixName);
826template DEIM<fvVectorMatrix>::DEIM (PtrList<fvVectorMatrix>& s,
827 label MaxModesA,
828 label MaxModesB, word MatrixName);
829template DEIM<volScalarField>::DEIM(PtrList<volScalarField>& s, label MaxModes,
830 word FunctionName, word FieldName);
831template DEIM<volVectorField>::DEIM(PtrList<volVectorField>& s, label MaxModes,
832 word FunctionName, word FieldName);
833
834// Specialization for generateSubField
835template volVectorField DEIM<volScalarField>::generateSubField(
836 volVectorField& field);
837template volVectorField DEIM<volVectorField>::generateSubField(
838 volVectorField& field);
839template volScalarField DEIM<volScalarField>::generateSubField(
840 volScalarField& field);
841template volScalarField DEIM<volVectorField>::generateSubField(
842 volScalarField& field);
843template volTensorField DEIM<volScalarField>::generateSubField(
844 volTensorField& field);
845template volTensorField DEIM<volVectorField>::generateSubField(
846 volTensorField& field);
847template const volVectorField DEIM<volScalarField>::generateSubField(
848 const volVectorField& field);
849template const volVectorField DEIM<volVectorField>::generateSubField(
850 const volVectorField& field);
851template const volScalarField DEIM<volScalarField>::generateSubField(
852 const volScalarField& field);
853template const volScalarField DEIM<volVectorField>::generateSubField(
854 const volScalarField& field);
855template const volTensorField DEIM<volScalarField>::generateSubField(
856 const volTensorField& field);
857template const volTensorField DEIM<volVectorField>::generateSubField(
858 const volTensorField& field);
859
860// Specialization for generateSubFieldMatrix
862 volScalarField& field);
864 volVectorField& field);
865template surfaceScalarField
866DEIM<fvScalarMatrix>::generateSubFieldMatrix(surfaceScalarField& field);
867template surfaceVectorField
868DEIM<fvScalarMatrix>::generateSubFieldMatrix(surfaceVectorField& field);
870 volScalarField& field);
872 volVectorField& field);
873template surfaceScalarField
874DEIM<fvVectorMatrix>::generateSubFieldMatrix(surfaceScalarField& field);
875template surfaceVectorField
876DEIM<fvVectorMatrix>::generateSubFieldMatrix(surfaceVectorField& field);
877
878// Specialization for generateSubFieldVector
880 volScalarField& field);
882 volVectorField& field);
883template surfaceScalarField
884DEIM<fvScalarMatrix>::generateSubFieldVector(surfaceScalarField& field);
885template surfaceVectorField
886DEIM<fvScalarMatrix>::generateSubFieldVector(surfaceVectorField& field);
888 volScalarField& field);
890 volVectorField& field);
891template surfaceScalarField
892DEIM<fvVectorMatrix>::generateSubFieldVector(surfaceScalarField& field);
893template surfaceVectorField
894DEIM<fvVectorMatrix>::generateSubFieldVector(surfaceVectorField& field);
895
896// Specialization for generateSubmesh
897template volScalarField DEIM<volScalarField>::generateSubmesh(
898 label layers, const fvMesh& mesh, volScalarField field,
899 label secondTime);
900template volVectorField DEIM<volVectorField>::generateSubmesh(
901 label layers, const fvMesh& mesh, volVectorField field,
902 label secondTime);
903template volScalarField DEIM<volVectorField>::generateSubmesh(
904 label layers, const fvMesh& mesh, volScalarField field,
905 label secondTime);
906template volVectorField DEIM<volScalarField>::generateSubmesh(
907 label layers, const fvMesh& mesh, volVectorField field,
908 label secondTime);
909
910// Specialization for generateSubmeshVector
911template volScalarField DEIM<fvScalarMatrix>::generateSubmeshVector(
912 label layers, const fvMesh& mesh, volScalarField field, label secondTime);
913template volVectorField DEIM<fvScalarMatrix>::generateSubmeshVector(
914 label layers, const fvMesh& mesh, volVectorField field, label secondTime);
915template surfaceScalarField
916DEIM<fvScalarMatrix>::generateSubmeshVector(label layers, const fvMesh& mesh,
917 surfaceScalarField field, label secondTime);
918template surfaceVectorField
919DEIM<fvScalarMatrix>::generateSubmeshVector(label layers, const fvMesh& mesh,
920 surfaceVectorField field, label secondTime);
921template volScalarField DEIM<fvVectorMatrix>::generateSubmeshVector(
922 label layers, const fvMesh& mesh, volScalarField field, label secondTime);
923template volVectorField DEIM<fvVectorMatrix>::generateSubmeshVector(
924 label layers, const fvMesh& mesh, volVectorField field, label secondTime);
925template surfaceScalarField
926DEIM<fvVectorMatrix>::generateSubmeshVector(label layers, const fvMesh& mesh,
927 surfaceScalarField field, label secondTime);
928template surfaceVectorField
929DEIM<fvVectorMatrix>::generateSubmeshVector(label layers, const fvMesh& mesh,
930 surfaceVectorField field, label secondTime);
931
932// Specialization for generateSubmeshMatrix
933template volScalarField DEIM<fvScalarMatrix>::generateSubmeshMatrix(
934 label layers, const fvMesh& mesh, volScalarField field, label secondTime);
935template volVectorField DEIM<fvScalarMatrix>::generateSubmeshMatrix(
936 label layers, const fvMesh& mesh, volVectorField field, label secondTime);
937template surfaceScalarField
938DEIM<fvScalarMatrix>::generateSubmeshMatrix(label layers, const fvMesh& mesh,
939 surfaceScalarField field, label secondTime);
940template surfaceVectorField
941DEIM<fvScalarMatrix>::generateSubmeshMatrix(label layers, const fvMesh& mesh,
942 surfaceVectorField field, label secondTime);
943template volScalarField DEIM<fvVectorMatrix>::generateSubmeshMatrix(
944 label layers, const fvMesh& mesh, volScalarField field, label secondTime);
945template volVectorField DEIM<fvVectorMatrix>::generateSubmeshMatrix(
946 label layers, const fvMesh& mesh, volVectorField field, label secondTime);
947template surfaceScalarField
948DEIM<fvVectorMatrix>::generateSubmeshMatrix(label layers, const fvMesh& mesh,
949 surfaceScalarField field, label secondTime);
950template surfaceVectorField
951DEIM<fvVectorMatrix>::generateSubmeshMatrix(label layers, const fvMesh& mesh,
952 surfaceVectorField field, label secondTime);
953
954// specialization for setMagicPoints
955template void DEIM<volScalarField>::setMagicPoints(labelList& newMagicPoints,
956 labelList& newxyz);
957template void DEIM<volVectorField>::setMagicPoints(labelList& newMagicPoints,
958 labelList& newxyz);
autoPtr< fvMeshSubset > submeshA
Submesh of the DEIM method.
Definition DEIM.H:175
List< Eigen::SparseMatrix< double > > MatrixOnlineA
Online Matrices.
Definition DEIM.H:109
autoPtr< fvMeshSubset > submesh
Submesh of the DEIM method.
Definition DEIM.H:174
std::tuple< List< Eigen::SparseMatrix< double > >, List< Eigen::VectorXd > > Matrix_Modes
Definition DEIM.H:74
label MaxModes
The maximum number of modes to be considered.
Definition DEIM.H:77
autoPtr< IOList< label > > uniqueMagicPoints
List of unique indices that define the submesh.
Definition DEIM.H:138
autoPtr< IOList< label > > xyz_Arow
Definition of the x, y, z coordinate of the identified element in the matrix or source term 0 for x,...
Definition DEIM.H:152
List< label > localMagicPointsAcol
Indices of the local magic points in the subMesh.
Definition DEIM.H:161
S generateSubmesh(label layers, const fvMesh &mesh, S field, label secondTime=0)
Function to generate the submesh for the nonlinear function case.
Definition DEIM.C:359
autoPtr< IOList< label > > magicPointsAcol
Magic points in the case of the a matrix function (cols indices).
Definition DEIM.H:125
autoPtr< IOList< labelList > > totalMagicPointsA
Magic points and indices of the surrounding layers.
Definition DEIM.H:132
S generateSubmeshMatrix(label layers, const fvMesh &mesh, S field, label secondTime=0)
Function to generate the submesh for the nonlinear matrix function case (RHS).
Definition DEIM.C:452
Eigen::MatrixXd MatrixOnlineB
Online Matrices.
Definition DEIM.H:110
autoPtr< IOList< label > > magicPoints
Magic points in the case of the a nonlinear function.
Definition DEIM.H:121
List< label > localMagicPointsB
Indices of the local magic points in the subMesh.
Definition DEIM.H:162
S generateSubmeshVector(label layers, const fvMesh &mesh, S field, label secondTime=0)
Function to generate the submesh for the nonlinear matrix function case (LHS).
Definition DEIM.C:545
autoPtr< IOList< label > > xyz
Definition DEIM.H:151
word MatrixName
The name of the matrix.
Definition DEIM.H:101
autoPtr< IOList< label > > xyz_B
Definition DEIM.H:154
Eigen::MatrixXd U
Definition DEIM.H:115
DEIM(PtrList< T > &SnapShotsMatrix, label MaxModes, word FunctionName, word FieldName)
Construct DEIM for non-linear function.
Definition DEIM.C:34
List< label > localMagicPoints
Indices of the local magic points in the subMesh.
Definition DEIM.H:159
autoPtr< IOList< labelList > > totalMagicPoints
Magic points and indices of the surrounding layers.
Definition DEIM.H:131
F generateSubFieldVector(F &field)
Function to generate a a subfield in the location of the magic points computed for the Matrix (RHS).
Definition DEIM.C:736
Eigen::MatrixXd MatrixModes
Definition DEIM.H:104
autoPtr< IOList< label > > uniqueMagicPointsA
List of unique indices that define the submesh.
Definition DEIM.H:139
List< Eigen::SparseMatrix< double > > PA
Definition DEIM.H:168
List< label > localMagicPointsArow
Indices of the local magic points in the subMesh.
Definition DEIM.H:160
word Folder
Folder for nonlinear functions.
Definition DEIM.H:144
PtrList< fvScalarMatrix > modes
Definition DEIM.H:70
word FolderM
Folder in the matrix case.
Definition DEIM.H:146
autoPtr< IOList< label > > uniqueMagicPointsB
List of unique indices that define the submesh.
Definition DEIM.H:140
void check3DIndices(label &ind_rowA, label &ind_colA, label &xyz_rowA, label &xyz_colA)
check3DIndices in case of three dimensional fields
Definition DEIM.C:661
autoPtr< IOList< label > > magicPointsArow
Magic points in the case of the a matrix function (rows indices).
Definition DEIM.H:123
Eigen::SparseMatrix< double > P
Definition DEIM.H:167
autoPtr< IOList< labelList > > totalMagicPointsB
Magic points and indices of the surrounding layers.
Definition DEIM.H:133
autoPtr< IOList< label > > xyz_Acol
Definition DEIM.H:153
F generateSubField(F &field)
Function to generate a a subfield in the location of the magic points.
Definition DEIM.C:716
Eigen::MatrixXd MatrixOnline
Online Matrices.
Definition DEIM.H:108
bool runSubMesh
Bool variable to check if the SubMesh is available.
Definition DEIM.H:181
List< Eigen::SparseMatrix< double > > UA
Definition DEIM.H:116
autoPtr< fvMeshSubset > submeshB
Submesh of the DEIM method.
Definition DEIM.H:176
autoPtr< IOList< label > > magicPointsB
Magic points in the case of the a matrix function, right hand side.
Definition DEIM.H:127
label getNcells(label sizeM)
get the number of cells from the dimension of a LHS matrix
F generateSubFieldMatrix(F &field)
Function to generate a a subfield in the location of the magic points computed for the Matrix (LHS).
Definition DEIM.C:726
Eigen::SparseMatrix< double > PB
Definition DEIM.H:169
void setMagicPoints(labelList &newMagicPoints, labelList &newxyz)
Function to set the magic points externally.
Definition DEIM.C:758
PtrList< T > SnapShotsMatrix
The snapshots matrix containing the nonlinear function or operator.
Definition DEIM.H:67
Eigen::MatrixXd UB
Definition DEIM.H:117
word FunctionName
The name of the non-linear function.
Definition DEIM.H:82
List< label > global2local(List< label > &points, fvMeshSubset &submesh)
Get local indices in the submeshe from indices in the global ones.
Definition DEIM.C:640
bool runSubMeshA
Bool variable to check if the SubMesh is available.
Definition DEIM.H:182
bool runSubMeshB
Bool variable to check if the SubMesh is available.
Definition DEIM.H:183
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 for the definition of some general parameters, the parameters must be defined from the file ITH...
static ITHACAparameters * getInstance(const fvMesh &mesh, Time &localTime)
Gets an instance of ITHACAparameters, to be used if the instance is not existing.
Eigen::SparseMatrix< T > MVproduct(List< Eigen::SparseMatrix< T > > &A, Eigen::DenseBase< Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > > &C)
Sparse Matrix-Vector product between a list of sparse matrices and a vector of coefficients.
T max(Eigen::SparseMatrix< T > &mat, label &ind_row, label &ind_col)
Find the maximum of a sparse Matrix (Useful for DEIM).
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > innerProduct(List< Eigen::SparseMatrix< T > > &A, List< Eigen::SparseMatrix< T > > &B)
Perform Frobenius inner Product between two list of sparse matrices A and B.
List< Eigen::SparseMatrix< T > > MMproduct(List< Eigen::SparseMatrix< T > > &A, Eigen::DenseBase< Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > > &C)
Sparse Matrix - Dense Matrix product between a list of sparse matrices and a dense matrix.
std::tuple< List< Eigen::SparseMatrix< double > >, List< Eigen::VectorXd > > DEIMmodes(List< Eigen::SparseMatrix< double > > &A, List< Eigen::VectorXd > &b, label nmodesA, label nmodesB, word MatrixName)
Get the DEIM modes for a generic non a parametrized matrix coming from a differential operator functi...
Definition ITHACAPOD.C:1172
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.
void assignONE(volScalarField &s, List< label > &L)
Assign one to volScalarField.
List< T > combineList(List< List< T > > &doubleList)
Combine a list of list into a single list with unique elements.