8#include <lf/assemble/dofhandler.h>
11#include <lf/mesh/hybrid2d/hybrid2d.h>
12#include <lf/mesh/utils/utils.h>
13#include <lf/refinement/mesh_function_transfer.h>
14#include <lf/refinement/mesh_hierarchy.h>
15#include <lf/refinement/refinement.h>
16#include <lf/uscalfe/uscalfe.h>
26#include "strangsplitting.h"
31double getMeshSize(
const std::shared_ptr<const lf::mesh::Mesh>& mesh_p) {
32 double mesh_size = 0.0;
38 edge_length = (endpoints.col(0) - endpoints.col(1)).norm();
39 if (mesh_size < edge_length) {
40 mesh_size = edge_length;
46int main(
int ,
char** ) {
48 std::unique_ptr<lf::mesh::hybrid2d::MeshFactory> mesh_factory =
49 std::make_unique<lf::mesh::hybrid2d::MeshFactory>(2);
50 std::filesystem::path here = __FILE__;
51 auto mesh_file = (here.parent_path() /
"/meshes/test1.msh").
string();
53 std::shared_ptr<lf::mesh::Mesh> mesh_p = reader.mesh();
55 std::unique_ptr<lf::mesh::hybrid2d::MeshFactory> mesh_factory2 =
56 std::make_unique<lf::mesh::hybrid2d::MeshFactory>(2);
59 std::shared_ptr<lf::uscalfe::UniformScalarFESpace<double>> fe_space_fine;
61 Eigen::VectorXi numDofs(5);
63 Eigen::VectorXd meshsizes(5);
67 Eigen::VectorXd tau(5);
75 meshsizes(0) = 3.52544;
77 Eigen::VectorXd mu1(39);
79 Eigen::VectorXd mu2(125);
81 Eigen::VectorXd mu3(444);
83 Eigen::VectorXd mu4(1670);
85 Eigen::VectorXd mu5(6474);
88 Eigen::VectorXd mu1_ipol(6474);
90 Eigen::VectorXd mu2_ipol(6474);
92 Eigen::VectorXd mu3_ipol(6474);
94 Eigen::VectorXd mu4_ipol(6474);
98 auto c = [](
const Eigen::Vector2d & ) ->
double {
return 1.2; };
102 hierarchy.RefineRegular();
103 hierarchy.RefineRegular();
104 hierarchy.RefineRegular();
105 hierarchy.RefineRegular();
107 for (
int l = 4; l >= 0; l--) {
108 mesh_p = hierarchy.getMesh(l);
110 std::shared_ptr<lf::uscalfe::UniformScalarFESpace<double>> fe_space =
111 std::make_shared<lf::uscalfe::FeSpaceLagrangeO1<double>>(mesh_p);
117 meshsizes(l) = getMeshSize(mesh_p);
119 std::cout <<
"Num of Dofs " << N_dofs << std::endl;
120 std::cout <<
"Meshsizes " << meshsizes(l) << std::endl;
123 Eigen::VectorXd u0(N_dofs);
142 auto boundary_nodes = [&bd_flags, &dofh](
unsigned int idx) ->
bool {
143 return bd_flags(dofh.Entity(idx));
149 return bd_flags_edge(edge);
155 auto h = [fe_space, mesh_p, edge_pred](
const Eigen::Vector2d& x) ->
double {
158 auto g = [&x](
const Eigen::Vector2d& y) ->
double {
159 double tmp_res = 0.0;
160 if ((x - y).norm() >= 15 && (x - y).norm() <= 35) {
180 Eigen::MatrixXd L(N_dofs, N_dofs);
181 for (
int j = 0; j < N_dofs; j++) {
182 if (boundary_nodes(j)) {
183 auto L_j = [fe_space, &dofh, N_dofs, edge_pred,
184 j](
const Eigen::Vector2d& x) ->
double {
185 auto g_j = [&x](
const Eigen::Vector2d& y) ->
double {
186 double tmp_res = 0.0;
187 if ((x - y).norm() >= 15 && (x - y).norm() <= 35) {
193 Eigen::VectorXd L1(N_dofs);
199 edgeVec_y(fe_space, mf_g, edge_pred);
205 Eigen::VectorXd L2(N_dofs);
211 edgeVec_x(fe_space, mf_L, edge_pred);
218 L.col(j) = Eigen::VectorXd::Zero(N_dofs);
221 std::cout <<
"L norm " << L.norm() << std::endl;
229 tau(l) = (tau(0) / meshsizes(0)) * meshsizes(l);
230 m(l) = std::round(T / tau(l));
233 std::cout <<
"tau " << tau(l) << std::endl;
234 std::cout <<
"M " << m(l) << std::endl;
237 Eigen::VectorXd cap(N_dofs);
239 cap = 0.8 * Eigen::VectorXd::Ones(N_dofs);
243 StrangSplit StrangSplitter1(fe_space, T, m(0), lambda, c, h, L);
244 mu1 = StrangSplitter1.Evolution(cap, u0);
252 StrangSplit StrangSplitter2(fe_space, T, m(1), lambda, c, h, L);
253 mu2 = StrangSplitter2.Evolution(cap, u0);
260 StrangSplit StrangSplitter3(fe_space, T, m(2), lambda, c, h, L);
261 mu3 = StrangSplitter3.Evolution(cap, u0);
269 StrangSplit StrangSplitter4(fe_space, T, m(3), lambda, c, h, L);
270 mu4 = StrangSplitter4.Evolution(cap, u0);
278 StrangSplit StrangSplitter5(fe_space, T, m(4), lambda, c, h, L);
279 mu5 = StrangSplitter5.Evolution(cap, u0);
280 fe_space_fine = fe_space;
288 eL2(0) = (mu1_ipol - mu5).lpNorm<2>();
289 eL2(1) = (mu2_ipol - mu5).lpNorm<2>();
290 eL2(2) = (mu3_ipol - mu5).lpNorm<2>();
291 eL2(3) = (mu4_ipol - mu5).lpNorm<2>();
293 for (
int l = 0; l < 4; l++) {
294 std::cout <<
"numdofs for l = " << l <<
" : " << numDofs(l) << std::endl;
295 std::cout <<
"meshsize for l = " << l <<
" : " << meshsizes(l) << std::endl;
296 std::cout <<
"for l = " << l <<
"number of timesteps m : " << m(l)
298 std::cout <<
"for l = " << l <<
"timestep size : " << tau(l) << std::endl;
300 std::cout <<
"L2 error of solution with respect to reference solution on "
301 "finest mesh, for l = "
302 << l <<
" : " << eL2(l) << std::endl;
306 const static Eigen::IOFormat CSVFormat(Eigen::StreamPrecision,
307 Eigen::DontAlignCols,
", ",
"\n");
310 file.open(
"eL2.csv");
311 file << eL2.format(CSVFormat);
315 file << m.format(CSVFormat);
318 file.open(
"tau.csv");
319 file << tau.format(CSVFormat);
322 file.open(
"NumDofs.csv");
323 file << numDofs.format(CSVFormat);
326 file.open(
"meshsizes.csv");
327 file << meshsizes.format(CSVFormat);
331 file.open(
"mu1.csv");
332 file << mu1.format(CSVFormat);
335 file.open(
"mu2.csv");
336 file << mu2.format(CSVFormat);
339 file.open(
"mu3.csv");
340 file << mu3.format(CSVFormat);
343 file.open(
"mu4.csv");
344 file << mu4.format(CSVFormat);
347 file.open(
"mu5.csv");
348 file << mu5.format(CSVFormat);
352 file.open(
"mu1_ipol.csv");
353 file << mu1_ipol.format(CSVFormat);
356 file.open(
"mu2_ipol.csv");
357 file << mu2_ipol.format(CSVFormat);
360 file.open(
"mu3_ipol.csv");
361 file << mu3_ipol.format(CSVFormat);
364 file.open(
"mu4_ipol.csv");
365 file << mu4_ipol.format(CSVFormat);
A general (interface) class for DOF handling, see Lecture Document Paragraph 2.7.4....
static constexpr RefEl kSegment()
Returns the (1-dimensional) reference segment.
static constexpr RefEl kTria()
Returns the reference triangle.
A MeshFunction representing an element from a ScalarUniformFESpace (e.g. solution of BVP)
Reads a Gmsh *.msh file into a mesh::MeshFactory and provides a link between mesh::Entity objects and...
Interface class representing a topological entity in a cellular complex
MeshFunction wrapper for a simple function of physical coordinates.
auto squaredNorm(const A &a)
Pointwise squared norm of another mesh function.
A MeshFunction representing interpolation on a lf::refinement::MeshHierarchy.
A hierarchy of nested 2D hybrid meshes created by refinement.
Local edge contributions to element vector.
void AssembleVectorLocally(dim_t codim, const DofHandler &dof_handler, ENTITY_VECTOR_PROVIDER &entity_vector_provider, VECTOR &resultvector)
entity-local assembly of (right-hand-side) vectors from element vectors
QuadRule make_TriaQR_EdgeMidpointRule()
edge midpoint quadrature rule for reference triangles
auto localQuadFunction(const lf::mesh::Mesh &mesh, std::map< lf::base::RefEl, lf::quad::QuadRule > quadrules, FUNCTOR &&f, unsigned int codim, const std::function< bool(const lf::mesh::Entity &)> &pred)
auto NodalProjection(const lf::fe::ScalarFESpace< SCALAR > &fe_space, MF &&u, SELECTOR &&pred=base::PredicateTrue{})
Computes nodal projection of a mesh function and returns the finite element basis expansion coefficie...
Eigen::MatrixXd Corners(const Geometry &geo)
The corners of a shape with piecewise smooth boundary.
CodimMeshDataSet< bool > flagEntitiesOnBoundary(const std::shared_ptr< const Mesh > &mesh_p, lf::base::dim_t codim)
flag entities of a specific co-dimension located on the boundary
QuadRule make_QuadRule(base::RefEl ref_el, unsigned degree)
Returns a QuadRule object for the given Reference Element and Degree.
lf::assemble::size_type size_type