1#ifndef HLDO_SPHERE_WHITNEY_ONE_CURL_TEST_H
2#define HLDO_SPHERE_WHITNEY_ONE_CURL_TEST_H
8#include <lf/assemble/coomatrix.h>
9#include <lf/assemble/dofhandler.h>
10#include <lf/mesh/entity.h>
11#include <lf/mesh/hybrid2d/mesh.h>
12#include <lf/mesh/hybrid2d/mesh_factory.h>
13#include <lf/quad/quad.h>
14#include <rot_whitney_one_div_matrix_provider.h>
15#include <sphere_triag_mesh_builder.h>
22#include "whitney_one_basis_expansion_coeffs.h"
53 auto v = [](Eigen::Matrix<double, 3, 1> x) ->
double {
return 0; };
54 auto u = [](Eigen::Matrix<double, 3, 1> x) -> Eigen::Matrix<double, 3, 1> {
55 return Eigen::Matrix<double, 3, 1>::Zero();
60 meshs_ = std::vector<std::shared_ptr<const lf::mesh::Mesh>>(1);
78 std::unique_ptr<lf::mesh::MeshFactory> factory =
79 std::make_unique<lf::mesh::hybrid2d::MeshFactory>(3);
89 meshs_.resize(max_ref + 1);
92 std::chrono::steady_clock::time_point start_time_total =
93 std::chrono::steady_clock::now();
96 for (
unsigned lvl = 0; lvl <= max_ref; ++lvl) {
97 std::cout <<
"\nstart computation of max_ref " << lvl << std::flush;
100 std::chrono::steady_clock::time_point start_time =
101 std::chrono::steady_clock::now();
105 const std::shared_ptr<lf::mesh::Mesh> mesh = sphere.
Build();
109 std::chrono::steady_clock::time_point end_time =
110 std::chrono::steady_clock::now();
112 std::chrono::duration_cast<std::chrono::milliseconds>(end_time -
117 std::cout <<
" -> built mesh " << elapsed_sec <<
" [s] " << std::flush;
120 start_time = std::chrono::steady_clock::now();
139 lf::assemble::AssembleMatrixLocally<lf::assemble::COOMatrix<double>>(
140 0, dof_handler_cell, dof_handler_edge, matrix_div_provider, coo_mat);
145 one_coeffs.SetFunction(
u_);
146 one_coeffs.Compute();
147 Eigen::Matrix<double, Eigen::Dynamic, 1> u_h(n_dofs_edge);
148 u_h = one_coeffs.GetMu();
152 Eigen::Matrix<double, Eigen::Dynamic, 1> v_h(n_dofs_cell);
154 Eigen::MatrixXd points(3, 3);
156 Eigen::VectorXd midpoint =
157 (points.col(0) + points.col(1) + points.col(2)) / 3.;
160 midpoint = midpoint / midpoint.norm();
162 unsigned glob_idx = mesh->Index(*c);
163 v_h(glob_idx) =
v_(midpoint);
169 end_time = std::chrono::steady_clock::now();
170 elapsed_sec = std::chrono::duration_cast<std::chrono::milliseconds>(
171 end_time - start_time)
175 std::cout <<
" -> computed discret solution " << elapsed_sec <<
" [s] "
181 std::chrono::steady_clock::time_point end_time_total =
182 std::chrono::steady_clock::now();
183 double elapsed_sec_total =
184 std::chrono::duration_cast<std::chrono::milliseconds>(end_time_total -
189 std::cout <<
"\nTotal computation time for all levels " << elapsed_sec_total
195 std::string main_dir =
"results";
196 std::filesystem::create_directory(main_dir);
199 int table_width = 13;
203 std::ofstream csv_file;
204 std::string csv_name =
concat(
"whitney_one_curl_test_", max_ref);
205 std::replace(csv_name.begin(), csv_name.end(),
'.',
'_');
206 csv_file.open(
concat(main_dir,
"/", csv_name,
".csv"));
207 csv_file <<
"numCells,"
213 csv_file <<
",Errors";
214 csv_file << std::endl;
216 Eigen::VectorXd hMax(max_ref + 1);
222 auto &sol_mesh =
meshs_[lvl];
227 if (h > hMax(lvl)) hMax(lvl) = h;
231 csv_file << sol_mesh->NumEntities(0) <<
"," << sol_mesh->NumEntities(1)
232 <<
"," << sol_mesh->NumEntities(2) <<
"," << hMax(lvl);
256 std::function<
double(
const Eigen::Matrix<double, 3, 1> &)> v,
258 Eigen::Matrix<double, 3, 1>(
const Eigen::Matrix<double, 3, 1> &)>
265 std::function<double(
const Eigen::Matrix<double, 3, 1> &)>
v_;
266 std::function<Eigen::Matrix<double, 3, 1>(
267 const Eigen::Matrix<double, 3, 1> &)>
271 std::vector<std::shared_ptr<const lf::mesh::Mesh>>
meshs_;
A temporary data structure for matrix in COO format.
void setZero()
Erase all entries of the matrix.
Eigen::SparseMatrix< Scalar > makeSparse() const
Create an Eigen::SparseMatrix out of the COO format.
A general (interface) class for DOF handling, see Lecture Document Paragraph 2.7.4....
virtual size_type NumDofs() const =0
total number of dof's handled by the object
static constexpr RefEl kSegment()
Returns the (1-dimensional) reference segment.
static constexpr RefEl kTria()
Returns the reference triangle.
Interface class representing a topological entity in a cellular complex
Element matrix provider for rotated whitney one form.
Class to find the "best" basisexpansion coefficients with the analytical solution.
void SetMesh(std::shared_ptr< const lf::mesh::Mesh > mesh)
Tests convergence of the below bilinear form on the Mesh to the analytical solution.
std::function< double(const Eigen::Matrix< double, 3, 1 > &)> v_
std::function< Eigen::Matrix< double, 3, 1 >(const Eigen::Matrix< double, 3, 1 > &)> u_
void Compute(int max_ref)
Computes the error up to the refinemet level 'max_ref'.
Eigen::VectorXd discrete_sols_
std::vector< std::shared_ptr< const lf::mesh::Mesh > > meshs_
void SetAnaSol(double sol)
Sets the value of the analytical solution .
WhitneyOneCurlTest()
Constructor creates an object with zero testfunctions.
void SetFunctions(std::function< double(const Eigen::Matrix< double, 3, 1 > &)> v, std::function< Eigen::Matrix< double, 3, 1 >(const Eigen::Matrix< double, 3, 1 > &)> u)
Sets the test functions.
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.
unsigned int size_type
general type for variables related to size of arrays
lf::base::size_type size_type
Eigen::MatrixXd Corners(const Geometry &geo)
The corners of a shape with piecewise smooth boundary.
double Volume(const Geometry &geo)
Compute the (approximate) volume (area) of a shape.
static std::string concat(Args &&...args)
Concatenate objects defining an operator<<(std::ostream&)
Implementation of the thesis Hogde Laplacians and Dirac Operators on the surface of the 3-Sphere.