1#ifndef HLDO_SPHERE_POST_PROCESSING_RESULTS_PROCESSING_H
2#define HLDO_SPHERE_POST_PROCESSING_RESULTS_PROCESSING_H
10#include <lf/io/vtk_writer.h>
11#include <mesh_function_whitney_one.h>
12#include <mesh_function_whitney_two.h>
13#include <mesh_function_whitney_zero.h>
15#include <sphere_triag_mesh_builder.h>
29namespace post_processing {
32using lf::uscalfe::operator-;
39template <
typename SCALAR>
41 std::vector<Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>>
mu_zero;
42 std::vector<Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>>
mu_one;
43 std::vector<Eigen::Matrix<SCALAR, Eigen::Dynamic, 1>>
mu_two;
52template <
typename SCALAR>
55 std::vector<double>
k;
57 std::vector<std::shared_ptr<const lf::mesh::Mesh>>
mesh;
67template <
typename... Args>
68static std::string
concat(Args &&...args) {
69 std::ostringstream ss;
95template <
typename SCALAR>
100 std::string main_dir =
"results";
101 std::filesystem::create_directory(main_dir);
104 int nk = results_lap.
k.size();
105 int nl = results_lap.
levels.size();
108 LF_ASSERT_MSG(nk == results_dirac.
k.size(),
109 "Results differ in the number of computed k");
110 LF_ASSERT_MSG(nl == results_dirac.
levels.size(),
111 "Results differ in the number of computed refinement levels");
114 int table_width = 13;
118 double min_k = results_lap.
k[0];
119 double max_k = results_lap.
k[nk - 1];
122 std::ofstream csv_file;
123 std::string csv_name =
concat(
"result_", name,
"_", min_k,
"-", max_k);
124 std::replace(csv_name.begin(), csv_name.end(),
'.',
'_');
125 csv_file.open(
concat(main_dir,
"/", csv_name,
".csv"));
126 csv_file <<
"numCells,"
132 auto square_scalar = [](SCALAR a) ->
double {
133 return std::abs(a) * std::abs(a);
136 [](Eigen::Matrix<SCALAR, Eigen::Dynamic, 1> a) ->
double {
137 return a.squaredNorm();
144 Eigen::MatrixXd L2ErrorZero = Eigen::MatrixXd::Zero(nl, nk);
145 Eigen::MatrixXd L2ErrorOne = Eigen::MatrixXd::Zero(nl, nk);
146 Eigen::MatrixXd L2ErrorTwo = Eigen::MatrixXd::Zero(nl, nk);
147 Eigen::VectorXd hMax = Eigen::VectorXd::Zero(nl);
150 for (
int i = 0; i < nk; i++) {
151 csv_file <<
",L2ErrorZero_" << results_lap.
k[i] <<
",RateL2ErrorZero_"
152 << results_lap.
k[i] <<
",L2ErrorOne_" << results_lap.
k[i]
153 <<
",RateL2ErrorOne_" << results_lap.
k[i] <<
",L2ErrorTwo_"
154 << results_lap.
k[i] <<
",RateL2ErrorTwo_" << results_lap.
k[i];
157 std::string kstr =
concat(results_lap.
k[i]);
158 std::replace(kstr.begin(), kstr.end(),
'.',
'_');
159 std::filesystem::create_directory(
concat(main_dir,
"/k_", kstr));
161 csv_file << std::endl;
167 for (
int i = 0; i < nk; i++) {
168 csv_file <<
"," << results_lap.
k[i] <<
"," << results_lap.
k[i] <<
","
169 << results_lap.
k[i] <<
"," << results_lap.
k[i] <<
","
170 << results_lap.
k[i] <<
"," << results_lap.
k[i];
172 csv_file << std::endl;
177 auto &sol_mesh = results_lap.
mesh[lvl];
178 auto &sol_mus_lap = results_lap.
solutions[lvl];
179 auto &sol_mus_dirac = results_dirac.
solutions[lvl];
184 if (h > hMax(lvl)) hMax(lvl) = h;
188 csv_file << sol_mesh->NumEntities(0) <<
"," << sol_mesh->NumEntities(1)
189 <<
"," << sol_mesh->NumEntities(2) <<
"," << hMax(lvl);
192 for (
int ik = 0; ik < nk; ik++) {
193 std::string kstr =
concat(results_lap.
k[ik]);
194 std::replace(kstr.begin(), kstr.end(),
'.',
'_');
195 std::string folder =
concat(main_dir,
"/k_", kstr);
198 mf_zero_lap(sol_mus_lap.mu_zero[ik], sol_mesh);
200 sol_mus_lap.mu_one[ik], sol_mesh);
202 sol_mus_lap.mu_two[ik], sol_mesh);
205 mf_zero_dirac(sol_mus_dirac.mu_zero[ik], sol_mesh);
207 mf_one_dirac(sol_mus_dirac.mu_one[ik], sol_mesh);
209 mf_two_dirac(sol_mus_dirac.mu_two[ik], sol_mesh);
212 auto mf_diff_zero = mf_zero_lap - mf_zero_dirac;
213 auto mf_diff_one = mf_one_lap - mf_one_dirac;
214 auto mf_diff_two = mf_two_lap - mf_two_dirac;
218 lvl,
"_k_", kstr,
".vtk"));
221 const std::pair<double, lf::mesh::utils::CodimMeshDataSet<double>>
223 sol_mesh, mf_diff_zero, square_scalar, qr);
224 L2ErrorZero(lvl, ik) = std::get<0>(L2_zero);
226 std::get<1>(L2_zero);
230 const std::pair<double, lf::mesh::utils::CodimMeshDataSet<double>>
232 sol_mesh, mf_diff_one, square_vector, qr);
233 L2ErrorOne(lvl, ik) = std::get<0>(L2_one);
239 const std::pair<double, lf::mesh::utils::CodimMeshDataSet<double>>
241 sol_mesh, mf_diff_two, square_scalar, qr);
242 L2ErrorTwo(lvl, ik) = std::get<0>(L2_two);
247 double l2RateZero = 0;
248 double l2RateOne = 0;
249 double l2RateTwo = 0;
254 (log(L2ErrorZero(lvl, ik)) - log(L2ErrorZero(lvl - 1, ik))) /
255 (log(hMax(lvl) / hMax(lvl - 1)));
256 l2RateOne = (log(L2ErrorOne(lvl, ik)) - log(L2ErrorOne(lvl - 1, ik))) /
257 (log(hMax(lvl) / hMax(lvl - 1)));
258 l2RateTwo = (log(L2ErrorTwo(lvl, ik)) - log(L2ErrorTwo(lvl - 1, ik))) /
259 (log(hMax(lvl) / hMax(lvl - 1)));
266 csv_file <<
"," << L2ErrorZero(lvl, ik) <<
"," << l2RateZero <<
","
267 << L2ErrorOne(lvl, ik) <<
"," << l2RateOne <<
","
268 << L2ErrorTwo(lvl, ik) <<
"," << l2RateTwo;
301template <
typename U_ZERO,
typename U_ONE,
typename U_TWO,
typename SCALAR>
303 U_ZERO &u_zero, U_ONE &u_one, U_TWO &u_two,
double &k) {
305 std::string main_dir =
"results";
306 std::filesystem::create_directory(main_dir);
309 int nk = results.
k.size();
310 int nl = results.
levels.size();
313 int table_width = 13;
317 double min_k = results.
k[0];
318 double max_k = results.
k[nk - 1];
321 std::ofstream csv_file;
322 std::string csv_name =
concat(
"result_", name,
"_", min_k,
"-", max_k);
323 std::replace(csv_name.begin(), csv_name.end(),
'.',
'_');
324 csv_file.open(
concat(main_dir,
"/", csv_name,
".csv"));
325 csv_file <<
"numCells,"
331 auto square_scalar = [](SCALAR a) ->
double {
332 return std::abs(a) * std::abs(a);
335 [](Eigen::Matrix<SCALAR, Eigen::Dynamic, 1> a) ->
double {
336 return a.squaredNorm();
343 Eigen::MatrixXd SupErrorZero = Eigen::MatrixXd::Zero(nl, nk);
344 Eigen::MatrixXd SupErrorOne = Eigen::MatrixXd::Zero(nl, nk);
345 Eigen::MatrixXd SupErrorTwo = Eigen::MatrixXd::Zero(nl, nk);
346 Eigen::MatrixXd L2ErrorZero = Eigen::MatrixXd::Zero(nl, nk);
347 Eigen::MatrixXd L2ErrorOne = Eigen::MatrixXd::Zero(nl, nk);
348 Eigen::MatrixXd L2ErrorTwo = Eigen::MatrixXd::Zero(nl, nk);
349 Eigen::VectorXd hMax = Eigen::VectorXd::Zero(nl);
352 for (
int i = 0; i < nk; i++) {
353 csv_file <<
",SupErrorZero_" << results.
k[i] <<
",RateSupErrorZero_"
354 << results.
k[i] <<
",SupErrorOne_" << results.
k[i]
355 <<
",RateSupErrorOne_" << results.
k[i] <<
",SupErrorTwo_"
356 << results.
k[i] <<
",RateSupErrorTwo_" << results.
k[i]
357 <<
",L2ErrorZero_" << results.
k[i] <<
",RateL2ErrorZero_"
358 << results.
k[i] <<
",L2ErrorOne_" << results.
k[i]
359 <<
",RateL2ErrorOne_" << results.
k[i] <<
",L2ErrorTwo_"
360 << results.
k[i] <<
",RateL2ErrorTwo_" << results.
k[i];
363 std::string kstr =
concat(results.
k[i]);
364 std::replace(kstr.begin(), kstr.end(),
'.',
'_');
365 std::filesystem::create_directory(
concat(main_dir,
"/k_", kstr));
367 csv_file << std::endl;
373 for (
int i = 0; i < nk; i++) {
374 csv_file <<
"," << results.
k[i] <<
"," << results.
k[i] <<
","
375 << results.
k[i] <<
"," << results.
k[i] <<
"," << results.
k[i]
376 <<
"," << results.
k[i] <<
"," << results.
k[i] <<
","
377 << results.
k[i] <<
"," << results.
k[i] <<
"," << results.
k[i]
378 <<
"," << results.
k[i] <<
"," << results.
k[i];
380 csv_file << std::endl;
385 auto &sol_mesh = results.
mesh[lvl];
391 if (h > hMax(lvl)) hMax(lvl) = h;
395 csv_file << sol_mesh->NumEntities(0) <<
"," << sol_mesh->NumEntities(1)
396 <<
"," << sol_mesh->NumEntities(2) <<
"," << hMax(lvl);
399 for (
int ik = 0; ik < nk; ik++) {
400 std::string kstr =
concat(results.
k[ik]);
401 std::replace(kstr.begin(), kstr.end(),
'.',
'_');
402 std::string folder =
concat(main_dir,
"/k_", kstr);
405 sol_mus.mu_zero[ik], sol_mesh);
407 sol_mus.mu_one[ik], sol_mesh);
409 sol_mus.mu_two[ik], sol_mesh);
419 auto mf_diff_zero = mf_zero - mf_zero_ana;
420 auto mf_diff_one = mf_one - mf_one_ana;
421 auto mf_diff_two = mf_two - mf_two_ana;
425 lvl,
"_k_", kstr,
".vtk"));
428 const std::pair<double, lf::mesh::utils::CodimMeshDataSet<double>>
430 sol_mesh, mf_diff_zero, square_scalar, qr);
431 L2ErrorZero(lvl, ik) = std::get<0>(L2_zero);
433 std::get<1>(L2_zero);
437 const std::pair<double, lf::mesh::utils::CodimMeshDataSet<double>>
439 sol_mesh, mf_diff_one, square_vector, qr);
440 L2ErrorOne(lvl, ik) = std::get<0>(L2_one);
446 const std::pair<double, lf::mesh::utils::CodimMeshDataSet<double>>
448 sol_mesh, mf_diff_two, square_scalar, qr);
449 L2ErrorTwo(lvl, ik) = std::get<0>(L2_two);
455 const std::pair<double, lf::mesh::utils::CodimMeshDataSet<double>>
457 sol_mesh, mf_diff_zero, square_scalar, qr);
458 SupErrorZero(lvl, ik) = std::get<0>(sup_zero);
460 std::get<1>(sup_zero);
462 data_set_error_sup_zero);
465 const std::pair<double, lf::mesh::utils::CodimMeshDataSet<double>>
467 sol_mesh, mf_diff_one, square_vector, qr);
468 SupErrorOne(lvl, ik) = std::get<0>(sup_one);
470 std::get<1>(sup_one);
472 data_set_error_sup_one);
475 const std::pair<double, lf::mesh::utils::CodimMeshDataSet<double>>
477 sol_mesh, mf_diff_two, square_scalar, qr);
478 SupErrorTwo(lvl, ik) = std::get<0>(sup_two);
480 std::get<1>(sup_two);
482 data_set_error_sup_two);
484 double l2RateZero = 0;
485 double l2RateOne = 0;
486 double l2RateTwo = 0;
487 double supRateZero = 0;
488 double supRateOne = 0;
489 double supRateTwo = 0;
494 (log(L2ErrorZero(lvl, ik)) - log(L2ErrorZero(lvl - 1, ik))) /
495 (log(hMax(lvl) / hMax(lvl - 1)));
496 l2RateOne = (log(L2ErrorOne(lvl, ik)) - log(L2ErrorOne(lvl - 1, ik))) /
497 (log(hMax(lvl) / hMax(lvl - 1)));
498 l2RateTwo = (log(L2ErrorTwo(lvl, ik)) - log(L2ErrorTwo(lvl - 1, ik))) /
499 (log(hMax(lvl) / hMax(lvl - 1)));
501 (log(SupErrorZero(lvl, ik)) - log(SupErrorZero(lvl - 1, ik))) /
502 (log(hMax(lvl) / hMax(lvl - 1)));
504 (log(SupErrorOne(lvl, ik)) - log(SupErrorOne(lvl - 1, ik))) /
505 (log(hMax(lvl) / hMax(lvl - 1)));
507 (log(SupErrorTwo(lvl, ik)) - log(SupErrorTwo(lvl - 1, ik))) /
508 (log(hMax(lvl) / hMax(lvl - 1)));
515 csv_file <<
"," << SupErrorZero(lvl, ik) <<
"," << supRateZero <<
","
516 << SupErrorOne(lvl, ik) <<
"," << supRateOne <<
","
517 << SupErrorTwo(lvl, ik) <<
"," << supRateTwo <<
","
518 << L2ErrorZero(lvl, ik) <<
"," << l2RateZero <<
","
519 << L2ErrorOne(lvl, ik) <<
"," << l2RateOne <<
","
520 << L2ErrorTwo(lvl, ik) <<
"," << l2RateTwo;
static constexpr RefEl kTria()
Returns the reference triangle.
Write a mesh along with mesh data into a vtk file.
void WriteCellData(const std::string &name, const mesh::utils::MeshDataSet< unsigned char > &mds, unsigned char undefined_value=0)
Add a new unsigned char attribute dataset that attaches data to the cells of the mesh (i....
Interface class representing a topological entity in a cellular complex
A MeshDataSet that attaches data of type T to every entity of a mesh that has a specified codimension...
MeshFunction wrapper for a simple function of physical coordinates.
Represents a Quadrature Rule over one of the Reference Elements.
Provides Mesh Function for given basis expansion coefficients.
Provides Mesh Function for Whitney two basis expansion coefficients.
Provides Mesh Function for basis expansion coefficients of the zero form.
unsigned int size_type
general type for variables related to size of arrays
double Volume(const Geometry &geo)
Compute the (approximate) volume (area) of a shape.
QuadRule make_QuadRule(base::RefEl ref_el, unsigned degree)
Returns a QuadRule object for the given Reference Element and Degree.
static std::string concat(Args &&...args)
Concatenate objects defining an operator<<(std::ostream&)
void process_results(std::string name, ProblemSolutionWrapper< SCALAR > &results, U_ZERO &u_zero, U_ONE &u_one, U_TWO &u_two, double &k)
Generate vtk files containing meshdata and a csv table with results.
std::pair< double, lf::mesh::utils::CodimMeshDataSet< double > > SupNorm(const std::shared_ptr< const lf::mesh::Mesh > &mesh_p, const MF &f, const SQ_F &sq_f, const lf::quad::QuadRule &quadrule)
Computes the supremum norm of the squared values of some MeshFunction (type MF) f.
std::pair< double, lf::mesh::utils::CodimMeshDataSet< double > > L2norm(const std::shared_ptr< const lf::mesh::Mesh > &mesh_p, const MF &f, const SQ_F &sq_f, const lf::quad::QuadRule &quadrule)
Computes the L2Norm of some MeshFunction (type MF) f.
void compare_results(std::string name, ProblemSolutionWrapper< SCALAR > &results_lap, ProblemSolutionWrapper< SCALAR > &results_dirac)
Generate vtk files containing meshdata and a csv table with results of the comparison of the two give...
Implementation of the thesis Hogde Laplacians and Dirac Operators on the surface of the 3-Sphere.
stores solutions for several k and one refinement level
std::vector< Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 > > mu_one
std::vector< Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 > > mu_zero
std::vector< Eigen::Matrix< SCALAR, Eigen::Dynamic, 1 > > mu_two
stores solutions and setupinformation for a list of refinement levels and k values
std::vector< std::shared_ptr< const lf::mesh::Mesh > > mesh
std::vector< ProblemSolution< SCALAR > > solutions
std::vector< unsigned > levels