LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
convergence_study2.cc
1#include <cmath>
2#include <fstream>
3#include <iomanip>
4
5#include "primal_dpg.h"
6#include "ultraweak_dpg.h"
7
8#define reflev 5
9
10int main() {
11 std::cout << "Convergence study 2: Ultraweak DPG method, smooth solution \n";
12 std::cout << "Exact solution: u(x,y) = sin(pi*x)sin(pi*y), homogenous "
13 "dirichlet b.c. \n";
14 std::cout << "BVP 1: epsilon_1=1.0, beta_1=[0.0,0.0] \n";
15 std::cout << "BVP 2: epsilon_2=1.0, beta_2=[2.0,1.0] \n ";
16 std::cout << "p = {0,1}";
17
18 // specify the two boundary value problems:
19 // exact solution:
20 const double PI = lf::base::kPi;
21 auto u_exact = [PI](const Eigen::Vector2d& x) -> double {
22 return std::sin(PI * x[0]) * std::sin(PI * x[1]);
23 };
24 auto u_grad = [PI](const Eigen::Vector2d& x) -> Eigen::Vector2d {
25 return (Eigen::VectorXd(2)
26 << PI * std::cos(PI * x[0]) * std::sin(PI * x[1]),
27 PI * std::sin(PI * x[0]) * std::cos(PI * x[1]))
28 .finished();
29 };
30
31 // BVP1:
32 auto epsilon_1 = [](const Eigen::Vector2d & /*x*/) -> double { return 1.0; };
33 auto beta_1 = [](const Eigen::Vector2d & /*x*/) -> Eigen::Vector2d {
34 return (Eigen::VectorXd(2) << 0.0, 0.0).finished();
35 };
36 auto f_1 = [PI](const Eigen::Vector2d& x) -> double {
37 return 2.0 * PI * PI * std::sin(PI * x[0]) * std::sin(PI * x[1]);
38 };
39 auto g_1 = [](const Eigen::Vector2d & /*x*/) -> double { return 0.0; };
40
41 // BVP 2:
42 auto epsilon_2 = [](const Eigen::Vector2d & /*x*/) -> double { return 1.0; };
43 auto beta_2 = [PI](const Eigen::Vector2d & /*x*/) -> Eigen::Vector2d {
44 return (Eigen::VectorXd(2) << 2.0, 1.0).finished();
45 };
46 auto f_2 = [PI](const Eigen::Vector2d& x) -> double {
47 return 2.0 * PI * PI * std::sin(PI * x[0]) * std::sin(PI * x[1]) +
48 PI * (2.0 * std::cos(PI * x[0]) * std::sin(PI * x[1]) +
49 std::sin(PI * x[0]) * std::cos(PI * x[1]));
50 };
51 auto g_2 = [](const Eigen::Vector2d & /*x*/) -> double { return 0.0; };
52
53 // BVP 1 on a triangular mesh
54 // run the convergence tests choosing different approxiamtion orders and
55 std::cout << "Running convergence tests for BVP 1 on a triangular mesh \n";
56 for (int deg_p = 0; deg_p <= 1; deg_p++) {
57 int delta_p = 2;
58 auto errors = projects::dpg::test::
59 TestConververgenceUltraWeakDPGConvectionDiffusionDirichletBVP(
60 reflev, u_exact, u_grad, epsilon_1, beta_1, f_1, g_1, deg_p,
61 delta_p, lf::base::RefEl::kTria());
62
63 // output to a corresponding file
64 std::string file_name = "cs2/triangular/bvp1_" + std::to_string(deg_p);
65 std::ofstream file(file_name);
66 for (auto [dofs, erroru, errorsigma, errorestimate] : errors) {
67 file << dofs << ", " << erroru << "," << errorsigma << ","
68 << errorestimate << std::endl;
69 }
70 file.close();
71 }
72
73 // BVP 2 on a triangular mesh
74 // run the convergence tests choosing different approxiamtion orders
75 std::cout << "Running convergence tests for BVP 2 on a triangular mesh \n";
76 for (int deg_p = 0; deg_p <= 1; deg_p++) {
77 int delta_p = 2;
78 auto errors = projects::dpg::test::
79 TestConververgenceUltraWeakDPGConvectionDiffusionDirichletBVP(
80 reflev, u_exact, u_grad, epsilon_2, beta_2, f_2, g_2, deg_p,
81 delta_p, lf::base::RefEl::kTria());
82
83 // output to a corresponding file
84 std::string file_name = "cs2/triangular/bvp2_" + std::to_string(deg_p);
85 std::ofstream file(file_name);
86 for (auto [dofs, erroru, errorsigma, errorestimate] : errors) {
87 file << dofs << ", " << erroru << "," << errorsigma << ","
88 << errorestimate << std::endl;
89 }
90 file.close();
91 }
92
93 // BVP 1 on a quadrilateral mesh
94 // run the convergence tests choosing different approxiamtion orders
95 std::cout << "Running convergence tests for BVP 1 on a quadrilateral mesh \n";
96 for (int deg_p = 0; deg_p <= 1; deg_p++) {
97 int delta_p = 2;
98 auto errors = projects::dpg::test::
99 TestConververgenceUltraWeakDPGConvectionDiffusionDirichletBVP(
100 reflev, u_exact, u_grad, epsilon_1, beta_1, f_1, g_1, deg_p,
101 delta_p, lf::base::RefEl::kQuad());
102
103 // output to a corresponding file
104 std::string file_name = "cs2/quadrilateral/bvp1_" + std::to_string(deg_p);
105 std::ofstream file(file_name);
106 for (auto [dofs, erroru, errorsigma, errorestimate] : errors) {
107 file << dofs << ", " << erroru << "," << errorsigma << ","
108 << errorestimate << std::endl;
109 }
110 file.close();
111 }
112
113 // BVP 2 on a quadrilateral mesh
114 // run the convergence tests choosing different approxiamtion orders and
115 // enrichement degrees:
116 std::cout << "Running convergence tests for BVP 2 on a quadrilateral mesh \n";
117 for (int deg_p = 0; deg_p <= 1; deg_p++) {
118 int delta_p = 2;
119 auto errors = projects::dpg::test::
120 TestConververgenceUltraWeakDPGConvectionDiffusionDirichletBVP(
121 reflev, u_exact, u_grad, epsilon_2, beta_2, f_2, g_2, deg_p,
122 delta_p, lf::base::RefEl::kQuad());
123
124 // output to a corresponding file
125 std::string file_name = "cs2/quadrilateral/bvp2_" + std::to_string(deg_p);
126 std::ofstream file(file_name);
127 for (auto [dofs, erroru, errorsigma, errorestimate] : errors) {
128 file << dofs << ", " << erroru << "," << errorsigma << ","
129 << errorestimate << std::endl;
130 }
131 file.close();
132 }
133
134 return 0;
135}
static constexpr RefEl kTria()
Returns the reference triangle.
Definition: ref_el.h:158
static constexpr RefEl kQuad()
Returns the reference quadrilateral.
Definition: ref_el.h:166
constexpr double kPi
Definition: base.h:43