Loading...
Searching...
No Matches
08DEIM.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-------------------------------------------------------------------------------
12License
13 This file is part of ITHACA-FV
14 ITHACA-FV is free software: you can redistribute it and/or modify
15 it under the terms of the GNU Lesser General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18 ITHACA-FV is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU Lesser General Public License for more details.
22 You should have received a copy of the GNU Lesser General Public License
23 along with ITHACA-FV. If not, see <http://www.gnu.org/licenses/>.
24Description
25 Example of the reconstruction of a non-linear function using the DEIM
26SourceFiles
27 08DEIM.C
28\*---------------------------------------------------------------------------*/
29
30#include "fvCFD.H"
31#include "fvOptions.H"
32#include "simpleControl.H"
33#include "simpleControl.H"
34#include "fvMeshSubset.H"
35#include "ITHACAutilities.H"
36#include "Foam2Eigen.H"
37#include "ITHACAstream.H"
38#include "ITHACAPOD.H"
39#include "hyperReduction.templates.H"
40#include <chrono>
41class DEIM_function : public HyperReduction<PtrList<volScalarField> & >
42{
43 public:
45 static volScalarField evaluate_expression(volScalarField& S, Eigen::MatrixXd mu)
46 {
47 volScalarField yPos = S.mesh().C().component(vector::Y).ref();
48 volScalarField xPos = S.mesh().C().component(vector::X).ref();
49
50 for (auto i = 0; i < S.size(); i++)
51 {
52 S[i] = std::exp(- 2 * std::pow(xPos[i] - mu(0) - 1,
53 2) - 2 * std::pow(yPos[i] - mu(1) - 0.5, 2));
54 }
55
56 return S;
57 }
58
59 Eigen::VectorXd onlineCoeffs(Eigen::MatrixXd mu)
60 {
61 theta.resize(nodePoints().size());
62 auto f = evaluate_expression(subField(), mu);
63
64 for (int i = 0; i < nodePoints().size(); i++)
65 {
66 // double on_coeff = f[localMagicPoints[i]];
67 theta(i) = f[localNodePoints[i]];
68 }
69
70 return theta;
71 }
72
73 Eigen::VectorXd theta;
74 PtrList<volScalarField> fields;
75 autoPtr<volScalarField> subField;
76};
77
78int main(int argc, char* argv[])
79{
80 // Read parameters from ITHACAdict file
81#include "setRootCase.H"
82 Foam::Time runTime(Foam::Time::controlDictName, args);
83 Foam::fvMesh mesh
84 (
85 Foam::IOobject
86 (
87 Foam::fvMesh::defaultRegion,
88 runTime.timeName(),
89 runTime,
90 Foam::IOobject::MUST_READ
91 )
92 );
94 int NDEIM = para->ITHACAdict->lookupOrDefault<int>("NDEIM", 15);
95 simpleControl simple(mesh);
96#include "createFields.H"
97 // List of volScalarField where the snapshots are stored
98 PtrList<volScalarField> Sp;
99 // Non linear function
100 volScalarField S
101 (
102 IOobject
103 (
104 "S",
105 runTime.timeName(),
106 mesh,
107 IOobject::NO_READ,
108 IOobject::AUTO_WRITE
109 ),
110 T.mesh(),
111 dimensionedScalar("zero", dimensionSet(0, 0, -1, 1, 0, 0, 0), 0)
112 );
113 // Parameters used to train the non-linear function
114 Eigen::MatrixXd pars = ITHACAutilities::rand(100, 2, -0.5, 0.5);
115
116 // To compare with the same parameters, save data and then load it
117 // cnpy::load(pars, "./random100.npy");
118 // cnpy::save(pars, "./random100.npy");
119
120 // Perform the offline phase
121 for (int i = 0; i < 100; i++)
122 {
123 DEIM_function::evaluate_expression(S, pars.row(i));
124 Sp.append((S).clone());
125 ITHACAstream::exportSolution(S, name(i + 1), "./ITHACAoutput/Offline/");
126 }
127
128 Eigen::MatrixXd snapshotsModes;
129 // To use the DEIMmodes method from ITHACAPOD :
130 Eigen::VectorXd normalizingWeights = ITHACAutilities::getMassMatrixFV(
131 Sp[0]).array();
132 PtrList<volScalarField> modes = ITHACAPOD::DEIMmodes(Sp, NDEIM, "GappyDEIM",
133 S.name());
134 snapshotsModes = Foam2Eigen::PtrList2Eigen(modes);
135 // To use the SVD modes from the HyperReduction class :
136 // Eigen::VectorXd normalizingWeights;
137 // c.getModesSVD(c.snapshotsListTuple, snapshotsModes, normalizingWeights);
138 // Create DEIM object with given number of basis functions
139 Eigen::VectorXi initSeeds(0);
140 DEIM_function c(NDEIM, NDEIM, initSeeds, "DEIM", Sp);
141 // Compute the DEIM
142 c.offlineGappyDEIM(snapshotsModes, normalizingWeights);
143 // To access the same folder hierarchy as before :
144 // c.problemName = "Gaussian_function";
145 // c.offlineGappyDEIM(snapshotsModes, normalizingWeights, "ITHACAoutput/DEIM/"+c.problemName);
146 // Generate the submeshes with the depth of the layer
147 c.generateSubmesh(2, mesh);
148 c.subField = c.interpolateField<volScalarField>(Sp[0]);
149 // Define a new online parameter
150 Eigen::MatrixXd par_new(2, 1);
151 par_new(0, 0) = 0;
152 par_new(1, 0) = 0;
153 // Online evaluation of the non linear function
154 Eigen::VectorXd aprfield = c.MatrixOnline * c.onlineCoeffs(par_new);
155 // Transform to an OpenFOAM field and export
156 volScalarField S2("S_online", Foam2Eigen::Eigen2field(S, aprfield));
157 ITHACAstream::exportSolution(S2, name(1), "./ITHACAoutput/Online/");
158 // Evaluate the full order function and export it
159 DEIM_function::evaluate_expression(S, par_new);
160 ITHACAstream::exportSolution(S, name(1), "./ITHACAoutput/Online/");
161 // Compute the L2 error and print it
162 Info << ITHACAutilities::errorL2Rel(S2, S) << endl;
163 return 0;
164}
Header file of the Foam2Eigen class.
Header file of the ITHACAPOD class.
Header file of the ITHACAstream class, it contains the implementation of several methods for input ou...
Header file of the ITHACAutilities namespace.
HyperReduction(label n_modes, label n_nodes, Eigen::VectorXi initialSeeds, word problemName, SnapshotsLists &&...snapshotsLists)
Construct HyperReduction class, interpolation-based.
Eigen::VectorXd theta
Definition DEIM.H:89
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.
Definition Foam2Eigen.C:533
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
HyperReduction(label n_modes, label n_nodes, Eigen::VectorXi initialSeeds, word problemName, SnapshotsLists &&...snapshotsLists)
Construct HyperReduction class, interpolation-based.
Class for the definition of some general parameters, the parameters must be defined from the file ITH...
static ITHACAparameters * getInstance()
Gets an instance of ITHACAparameters, to be used if the instance is already existing.
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.
double errorL2Rel(GeometricField< T, fvPatchField, volMesh > &field1, GeometricField< T, fvPatchField, volMesh > &field2, List< label > *labels)
Computes the relative error between two geometric Fields in L2 norm.
Eigen::VectorXd getMassMatrixFV(GeometricField< Type, PatchField, GeoMesh > &snapshot)
Gets a vector containing the volumes of each cell of the mesh.
Eigen::MatrixXd rand(label rows, label cols, double min, double max)
Generates random matrix with random values in an interval.