6#define _USE_MATH_DEFINES
7#include <build_system_matrix.h>
8#include <lf/assemble/dofhandler.h>
9#include <lf/io/gmsh_reader.h>
10#include <lf/io/vtk_writer.h>
11#include <lf/mesh/entity.h>
12#include <lf/mesh/hybrid2d/mesh_factory.h>
13#include <lf/mesh/utils/tp_triag_mesh_builder.h>
14#include <lf/mesh/utils/utils.h>
15#include <lf/quad/quad.h>
16#include <lf/refinement/mesh_function_transfer.h>
17#include <lf/refinement/refinement.h>
18#include <mesh_function_velocity.h>
20#include <piecewise_const_element_matrix_provider.h>
21#include <piecewise_const_element_vector_provider.h>
22#include <solution_to_mesh_data_set.h>
31using lf::uscalfe::operator-;
32using lf::uscalfe::operator*;
40template <
typename... Args>
41static std::string concat(Args &&... args) {
42 std::ostringstream ss;
51 std::shared_ptr<const lf::mesh::Mesh>
mesh;
52 std::shared_ptr<const lf::assemble::DofHandler>
dofh;
53 Eigen::SparseMatrix<double>
A;
69 const unsigned refinement_level = 7;
72 std::unique_ptr<lf::mesh::MeshFactory> factory =
73 std::make_unique<lf::mesh::hybrid2d::MeshFactory>(2);
79 auto mesh0 = builder.
Build();
82 const auto mesh_hierarchy =
87 std::vector<ProblemSolution> solutions(refinement_level + 1);
89 const auto &mesh = mesh_hierarchy->getMesh(lvl);
90 auto &sol = solutions[lvl];
92 sol.dofh = std::shared_ptr<const lf::assemble::DofHandler>(
97 auto f = [](
const Eigen::Vector2d & ) -> Eigen::Vector2d {
98 return Eigen::Vector2d::Zero();
101 auto dirichlet_funct = [](
const lf::mesh::Entity &edge) -> Eigen::Vector2d {
102 static constexpr double eps = 1e-10;
103 const auto *
const geom = edge.Geometry();
104 const auto vertices = geom->Global(edge.RefEl().NodeCoords());
107 if (vertices(1, 0) <= 1 + eps && vertices(1, 0) >= 1 - eps &&
108 vertices(1, 1) <= 1 + eps && vertices(1, 1) >= 1 - eps) {
111 return Eigen::Vector2d::Zero();
113 const auto [A, rhs] =
115 sol.mesh, *(sol.dofh), f, dirichlet_funct, 100,
117 sol.A = A.makeSparse();
119 Eigen::SparseLU<Eigen::SparseMatrix<double>> solver;
120 solver.compute(sol.A);
121 sol.solution = solver.solve(rhs);
122 const auto [A_modified, rhs_modified] =
124 sol.mesh, *(sol.dofh), f, dirichlet_funct, 100,
126 sol.A_modified = A_modified.makeSparse();
127 Eigen::SparseLU<Eigen::SparseMatrix<double>> solver_modified(
129 sol.solution_modified = solver_modified.solve(rhs_modified);
133 const auto fe_space_fine =
134 std::make_shared<lf::uscalfe::FeSpaceLagrangeO1<double>>(
135 solutions.back().mesh);
137 velocity_exact(fe_space_fine, solutions.back().solution);
139 velocity_exact_modified(fe_space_fine,
140 solutions.back().solution_modified);
143 const auto fe_space_lvl =
144 std::make_shared<lf::uscalfe::FeSpaceLagrangeO1<double>>(
145 solutions[lvl].mesh);
147 velocity_lvl(fe_space_lvl, solutions[lvl].solution);
149 velocity_lvl_modified(fe_space_lvl, solutions[lvl].solution_modified);
151 *mesh_hierarchy, velocity_lvl, lvl, mesh_hierarchy->NumLevels() - 1);
153 *mesh_hierarchy, velocity_lvl_modified, lvl,
154 mesh_hierarchy->NumLevels() - 1);
155 writer.WriteCellData(concat(
"v_", solutions[lvl].mesh->NumEntities(2)),
157 writer.WriteCellData(
158 concat(
"v_modified", solutions[lvl].mesh->NumEntities(2)),
159 velocity_fine_modified);
166 return x[1] >= 0.9 ? (1 - std::cos(M_PI / 0.1 * (1 - x[1]))) / 2 : 1.;
168 const auto diff = velocity_fine - velocity_exact;
169 const auto diff_weighted = weight * diff;
170 const auto diff_modified = velocity_fine_modified - velocity_exact_modified;
171 const auto diff_weighted_modified = weight * diff_modified;
173 solutions.back().mesh, diff, qr_provider);
175 solutions.back().mesh, diff_weighted, qr_provider);
177 solutions.back().mesh, diff,
179 Eigen::Matrix2d::Zero()),
182 solutions.back().mesh, diff_modified, qr_provider);
184 solutions.back().mesh, diff_weighted_modified, qr_provider);
186 solutions.back().mesh, diff_modified,
188 Eigen::Matrix2d::Zero()),
190 std::cout << lvl <<
' ' << solutions[lvl].mesh->NumEntities(2) <<
' ' << L2
191 <<
' ' << L2w <<
' ' << DG <<
' ' << L2_modified <<
' '
192 << L2w_modified <<
' ' << DG_modified << std::endl;
static constexpr RefEl kSegment()
Returns the (1-dimensional) reference segment.
static constexpr RefEl kPoint()
Returns the (0-dimensional) reference point.
Write a mesh along with mesh data into a vtk file.
Interface class representing a topological entity in a cellular complex
A MeshFunction which takes the same constant value on the whole mesh.
MeshFunction wrapper for a simple function of physical coordinates.
StructuredMeshBuilder & setTopRightCorner(const VECTOR &&trc)
StructuredMeshBuilder & setBottomLeftCorner(const VECTOR &blc)
StructuredMeshBuilder & setNumXCells(size_type nxc)
StructuredMeshBuilder & setNumYCells(size_type nyc)
Implements a MeshBuilder that generates a triangular structured mesh.
std::shared_ptr< mesh::Mesh > Build() override
actual construction of the mesh
A MeshFunction representing interpolation on a lf::refinement::MeshHierarchy.
A MeshFunction returning the velocity computed from the basis function coefficients of a vector poten...
unsigned int size_type
general type for variables related to size of arrays
QuadRule make_TriaQR_MidpointRule()
midpoint quadrature rule for triangles
QuadRule make_QuadRule(base::RefEl ref_el, unsigned degree)
Returns a QuadRule object for the given Reference Element and Degree.
std::shared_ptr< MeshHierarchy > GenerateMeshHierarchyByUniformRefinemnt(const std::shared_ptr< lf::mesh::Mesh > &mesh_p, lf::base::size_type ref_lev, RefPat ref_pat)
Generated a sequence of nested 2D hybrid mehes by regular or barycentric refinement.
std::tuple< lf::assemble::COOMatrix< double >, Eigen::VectorXd > buildSystemMatrixNoFlow(const std::shared_ptr< const lf::mesh::Mesh > &mesh, const lf::assemble::DofHandler &dofh, const std::function< Eigen::Vector2d(const Eigen::Vector2d &)> &f, const std::function< Eigen::Vector2d(const lf::mesh::Entity &)> &dirichlet_data, double sigma, const lf::quad::QuadRule &quadrule, bool modified_penalty)
Build the system matrix for the stokes system with no flow boundary conditions.
double DGnorm(const std::shared_ptr< const lf::mesh::Mesh > &mesh, const MF_F &f, const MF_GRAD &f_grad, const QR_SELECTOR &qr_selector)
Compute the DG-norm of a vector valued function over a mesh.
double L2norm(const std::shared_ptr< const lf::mesh::Mesh > &mesh, const MF &f, const QR_SELECTOR &qr_selector)
Compute the -norm of a vector valued function over a mesh.
stores information to recover convergence properties
Eigen::SparseMatrix< double > A_modified
Eigen::VectorXd solution_modified
Eigen::SparseMatrix< double > A
std::shared_ptr< const lf::mesh::Mesh > mesh
std::shared_ptr< const lf::assemble::DofHandler > dofh