48#include "pod_voloctree.hpp"
49#include "pod_kernel.hpp"
50#include "piercedStorage.hpp"
52using namespace bitpit;
67 errorField.
scalar->fill(0.0);
68 errorField.
vector->fill(std::array<double, 3>{{0.0, 0.0, 0.0}});
70 errorField.
mask->fill(0.0);
72 for (
long id : listActIds) {
73 for (std::size_t isf = 0; isf < 2; ++isf) {
74 double field1s = field1.
scalar->at(
id, isf);
75 double field2s = field2.
scalar->at(
id, isf);
76 errorField.
scalar->at(
id, isf) += field1s-field2s;
78 std::array<double,3> field1sv = field1.
vector->at(
id,0);
79 std::array<double,3> field2sv = field2.
vector->at(
id,0);
80 errorField.
vector->at(
id, 0) += field1sv-field2sv;
81 errorField.
mask->at(
id) = 1;
100 errorField.
scalar->fill(0.0);
101 errorField.
vector->fill(std::array<double, 3>{{0.0, 0.0, 0.0}});
103 errorField.
mask->fill(0.0);
105 std::vector<double> vec;
106 if (norm_type ==
"L2") {
107 vec =
pod.fieldsl2norm(field1);
109 else if (norm_type ==
"Linf") {
110 vec =
pod.fieldsMax(field1);
112 const std::unordered_set<long> & listActIds =
pod.getListActiveIDs();
113 for (
long id : listActIds) {
114 for (std::size_t isf = 0; isf < 2; ++isf) {
115 double field1s = field1.
scalar->at(
id, isf);
116 double field2s = field2.
scalar->at(
id, isf);
117 errorField.
scalar->at(
id, isf) += (field1s-field2s)/vec[isf];
119 std::array<double,3> field1sv = field1.
vector->at(
id,0);
120 std::array<double,3> field2sv = field2.
vector->at(
id,0);
121 errorField.
vector->at(
id, 0) += (field1sv-field2sv)/vec[2];
122 errorField.
mask->at(
id) = 1;
137 std::vector<double> vecL2 =
pod.fieldsl2norm(field);
138 std::vector<std::string> scalarNames =
pod.getScalarNames();
139 std::vector<std::array<std::string,3>> vectorNames=
pod.getVectorNames();
140 int N = scalarNames.size();
141 for (
int i=0; i<N; i++) {
142 std::cout <<
"L2 norm of " << field_name <<
" " << scalarNames[i] <<
" is "<< vecL2[i] << std::endl;
144 int M = vectorNames.size();
145 for (
int i=N; i<N+M; i++) {
146 std::cout <<
"L2 norm of " << field_name <<
" " << vectorNames[i-N][0].substr(0,vectorNames[i-N][0].size()-2) <<
" is "<< vecL2[i] << std::endl;
159 std::vector<double> vecLinf =
pod.fieldsMax(field);
160 std::vector<std::string> scalarNames =
pod.getScalarNames();
161 std::vector<std::array<std::string,3>> vectorNames=
pod.getVectorNames();
162 int N = scalarNames.size();
163 for (
int i=0; i<N; i++) {
164 std::cout <<
"L infinity norm of " << field_name <<
" " << scalarNames[i] <<
" is "<< vecLinf[i] << std::endl;
166 int M = vectorNames.size();
167 for (
int i=N; i<N+M; i++) {
168 std::cout <<
"L infinity norm of " << field_name <<
" " << vectorNames[i-N][0].substr(0,vectorNames[i-N][0].size()-2) <<
" is "<< vecLinf[i] << std::endl;
177void printMat (std::vector<std::vector<double>> mat)
179 std::cout <<
"mat = " << std::endl;
180 size_t M = mat.size();
181 size_t N = mat[0].size();
182 for (
size_t i=0; i<M; i++) {
183 for (
size_t j=0; j<N; j++) {
185 std::cout <<
"[ "<< mat[i][j] ;
188 std::cout <<
" , " << mat[i][j] <<
" ]" << std::endl;
191 std::cout <<
" , " << mat[i][j] ;
194 std::cout <<
" ]" << std::endl;
209 for (
int i=0; i<6; i++) {
210 pod.addSnapshot(
"./data",
"test_set2."+std::to_string(i));
215 pod.setStaticMesh(
true);
219 pod.setEnergyLevel(99.00);
220 pod.setUseMean(
false);
221 pod.setDirectory(
"pod");
222 pod.setName(
"pod.test.solver");
225 pod.evalDecomposition();
230 pod.readSnapshot(snap0, solution0);
231 pod.write(solution0,
"solution0");
234 std::vector<std::vector<double>> recostructionCoeffs =
pod.projectField(solution0);
235 std::cout <<
"POD coefficients of the first snapshot " << std::endl;
236 printMat(recostructionCoeffs);
238 pod.reconstructFields(recostructionCoeffs, recon0);
239 pod.write(recon0,
"reconstruction0");
242 const std::unordered_set<long> & listActIds =
pod.getListActiveIDs();
243 pod::PODField error0 = buildErrorField(solution0, recon0, listActIds);
244 pod::PODField error0relL2 = buildRelErrorField(solution0, recon0,
pod,
"L2");
245 pod::PODField error0relLinf = buildRelErrorField(solution0, recon0,
pod,
"Linf");
246 printL2norm(solution0,
pod,
"solution");
247 printLinfnorm(solution0,
pod,
"solution");
248 printL2norm(error0,
pod,
"reconstruction error");
249 printLinfnorm(error0,
pod,
"reconstruction error");
250 printL2norm(error0relL2,
pod,
"relative error");
251 printLinfnorm(error0relLinf,
pod,
"relative error");
259 pod2.
setName(
"pod.test.solver");
262 std::cout <<
"the number of modes of pod 2 is " << pod2.
getModeCount() << std::endl;
263 std::cout <<
"the number of modes of pod is " <<
pod.getModeCount() << std::endl;
265 const std::vector<pod::PODMode> &vec_pod_modes = pod2.
getModes();
268 std::cout <<
"Number of active cells for pod2 object = ";
269 std::cout << listActIds_2.size() << std::endl;
271 std::cout <<
"Number of active cells for pod object = ";
272 std::cout << listActIds.size() << std::endl;
276 double coeff11 = recostructionCoeffs[0][0];
277 double coeff12 = recostructionCoeffs[0][1];
278 double coeff21 = recostructionCoeffs[1][0];
279 double coeff22 = recostructionCoeffs[1][1];
280 double coeff31 = recostructionCoeffs[2][0];
281 double coeff32 = recostructionCoeffs[2][1];
282 double scalar1_diff = 0;
283 double scalar2_diff = 0;
284 double vector1_diff = 0;
285 for (
long id : listActIds_2) {
286 double mode1 = vec_pod_modes[0].scalar->at(
id, 0);
287 double mode2 = vec_pod_modes[1].scalar->at(
id, 0);
288 scalar1_diff += coeff11*mode1+coeff12*mode2-recon0.
scalar->at(
id, 0);
289 mode1 = vec_pod_modes[0].scalar->at(
id, 1);
290 mode2 = vec_pod_modes[1].scalar->at(
id, 1);
291 scalar2_diff += coeff21*mode1+coeff22*mode2-recon0.
scalar->at(
id, 1);
292 std::array<double,3> mode1v = vec_pod_modes[0].vector->at(
id, 0);
293 std::array<double,3> mode2v = vec_pod_modes[1].vector->at(
id, 0);
294 std::array<double,3> diffv = recon0.
vector->at(
id, 0);
295 diffv -= coeff31*mode1v+coeff32*mode2v;
296 vector1_diff += std::sqrt(
dotProduct((diffv),(diffv)));
298 std::cout <<
" " << std::endl;
299 std::cout <<
"The absolute error between the reconstruction and the linear combination of the restored modes is " << std::endl;
300 std::cout << scalar1_diff <<
" for the first scalar field, " << std::endl;
301 std::cout << scalar2_diff <<
" for the second scalar field, "<< std::endl;
302 std::cout << vector1_diff <<
" for the first vector field. "<< std::endl;
308int main(
int argc,
char *argv[])
311 MPI_Init(&argc,&argv);
317 }
catch (
const std::exception &exception) {
The POD (Proper Orthogonal Decomposition) class provides an interface for defining POD object.
std::size_t getModeCount()
const std::vector< pod::PODMode > & getModes()
const std::unordered_set< long int > & getListActiveIDs()
void setDirectory(const std::string &directory)
void setUseMean(bool flag)
void setWriteMode(WriteMode mode)
void setName(const std::string &name)
PiercedVector< Cell > & getCells()
Metafunction for generating a pierced storage.
T dotProduct(const std::array< T, d > &x, const std::array< T, d > &y)
Logger & cout(log::Level defaultSeverity, log::Visibility defaultVisibility)
The namespace 'pod' contains structures for working with the POD class.
PiercedStorage< std::array< double, 3 > > VectorStorage
PiercedStorage< double > ScalarStorage
The PODfield structure is used to store the fields inside POD classes.
std::unique_ptr< pod::ScalarStorage > scalar
std::unique_ptr< PiercedStorage< bool > > mask
std::unique_ptr< pod::VectorStorage > vector
void setMesh(VolumeKernel *lmesh)
The SnapFile structure is used to store the file names inside POD classes.