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") {
109 else if (norm_type ==
"Linf") {
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;
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);
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));
222 pod.
setName(
"pod.test.solver");
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);
239 pod.
write(recon0,
"reconstruction0");
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()
std::vector< std::array< std::string, 3 > > getVectorNames()
const std::vector< pod::PODMode > & getModes()
std::vector< double > fieldsMax(pod::PODField &snap)
std::vector< std::string > getScalarNames()
const std::unordered_set< long int > & getListActiveIDs()
void setMeshType(MeshType type)
void setStaticMesh(bool flag)
std::vector< double > fieldsl2norm(pod::PODField &snap)
void setMemoryMode(MemoryMode mode)
void write(const pod::PODField &snap, std::string file_name) const
void setDirectory(const std::string &directory)
void readSnapshot(const pod::SnapshotFile &snap, pod::PODField &fieldr)
void reconstructFields(pod::PODField &field, pod::PODField &recon)
void setUseMean(bool flag)
std::vector< std::vector< double > > projectField(pod::PODField &field)
void setWriteMode(WriteMode mode)
void setEnergyLevel(double energy)
void setName(const std::string &name)
void setErrorMode(ErrorMode mode)
void addSnapshot(const std::string &directory, const std::string &name)
PiercedVector< Cell > & getCells()
T dotProduct(const std::array< T, d > &x, const std::array< T, d > &y)
Logger & cout(log::Level defaultSeverity, log::Visibility defaultVisibility)
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.