1#ifndef THESIS_EXPERIMENTS_HODGE_AND_DIRAC_H
2#define THESIS_EXPERIMENTS_HODGE_AND_DIRAC_H
7#include <dirac_operator_source_problem.h>
8#include <hodge_laplacians_source_problems.h>
9#include <lf/io/vtk_writer.h>
10#include <lf/mesh/hybrid2d/mesh_factory.h>
11#include <lf/mesh/utils/tp_triag_mesh_builder.h>
12#include <lf/mesh/utils/utils.h>
13#include <lf/quad/quad.h>
14#include <lf/refinement/refinement.h>
15#include <lf/uscalfe/uscalfe.h>
16#include <mesh_function_whitney_one.h>
17#include <mesh_function_whitney_two.h>
18#include <mesh_function_whitney_zero.h>
20#include <results_processing.h>
21#include <sphere_triag_mesh_builder.h>
31using complex = std::complex<double>;
70 std::function<
complex(
const Eigen::Matrix<double, 3, 1> &)> f_zero_dirac,
72 Eigen::Matrix<complex, 3, 1>(
const Eigen::Matrix<double, 3, 1> &)>
74 std::function<
complex(
const Eigen::Matrix<double, 3, 1> &)> f_two_dirac,
75 std::function<
complex(
const Eigen::Matrix<double, 3, 1> &)> f_zero,
77 Eigen::Matrix<complex, 3, 1>(
const Eigen::Matrix<double, 3, 1> &)>
79 std::function<
complex(
const Eigen::Matrix<double, 3, 1> &)> f_two,
80 double &k, std::string name)
99 void Compute(std::vector<unsigned> refinement_levels,
100 std::vector<double> ks) {
101 int nl = refinement_levels.size();
107 solutions_lap.
k = ks;
108 solutions_lap.
levels = refinement_levels;
109 solutions_lap.
mesh = std::vector<std::shared_ptr<const lf::mesh::Mesh>>(nl);
115 solutions_dirac.
k = ks;
116 solutions_dirac.levels = refinement_levels;
117 solutions_dirac.mesh =
118 std::vector<std::shared_ptr<const lf::mesh::Mesh>>(nl);
119 solutions_dirac.solutions = std::vector<
133 std::unique_ptr<lf::mesh::MeshFactory> factory =
134 std::make_unique<lf::mesh::hybrid2d::MeshFactory>(3);
143 std::chrono::steady_clock::time_point start_time_total =
144 std::chrono::steady_clock::now();
146 for (
unsigned il = 0; il < nl; ++il) {
147 unsigned lvl = refinement_levels[il];
149 solutions_lap.
solutions[il].mu_zero.resize(nk);
150 solutions_lap.
solutions[il].mu_one.resize(nk);
151 solutions_lap.
solutions[il].mu_two.resize(nk);
153 solutions_dirac.solutions[il].mu_zero.resize(nk);
154 solutions_dirac.solutions[il].mu_one.resize(nk);
155 solutions_dirac.solutions[il].mu_two.resize(nk);
157 for (
int ik = 0; ik < nk; ik++) {
159 std::cout <<
"\nStart computation of refinement_level " << lvl
160 <<
" and k = " <<
k_ << std::flush;
163 std::chrono::steady_clock::time_point start_time =
164 std::chrono::steady_clock::now();
168 const std::shared_ptr<lf::mesh::Mesh> mesh = sphere.
Build();
171 std::chrono::steady_clock::time_point end_time =
172 std::chrono::steady_clock::now();
174 std::chrono::duration_cast<std::chrono::milliseconds>(end_time -
179 std::cout <<
" -> Built Mesh " << elapsed_sec <<
" [s] " << std::flush;
181 solutions_lap.
mesh[lvl] = mesh;
182 solutions_dirac.mesh[lvl] = mesh;
185 hodge_builder.SetMesh(mesh);
186 hodge_builder.SetK(
k_);
192 start_time = std::chrono::steady_clock::now();
195 hodge_builder.Compute();
199 end_time = std::chrono::steady_clock::now();
200 elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(
201 end_time - start_time)
205 std::cout <<
" -> Computed LSE " << elapsed_sec <<
" [s] "
209 start_time = std::chrono::steady_clock::now();
212 hodge_builder.Solve();
213 dirac_builder.
Solve();
216 end_time = std::chrono::steady_clock::now();
218 elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(
219 end_time - start_time)
223 std::cout <<
" -> Solved System " << elapsed_sec <<
" [s] "
227 solutions_lap.
solutions[lvl].mu_zero[ik] = hodge_builder.GetMuZero();
228 solutions_lap.
solutions[lvl].mu_one[ik] =
229 std::get<0>(hodge_builder.GetMuOne());
230 solutions_lap.
solutions[lvl].mu_two[ik] =
231 std::get<1>(hodge_builder.GetMuTwo());
233 solutions_dirac.solutions[lvl].mu_zero[ik] = dirac_builder.
GetMu(0);
234 solutions_dirac.solutions[lvl].mu_one[ik] = dirac_builder.
GetMu(1);
235 solutions_dirac.solutions[lvl].mu_two[ik] = dirac_builder.
GetMu(2);
241 std::chrono::steady_clock::time_point end_time_total =
242 std::chrono::steady_clock::now();
243 double elapsed_sec_total =
244 std::chrono::duration_cast<std::chrono::milliseconds>(end_time_total -
249 std::cout <<
"\nTotal computation time for all levels " << elapsed_sec_total
252 projects::hldo_sphere::post_processing::compare_results<complex>(
253 name_, solutions_lap, solutions_dirac);
258 std::function<Eigen::Matrix<complex, 3, 1>(
259 const Eigen::Matrix<double, 3, 1> &)>
263 std::function<Eigen::Matrix<complex, 3, 1>(
264 const Eigen::Matrix<double, 3, 1> &)>
Creates and solves the discretised Hodge Laplacian source problems and the Dirac operator source Prob...
std::function< complex(const Eigen::Matrix< double, 3, 1 > &)> f_two_dirac_
std::function< Eigen::Matrix< complex, 3, 1 >(const Eigen::Matrix< double, 3, 1 > &)> f_one_dirac_
std::function< Eigen::Matrix< complex, 3, 1 >(const Eigen::Matrix< double, 3, 1 > &)> f_one_
std::function< complex(const Eigen::Matrix< double, 3, 1 > &)> f_zero_
std::function< complex(const Eigen::Matrix< double, 3, 1 > &)> f_two_
void Compute(std::vector< unsigned > refinement_levels, std::vector< double > ks)
Solves the Hodge Laplacian and the Dirac operator source problems for the tensor product of passed re...
std::function< complex(const Eigen::Matrix< double, 3, 1 > &)> f_zero_dirac_
HodgeAndDiracExperiment(std::function< complex(const Eigen::Matrix< double, 3, 1 > &)> f_zero_dirac, std::function< Eigen::Matrix< complex, 3, 1 >(const Eigen::Matrix< double, 3, 1 > &)> f_one_dirac, std::function< complex(const Eigen::Matrix< double, 3, 1 > &)> f_two_dirac, std::function< complex(const Eigen::Matrix< double, 3, 1 > &)> f_zero, std::function< Eigen::Matrix< complex, 3, 1 >(const Eigen::Matrix< double, 3, 1 > &)> f_one, std::function< complex(const Eigen::Matrix< double, 3, 1 > &)> f_two, double &k, std::string name)
Constructor setting all the functions and the reference k.
A mesh builder for regular 3-Sphere.
void setRefinementLevel(lf::base::size_type n)
Set the refinement level.
void setRadius(double r)
Sets the radius.
std::shared_ptr< lf::mesh::Mesh > Build()
Build the mesh.
Computes the Galerkin LSE for the Dirac Operator source problem.
void Compute()
Computes the Galerkin LSE for the dirac operator source problem.
Eigen::Matrix< double, Eigen::Dynamic, 1 > GetMu(int index)
retunrs the basis expansion coefficiants for the solution of the source problem
void Solve()
solves the linear systems build in Compute
void SetLoadFunctions(std::function< complex(const Eigen::Matrix< double, 3, 1 > &)> f0, std::function< Eigen::Matrix< complex, 3, 1 >(const Eigen::Matrix< double, 3, 1 > &)> f1, std::function< complex(const Eigen::Matrix< double, 3, 1 > &)> f2)
Sets the load functions.
void SetK(double k)
Sets k for the souce problems.
void SetMesh(std::shared_ptr< const lf::mesh::Mesh > mesh_p)
Sets the mesh.
Creates and solves the discretised Hodge Laplacian source problems.
Wrapper classes for experiments.
std::complex< double > complex
stores solutions for several k and one refinement level
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