27#ifndef _HHO_DIFFUSION_HPP
28#define _HHO_DIFFUSION_HPP
34#include <boost/timer/timer.hpp>
37#include <Eigen/Sparse>
79 std::string solver_type,
81 std::ostream & output = std::cout
99 return double(_assembly_time) * pow(10, -9);
104 return double(_solving_time) * pow(10, -9);
109 return _solving_error;
114 return double(_itime[
idx]) * pow(10, -9);
153 const std::string solver_type;
154 const bool m_use_threads;
155 std::ostream & m_output;
158 const size_t m_nlocal_cell_dofs;
159 const size_t m_nlocal_edge_dofs;
160 const size_t m_nhighorder_dofs;
161 const size_t m_ntotal_cell_dofs;
162 const size_t m_ntotal_edge_dofs;
163 const size_t m_ndir_edge_dofs;
164 const size_t m_nnondir_edge_dofs;
165 const size_t m_ntotal_dofs;
168 std::vector<Eigen::MatrixXd> aT;
170 Eigen::SparseMatrix<double> GlobMat;
171 Eigen::SparseMatrix<double> SysMat;
174 Eigen::SparseMatrix<double> ScBeMat;
176 Eigen::VectorXd GlobRHS;
177 Eigen::VectorXd ScRHS;
180 size_t _assembly_time;
181 size_t _solving_time;
182 double _solving_error;
183 mutable std::vector<size_t> _itime = std::vector<size_t>(10, 0);
187 HHO_Diffusion::HHO_Diffusion(
HybridCore&
hho,
size_t K,
int L,
CellFType<MatrixRd> kappa,
CellFType<double> source,
BoundaryConditions BC,
FType<double> exact_solution,
CellFType<VectorRd> grad_exact_solution, std::string solver_type,
bool use_threads, std::ostream & output)
191 m_Ldeg(std::
max(
L,0)),
195 exact_solution(exact_solution),
196 grad_exact_solution(grad_exact_solution),
197 solver_type(solver_type),
200 m_nlocal_cell_dofs(
DimPoly<Cell>(m_Ldeg)),
201 m_nlocal_edge_dofs(
DimPoly<Edge>(m_K)),
202 m_nhighorder_dofs(
DimPoly<Cell>(m_K+1)),
203 m_ntotal_cell_dofs(m_nlocal_cell_dofs * m_hho.get_mesh()->n_cells()),
204 m_ntotal_edge_dofs(m_nlocal_edge_dofs * m_hho.get_mesh()->n_edges()),
205 m_ndir_edge_dofs(m_nlocal_edge_dofs * m_BC.n_dir_edges()),
206 m_nnondir_edge_dofs(m_nlocal_edge_dofs * m_hho.get_mesh()->n_edges() - m_ndir_edge_dofs),
207 m_ntotal_dofs(m_ntotal_cell_dofs + m_ntotal_edge_dofs),
211 m_output <<
"[HHO_Diffusion] Initializing" << std::endl;
212 GlobMat.resize(m_ntotal_edge_dofs, m_ntotal_edge_dofs);
213 ScBeMat.resize(m_ntotal_cell_dofs, m_ntotal_edge_dofs);
219 boost::timer::cpu_timer
timer;
221 const Mesh* mesh =
hho.get_mesh();
243 = [&](
size_t start,
size_t end)->
void
253 size_t doeT = m_Ldeg + m_K + 1;
254 size_t doeF = 2*m_K + 1;
268 Eigen::MatrixXd
ATT = aT[
iT].topLeftCorner(m_nlocal_cell_dofs, m_nlocal_cell_dofs);
269 Eigen::MatrixXd
ATF = aT[
iT].topRightCorner(m_nlocal_cell_dofs,
edge_dofs);
272 Eigen::PartialPivLU<Eigen::MatrixXd>
invATT;
282 ScRHS.segment(
iT * m_nlocal_cell_dofs, m_nlocal_cell_dofs) =
invATT_bTcell;
283 for (
size_t i = 0;
i < m_nlocal_cell_dofs;
i++) {
285 const size_t jF =
iCell->edge(
jlF)->global_index();
286 for (
size_t jk = 0;
jk < m_nlocal_edge_dofs;
jk++) {
287 const size_t jLocal =
jlF * m_nlocal_edge_dofs +
jk;
288 const size_t jGlobal =
jF * m_nlocal_edge_dofs +
jk;
316 const size_t jF =
iCell->edge(
jlF)->global_index();
317 const size_t jGlobal =
jF * m_nlocal_edge_dofs;
326 const size_t iF =
iCell->edge(
ilF)->global_index();
327 for (
size_t ik = 0;
ik < m_nlocal_edge_dofs;
ik++) {
328 const size_t iLocal =
ilF * m_nlocal_edge_dofs +
ik;
329 const size_t iGlobal =
iF * m_nlocal_edge_dofs +
ik;
331 const size_t jF =
iCell->edge(
jlF)->global_index();
332 for (
size_t jk = 0;
jk < m_nlocal_edge_dofs;
jk++) {
333 const size_t jLocal =
jlF * m_nlocal_edge_dofs +
jk;
334 const size_t jGlobal =
jF * m_nlocal_edge_dofs +
jk;
359 for (
size_t ilF = 0;
ilF <
T.n_edges();
ilF++) {
360 const size_t iF =
T.
edge(
ilF)->global_index();
361 for (
size_t ik = 0;
ik < m_nlocal_edge_dofs;
ik++) {
362 const size_t iLocal =
ilF * m_nlocal_edge_dofs +
ik;
363 const size_t iGlobal =
iF * m_nlocal_edge_dofs +
ik;
369 if (m_BC.
name()==
"Neumann"){
383 _assembly_time =
timer.elapsed().wall;
389 const Mesh* mesh =
hho.get_mesh();
390 boost::timer::cpu_timer
timer;
402 Eigen::VectorXd UDir;
404 if (m_BC.
name() !=
"Neumann"){
414 for (
size_t idF = 0;
idF < n_dir_edges;
idF++){
442 Eigen::BiCGSTAB<Eigen::SparseMatrix<double> >
solver;
445 std::cout <<
" [solver] #iterations: " <<
solver.iterations() <<
", estimated error: " <<
solver.error() << std::endl;
447 _solving_error = (SysMat *
xF - B).
norm();
449 Eigen::VectorXd
Xh = Eigen::VectorXd::Zero(m_ntotal_dofs);
453 Xh.head(m_ntotal_cell_dofs) = ScRHS - ScBeMat *
Xh.tail(m_ntotal_edge_dofs);
455 Xh.head(m_ntotal_cell_dofs) = ScBeMat *
Xh.tail(m_ntotal_edge_dofs);
459 if (m_BC.
name()==
"Neumann"){
469 for (
size_t i = 0;
i <
basisT.dimension();
i++){
494 _solving_time =
timer.elapsed().user +
timer.elapsed().system;
505 boost::timer::cpu_timer
timeint;
507 const auto mesh =
hho.get_mesh();
508 Cell* cell = mesh->cell(
iT);
509 const size_t nedgesT = cell->n_edges();
519 return kappa(cell->center_mass(), cell);
542 std::vector<Eigen::MatrixXd>
MFF(
nedgesT, Eigen::MatrixXd::Zero(m_nlocal_edge_dofs, m_nlocal_edge_dofs));
543 std::vector<Eigen::MatrixXd>
MFT(
nedgesT, Eigen::MatrixXd::Zero(m_nlocal_edge_dofs, m_nhighorder_dofs));
561 Eigen::MatrixXd
LTtLT =
LT * (
LT.transpose());
564 Eigen::MatrixXd
BP = Eigen::MatrixXd::Zero(m_nhighorder_dofs,
local_dofs);
565 BP.topLeftCorner(m_nhighorder_dofs, m_nlocal_cell_dofs) =
StiffT.topLeftCorner(m_nhighorder_dofs, m_nlocal_cell_dofs);
570 const size_t offset_F = m_nlocal_cell_dofs +
ilF * m_nlocal_edge_dofs;
571 const auto&
nTF = cell->edge_normal(
ilF);
588 for (
size_t i = 1;
i < m_nhighorder_dofs;
i++) {
594 for (
size_t j = 0;
j < m_nlocal_cell_dofs;
j++) {
598 for (
size_t j = 0;
j < m_nlocal_edge_dofs;
j++) {
613 BP.topLeftCorner(m_nhighorder_dofs, m_nlocal_cell_dofs) +=
scalT *
LTtLT.topLeftCorner(m_nhighorder_dofs, m_nlocal_cell_dofs);
628 Eigen::MatrixXd
MTT_LL =
MTT.topLeftCorner(m_nlocal_cell_dofs, m_nlocal_cell_dofs);
630 deltaTL.topLeftCorner(m_nlocal_cell_dofs, m_nlocal_cell_dofs) -= Eigen::MatrixXd::Identity(m_nlocal_cell_dofs, m_nlocal_cell_dofs);
634 double dTF = cell->edge(
ilF)->diam();
647 deltaTFK.block(0, m_nlocal_cell_dofs +
ilF * m_nlocal_edge_dofs, m_nlocal_edge_dofs, m_nlocal_edge_dofs) -=
648 Eigen::MatrixXd::Identity(m_nlocal_edge_dofs, m_nlocal_edge_dofs);
672 const auto mesh =
hho.get_mesh();
673 Cell* cell = mesh->cell(
iT);
674 size_t cell_edge_dofs = m_nlocal_cell_dofs + cell->n_edges()*m_nlocal_edge_dofs;
688 for (
size_t i=0;
i < m_nlocal_cell_dofs;
i++){
695 if (cell->is_boundary()){
697 for (
size_t ilF = 0;
ilF < cell->n_edges();
ilF++) {
699 if (m_BC.
type(*
F)==
"neu"){
700 const size_t iF =
F->global_index();
702 if (
F->is_boundary()){
704 const size_t offset_F = m_nlocal_cell_dofs +
ilF * m_nlocal_edge_dofs;
706 const auto&
nTF = cell->edge_normal(
ilF);
709 for (
size_t i = 0;
i < m_nlocal_edge_dofs;
i++){
712 return nTF.dot(kappa(
p,cell) * grad_exact_solution(
p,cell)) *
basisF.function(
i,
p);
727 const auto mesh =
hho.get_mesh();
730 for (
size_t iT = 0;
iT < mesh->n_cells();
iT++) {
731 Eigen::VectorXd
XTF =
Xh.restr(
iT);
732 value +=
XTF.transpose() * aT[
iT] *
XTF;
std::function< T(const VectorRd &, const Cell *)> CellFType
type for function of a point, that could be discontinuous between cells. T is the type of value of th...
Definition TestCase.hpp:42
The BoundaryConditions class provides definition of boundary conditions.
Definition BoundaryConditions.hpp:45
const std::string type(const Edge &edge) const
Test the boundary condition of an edge.
Definition BoundaryConditions.cpp:41
const std::string name() const
Returns the complete name of the boundary condition.
Definition BoundaryConditions.hpp:80
const size_t n_dir_edges() const
Returns the number of Dirichlet edges.
Definition BoundaryConditions.hpp:70
Definition elementquad.hpp:49
The HHO_Diffusion class provides tools to implement the HHO method for the diffusion problem.
Definition HHO_Diffusion.hpp:65
Definition hybridcore.hpp:179
Definition hybridcore.hpp:82
for i
Definition convergence_analysis.m:48
for j
Definition convergence_analysis.m:19
end
Definition convergence_analysis.m:110
Create grid points x
Definition generate_cartesian_mesh.m:22
Eigen::Vector2d VectorRd
Definition basis.hpp:55
Eigen::MatrixXd compute_gram_matrix(const boost::multi_array< VectorRd, 2 > &B1, const boost::multi_array< double, 2 > &B2, const QuadratureRule &qr)
Compute the Gram-like matrix given a family of vector-valued and one of scalar-valued functions by te...
Definition basis.cpp:239
Eigen::Matrix2d MatrixRd
Definition basis.hpp:54
std::function< T(const VectorRd &)> FType
type for function of point. T is the type of value of the function
Definition basis.hpp:64
static boost::multi_array< typename detail::basis_evaluation_traits< BasisType, BasisFunction >::ReturnValue, 2 > compute(const BasisType &basis, const QuadratureRule &quad)
Generic basis evaluation.
Definition basis.hpp:2425
static void parallel_for(unsigned nb_elements, std::function< void(size_t start, size_t end)> functor, bool use_threads=true, unsigned nb_threads_max=1e9)
Generic function to execute threaded processes.
Definition parallel_for.hpp:42
bool use_threads
Definition HHO_DiffAdvecReac.hpp:45
size_t L
Definition HHO_DiffAdvecReac.hpp:44
size_t K
Definition HHO_DiffAdvecReac.hpp:44
const size_t get_ntotal_edge_dofs()
Total number of edge DOFs over the entire mesh.
Definition HHO_Diffusion.hpp:126
double get_solving_time() const
cpu time to solve the scheme
Definition HHO_Diffusion.hpp:102
const size_t get_nlocal_edge_dofs()
Number of DOFs on each edge.
Definition HHO_Diffusion.hpp:120
const size_t get_ndir_edge_dofs()
Total number of edge DOFs for Dirichlet edges.
Definition HHO_Diffusion.hpp:128
const size_t get_nlocal_cell_dofs()
Number of DOFs in each cell.
Definition HHO_Diffusion.hpp:118
double get_itime(size_t idx) const
various intermediate assembly times
Definition HHO_Diffusion.hpp:112
double get_assembly_time() const
cpu time to assemble the scheme
Definition HHO_Diffusion.hpp:97
UVector solve(HybridCore &hho)
Definition HHO_Diffusion.hpp:387
Eigen::SparseMatrix< double > get_SysMat()
Return the (statically condensed) matrix system.
Definition HHO_Diffusion.hpp:92
const size_t get_ntotal_dofs()
Total number of degrees of freedom over the entire mesh.
Definition HHO_Diffusion.hpp:130
double EnergyNorm(HybridCore &hho, const UVector Xh)
Discrete energy norm (associated to the diffusion operator) of an hybrid function.
Definition HHO_Diffusion.hpp:726
void assemble(HybridCore &hho)
Assemble and solve the scheme.
Definition HHO_Diffusion.hpp:217
const size_t get_ntotal_cell_dofs()
Total number of cell DOFs over the entire mesh.
Definition HHO_Diffusion.hpp:124
double get_solving_error() const
residual after solving the scheme
Definition HHO_Diffusion.hpp:107
const size_t get_nhighorder_dofs()
Number of DOFs per cell for high-order (K+1) polynomials.
Definition HHO_Diffusion.hpp:122
HHO_Diffusion(HybridCore &hho, size_t K, int L, CellFType< MatrixRd > kappa, CellFType< double > source, BoundaryConditions BC, FType< double > exact_solution, CellFType< VectorRd > grad_exact_solution, std::string solver_type, bool use_threads, std::ostream &output=std::cout)
Constructor of the class.
Definition HHO_Diffusion.hpp:187
Eigen::VectorXd & asVectorXd() const
Return the values as an Eigen vector.
Definition hybridcore.hpp:92
size_t const DimPoly(int m)
std::vector< Cell * > get_cells() const
lists the cells in the mesh.
Definition Mesh2D.hpp:78
double measure() const
Return the Lebesgue measure of the Polytope.
Definition Polytope2D.hpp:77
Polytope< DIMENSION > Cell
Definition Polytope2D.hpp:152
Cell * cell(std::size_t index) const
get a constant pointer to a cell using its global index
Definition Mesh2D.hpp:178
size_t n_edges() const
Return the number of edges of the Polytope.
Definition Polytope2D.hpp:89
Edge * edge(std::size_t index) const
get a constant pointer to a edge using its global index
Definition Mesh2D.hpp:168
Polytope< 1 > Edge
A Face is a Polytope with object_dim = DIMENSION - 1.
Definition Polytope2D.hpp:148
Polytope< 1 > * edge(const size_t i) const
Return the i-th edge of the Polytope.
Definition Polytope2D.hpp:304
std::size_t n_cells() const
number of cells in the mesh.
Definition Mesh2D.hpp:63
size_t global_index() const
Return the global index of the Polytope.
Definition Polytope2D.hpp:74
std::size_t n_edges() const
number of edges in the mesh.
Definition Mesh2D.hpp:61
std::vector< QuadratureNode > QuadratureRule
Definition quadraturerule.hpp:55
QuadratureRule generate_quadrature_rule(const Cell &T, const int doe, const bool force_split)
Generate quadrature rule on mesh element.
Definition quadraturerule.cpp:10
depending on the Matrix Market format indicated by or array(dense array storage). The data will be duplicated % as appropriate if symmetry is indicated in the header. % % Optionally
if(strcmp(field, 'real')) % real valued entries T
Definition mmread.m:93
Definition PastixInterface.hpp:16
Definition mhd-solutions.hpp:9
Description of one node and one weight from a quadrature rule.
Definition quadraturerule.hpp:41