DUBeat 1.0.1
High-order discontinuous Galerkin methods and applications to cardiac electrophysiology
Loading...
Searching...
No Matches
laplace_dg.hpp
Go to the documentation of this file.
1/********************************************************************************
2 Copyright (C) 2024 by the DUBeat authors.
3
4 This file is part of DUBeat.
5
6 DUBeat is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 DUBeat is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with DUBeat. If not, see <http://www.gnu.org/licenses/>.
18********************************************************************************/
19
27#ifndef LAPLACE_DG_HPP_
28#define LAPLACE_DG_HPP_
29
30#include <memory>
31#include <vector>
32
33#include "../source/DUBValues.hpp"
34#include "../source/DUB_FEM_handler.hpp"
35#include "../source/assemble_DG.hpp"
36#include "../source/face_handler_DG.hpp"
37#include "../source/model_DG.hpp"
38#include "../source/volume_handler_DG.hpp"
39#include "source/core_model.hpp"
40#include "source/geometry/mesh_handler.hpp"
41#include "source/init.hpp"
42#include "source/io/data_writer.hpp"
43#include "source/numerics/bc_handler.hpp"
44#include "source/numerics/linear_solver_handler.hpp"
45#include "source/numerics/preconditioner_handler.hpp"
46#include "source/numerics/tools.hpp"
47
48namespace DUBeat::models
49{
50 namespace laplace_DG
51 {
55 class ExactSolution : public lifex::utils::FunctionDirichlet
56 {
57 public:
60 : lifex::utils::FunctionDirichlet()
61 {}
62
64 virtual double
65 value(const dealii::Point<lifex::dim> &p,
66 const unsigned int /*component*/ = 0) const override
67 {
68 if (lifex::dim == 2)
69 return std::exp(p[0] + p[1]);
70 else
71 return std::exp(p[0] + p[1] + p[2]);
72 }
73 };
74
78 class RightHandSide : public lifex::Function<lifex::dim>
79 {
80 public:
83 : Function<lifex::dim>()
84 {}
85
87 virtual double
88 value(const dealii::Point<lifex::dim> &p,
89 const unsigned int /*component*/ = 0) const override
90 {
91 if (lifex::dim == 2)
92 return -2 * std::exp(p[0] + p[1]);
93 else
94 return -3 * std::exp(p[0] + p[1] + p[2]);
95 }
96 };
97
101 class GradExactSolution : public lifex::Function<lifex::dim>
102 {
103 public:
106 : Function<lifex::dim>()
107 {}
108
110 virtual double
111 value(const dealii::Point<lifex::dim> &p,
112 const unsigned int component = 0) const override
113 {
114 if (lifex::dim == 2)
115 {
116 if (component == 0) // x
117 return std::exp(p[0] + p[1]);
118 else // y
119 return std::exp(p[0] + p[1]);
120 }
121 else // dim=3
122 {
123 if (component == 0) // x
124 return std::exp(p[0] + p[1] + p[2]);
125 if (component == 1) // y
126 return std::exp(p[0] + p[1] + p[2]);
127 else // z
128 return std::exp(p[0] + p[1] + p[2]);
129 }
130 }
131 };
132 } // namespace laplace_DG
133
160 template <class basis>
161 class LaplaceDG : public ModelDG<basis>
162 {
163 public:
166 : ModelDG<basis>("Laplace")
167 {
168 this->u_ex = std::make_shared<laplace_DG::ExactSolution>();
169 this->grad_u_ex = std::make_shared<laplace_DG::GradExactSolution>();
170 this->f_ex = std::make_shared<laplace_DG::RightHandSide>();
171 }
172
173 private:
174 void
175 assemble_system() override;
176 };
177
179 template <class basis>
180 void
182 {
183 this->matrix = 0;
184 this->rhs = 0;
185
186 // The method is needed to define how the system matrix and rhs term are
187 // defined for the Laplace problem with Dirichlet boundary conditions. The
188 // full matrix is composed by different sub-matrices that are called with
189 // simple capital letters. We refer here to the DG_Assemble methods for
190 // their definition.
191
192 // See DG_Assemble::local_V().
193 dealii::FullMatrix<double> V(this->dofs_per_cell, this->dofs_per_cell);
194 // See DG_Assemble::local_SC().
195 dealii::FullMatrix<double> SC(this->dofs_per_cell, this->dofs_per_cell);
196 // See DG_Assemble::local_IC().
197 dealii::FullMatrix<double> IC(this->dofs_per_cell, this->dofs_per_cell);
198 // Transpose of IC.
199 dealii::FullMatrix<double> IC_t(this->dofs_per_cell, this->dofs_per_cell);
200 // See DG_Assemble::local_IB().
201 dealii::FullMatrix<double> IB(this->dofs_per_cell, this->dofs_per_cell);
202 // Transpose of IB.
203 dealii::FullMatrix<double> IB_t(this->dofs_per_cell, this->dofs_per_cell);
204 // See DG_Assemble::local_IN().
205 dealii::FullMatrix<double> IN(this->dofs_per_cell, this->dofs_per_cell);
206 // Transpose of IN.
207 dealii::FullMatrix<double> IN_t(this->dofs_per_cell, this->dofs_per_cell);
208 // See DG_Assemble::local_SN().
209 dealii::FullMatrix<double> SN(this->dofs_per_cell, this->dofs_per_cell);
210
211 // See DG_Assemble::local_rhs().
212 dealii::Vector<double> cell_rhs(this->dofs_per_cell);
213 // See DG_Assemble::local_rhs_edge_dirichlet().
214 dealii::Vector<double> cell_rhs_edge(this->dofs_per_cell);
215
216 std::vector<lifex::types::global_dof_index> dof_indices(
217 this->dofs_per_cell);
218
219 for (const auto &cell : this->dof_handler.active_cell_iterators())
220 {
221 if (cell->is_locally_owned())
222 {
223 this->assemble->reinit(cell);
224 dof_indices = this->dof_handler.get_dof_indices(cell);
225
226 V = this->assemble->local_V();
227 cell_rhs = this->assemble->local_rhs(this->f_ex);
228
229 this->matrix.add(dof_indices, V);
230 this->rhs.add(dof_indices, cell_rhs);
231
232 for (const auto &edge : cell->face_indices())
233 {
234 this->assemble->reinit(cell, edge);
235 std::vector<lifex::types::global_dof_index> dof_indices_neigh(
236 this->dofs_per_cell);
237
238 SC = this->assemble->local_SC(this->prm_stability_coeff);
239 this->matrix.add(dof_indices, SC);
240
241 if (!cell->at_boundary(edge))
242 {
243 std::tie(IC, IC_t) =
244 this->assemble->local_IC(this->prm_penalty_coeff);
245 this->matrix.add(dof_indices, IC);
246 this->matrix.add(dof_indices, IC_t);
247
248 const auto neighcell = cell->neighbor(edge);
250 this->dof_handler.get_dof_indices(neighcell);
251
252 std::tie(IN, IN_t) =
253 this->assemble->local_IN(this->prm_penalty_coeff);
254 SN = this->assemble->local_SN(this->prm_stability_coeff);
255
256 this->matrix.add(dof_indices, dof_indices_neigh, IN);
257 this->matrix.add(dof_indices_neigh, dof_indices, IN_t);
258 this->matrix.add(dof_indices, dof_indices_neigh, SN);
259 }
260 else
261 {
262 std::tie(IB, IB_t) =
263 this->assemble->local_IB(this->prm_penalty_coeff);
264 cell_rhs_edge = this->assemble->local_rhs_edge_dirichlet(
266 this->prm_penalty_coeff,
267 this->u_ex);
268 this->matrix.add(dof_indices, IB);
269 this->matrix.add(dof_indices, IB_t);
270 this->rhs.add(dof_indices, cell_rhs_edge);
271 }
272 }
273 }
274 }
275
276 this->matrix.compress(dealii::VectorOperation::add);
277 this->rhs.compress(dealii::VectorOperation::add);
278 }
279} // namespace DUBeat::models
280
281#endif /* LAPLACE_DG_HPP_*/
Class to solve the heat equation using the Discontinuous Galerkin method.
Definition heat_dg.hpp:260
HeatDG()
Constructor.
Definition heat_dg.hpp:263
Class to solve the Laplace equation using the Discontinuous Galerkin method.
void assemble_system() override
Assembly of the linear system.
virtual double value(const dealii::Point< lifex::dim > &p, const unsigned int=0) const override
Evaluate the exact solution in a point.
Gradient of the exact solution.
virtual double value(const dealii::Point< lifex::dim > &p, const unsigned int component=0) const override
Evaluate the gradient of the exact solution in a point.
virtual double value(const dealii::Point< lifex::dim > &p, const unsigned int=0) const override
Evaluate the source term in a point.
Class representing the resolution of problems using discontinuous Galerkin methods.
Definition model_DG.hpp:63
lifex::LinAlg::MPI::SparseMatrix matrix
Distributed matrix of the linear system.
Definition model_DG.hpp:239
double prm_stability_coeff
DG stabilty coefficient.
Definition model_DG.hpp:220
std::unique_ptr< AssembleDG< basis > > assemble
Matrix assembler.
Definition model_DG.hpp:233
DoFHandlerDG< basis > dof_handler
DoFHandler (internal use for useful already implemented methods).
Definition model_DG.hpp:228
std::shared_ptr< dealii::Function< lifex::dim > > f_ex
Known forcing term.
Definition model_DG.hpp:255
double prm_penalty_coeff
DG Penalty coefficient.
Definition model_DG.hpp:218
std::shared_ptr< dealii::Function< lifex::dim > > grad_u_ex
Pointer to exact gradient solution Function.
Definition model_DG.hpp:253
unsigned int dofs_per_cell
Number of degrees of freedom per cell.
Definition model_DG.hpp:226
std::shared_ptr< lifex::utils::FunctionDirichlet > u_ex
Pointer to exact solution function.
Definition model_DG.hpp:251
lifex::LinAlg::MPI::Vector rhs
Distributed right hand side vector of the linear system.
Definition model_DG.hpp:241