27#ifndef _HHO_DIFFUSION_HPP
28#define _HHO_DIFFUSION_HPP
34#include <boost/timer/timer.hpp>
37#include <Eigen/Sparse>
77 std::string solver_type,
79 std::ostream &
output = std::cout
92 return double(_assembly_time) * pow(10, -9);
97 return double(_solving_time) * pow(10, -9);
102 return _solving_error;
107 return double(_itime[
idx]) * pow(10, -9);
146 const std::string solver_type;
147 const bool m_use_threads;
148 std::ostream & m_output;
151 const size_t m_nlocal_cell_dofs;
152 const size_t m_nlocal_face_dofs;
153 const size_t m_nhighorder_dofs;
154 const size_t m_ntotal_cell_dofs;
155 const size_t m_ntotal_face_dofs;
156 const size_t m_ndir_face_dofs;
157 const size_t m_nnondir_face_dofs;
158 const size_t m_ntotal_dofs;
161 std::vector<Eigen::MatrixXd> aT;
163 Eigen::SparseMatrix<double> GlobMat;
166 Eigen::SparseMatrix<double> ScBeMat;
168 Eigen::VectorXd GlobRHS;
169 Eigen::VectorXd ScRHS;
172 size_t _assembly_time;
173 size_t _solving_time;
174 double _solving_error;
175 mutable std::vector<size_t> _itime = std::vector<size_t>(10, 0);
179 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)
183 m_Ldeg(std::
max(
L,0)),
187 exact_solution(exact_solution),
188 grad_exact_solution(grad_exact_solution),
189 solver_type(solver_type),
192 m_nlocal_cell_dofs(
DimPoly<Cell>(m_Ldeg)),
193 m_nlocal_face_dofs(
DimPoly<Face>(m_K)),
194 m_nhighorder_dofs(
DimPoly<Cell>(m_K+1)),
195 m_ntotal_cell_dofs(m_nlocal_cell_dofs * m_hho.get_mesh()->n_cells()),
196 m_ntotal_face_dofs(m_nlocal_face_dofs * m_hho.get_mesh()->n_faces()),
197 m_ndir_face_dofs(m_nlocal_face_dofs * m_BC.n_dir_faces()),
198 m_nnondir_face_dofs(m_nlocal_face_dofs * m_hho.get_mesh()->n_faces() - m_ndir_face_dofs),
199 m_ntotal_dofs(m_ntotal_cell_dofs + m_ntotal_face_dofs),
203 m_output <<
"[HHO_Diffusion] Initializing" << std::endl;
204 GlobMat.resize(m_ntotal_face_dofs, m_ntotal_face_dofs);
205 ScBeMat.resize(m_ntotal_cell_dofs, m_ntotal_face_dofs);
211 boost::timer::cpu_timer
timer;
213 const Mesh* mesh =
hho.get_mesh();
235 = [&](
size_t start,
size_t end)->
void
245 size_t doeT = m_Ldeg + m_K + 1;
246 size_t doeF = 2*m_K + 1;
260 Eigen::MatrixXd
ATT = aT[
iT].topLeftCorner(m_nlocal_cell_dofs, m_nlocal_cell_dofs);
261 Eigen::MatrixXd
ATF = aT[
iT].topRightCorner(m_nlocal_cell_dofs,
face_dofs);
264 Eigen::PartialPivLU<Eigen::MatrixXd>
invATT;
274 ScRHS.segment(
iT * m_nlocal_cell_dofs, m_nlocal_cell_dofs) =
invATT_bTcell;
275 for (
size_t i = 0;
i < m_nlocal_cell_dofs;
i++) {
277 const size_t jF =
iCell->face(
jlF)->global_index();
278 for (
size_t jk = 0;
jk < m_nlocal_face_dofs;
jk++) {
279 const size_t jLocal =
jlF * m_nlocal_face_dofs +
jk;
280 const size_t jGlobal =
jF * m_nlocal_face_dofs +
jk;
293 VectorRd
xT =
iCell->center_mass();
296 VectorRd
xF =
iCell->face(
ilF)->center_mass();
308 const size_t jF =
iCell->face(
jlF)->global_index();
309 const size_t jGlobal =
jF * m_nlocal_face_dofs;
318 const size_t iF =
iCell->face(
ilF)->global_index();
319 for (
size_t ik = 0;
ik < m_nlocal_face_dofs;
ik++) {
320 const size_t iLocal =
ilF * m_nlocal_face_dofs +
ik;
321 const size_t iGlobal =
iF * m_nlocal_face_dofs +
ik;
323 const size_t jF =
iCell->face(
jlF)->global_index();
324 for (
size_t jk = 0;
jk < m_nlocal_face_dofs;
jk++) {
325 const size_t jLocal =
jlF * m_nlocal_face_dofs +
jk;
326 const size_t jGlobal =
jF * m_nlocal_face_dofs +
jk;
350 Cell& T = *mesh->
cell(
iT);
351 for (
size_t ilF = 0;
ilF < T.n_faces();
ilF++) {
352 const size_t iF = T.face(
ilF)->global_index();
353 for (
size_t ik = 0;
ik < m_nlocal_face_dofs;
ik++) {
354 const size_t iLocal =
ilF * m_nlocal_face_dofs +
ik;
355 const size_t iGlobal =
iF * m_nlocal_face_dofs +
ik;
361 if (m_BC.
name()==
"Neumann"){
375 _assembly_time =
timer.elapsed().wall;
381 const Mesh* mesh =
hho.get_mesh();
382 boost::timer::cpu_timer
timer;
393 Eigen::SparseMatrix<double> A;
395 Eigen::VectorXd UDir;
397 if (m_BC.
name() !=
"Neumann"){
408 for (
size_t idF = 0;
idF < n_dir_faces;
idF++){
410 size_t iF = face->global_index();
436 Eigen::BiCGSTAB<Eigen::SparseMatrix<double> >
solver;
439 std::cout <<
" [solver] #iterations: " <<
solver.iterations() <<
", estimated error: " <<
solver.error() << std::endl;
441 _solving_error = (A *
xF - B).
norm();
443 Eigen::VectorXd
Xh = Eigen::VectorXd::Zero(m_ntotal_dofs);
447 Xh.head(m_ntotal_cell_dofs) = ScRHS - ScBeMat *
Xh.tail(m_ntotal_face_dofs);
449 Xh.head(m_ntotal_cell_dofs) = ScBeMat *
Xh.tail(m_ntotal_face_dofs);
453 if (m_BC.
name()==
"Neumann"){
458 Cell& T = *mesh->
cell(
iT);
463 for (
size_t i = 0;
i <
basisT.dimension();
i++){
488 _solving_time =
timer.elapsed().user +
timer.elapsed().system;
499 boost::timer::cpu_timer
timeint;
501 const auto mesh =
hho.get_mesh();
502 Cell* cell = mesh->cell(
iT);
503 const size_t nfacesT = cell->n_faces();
513 return kappa(cell->center_mass(), cell);
536 std::vector<Eigen::MatrixXd>
MFF(
nfacesT, Eigen::MatrixXd::Zero(m_nlocal_face_dofs, m_nlocal_face_dofs));
537 std::vector<Eigen::MatrixXd>
MFT(
nfacesT, Eigen::MatrixXd::Zero(m_nlocal_face_dofs, m_nhighorder_dofs));
555 Eigen::MatrixXd
LTtLT =
LT * (
LT.transpose());
558 Eigen::MatrixXd
BP = Eigen::MatrixXd::Zero(m_nhighorder_dofs,
local_dofs);
559 BP.topLeftCorner(m_nhighorder_dofs, m_nlocal_cell_dofs) =
StiffT.topLeftCorner(m_nhighorder_dofs, m_nlocal_cell_dofs);
564 const size_t offset_F = m_nlocal_cell_dofs +
ilF * m_nlocal_face_dofs;
565 const auto&
nTF = cell->face_normal(
ilF);
582 for (
size_t i = 1;
i < m_nhighorder_dofs;
i++) {
588 for (
size_t j = 0;
j < m_nlocal_cell_dofs;
j++) {
592 for (
size_t j = 0;
j < m_nlocal_face_dofs;
j++) {
607 BP.topLeftCorner(m_nhighorder_dofs, m_nlocal_cell_dofs) +=
scalT *
LTtLT.topLeftCorner(m_nhighorder_dofs, m_nlocal_cell_dofs);
622 Eigen::MatrixXd
MTT_LL =
MTT.topLeftCorner(m_nlocal_cell_dofs, m_nlocal_cell_dofs);
624 deltaTL.topLeftCorner(m_nlocal_cell_dofs, m_nlocal_cell_dofs) -= Eigen::MatrixXd::Identity(m_nlocal_cell_dofs, m_nlocal_cell_dofs);
628 double dTF = cell->face(
ilF)->diam();
641 deltaTFK.block(0, m_nlocal_cell_dofs +
ilF * m_nlocal_face_dofs, m_nlocal_face_dofs, m_nlocal_face_dofs) -=
642 Eigen::MatrixXd::Identity(m_nlocal_face_dofs, m_nlocal_face_dofs);
666 const auto mesh =
hho.get_mesh();
667 Cell* cell = mesh->cell(
iT);
668 size_t cell_face_dofs = m_nlocal_cell_dofs + cell->n_faces()*m_nlocal_face_dofs;
682 for (
size_t i=0;
i < m_nlocal_cell_dofs;
i++){
689 if (cell->is_boundary()){
691 for (
size_t ilF = 0;
ilF < cell->n_faces();
ilF++) {
693 if (m_BC.
type(*
F)==
"neu"){
694 const size_t iF =
F->global_index();
696 if (
F->is_boundary()){
698 const size_t offset_F = m_nlocal_cell_dofs +
ilF * m_nlocal_face_dofs;
700 const auto&
nTF = cell->face_normal(
ilF);
703 for (
size_t i = 0;
i < m_nlocal_face_dofs;
i++){
706 return nTF.dot(kappa(p,cell) * grad_exact_solution(p,cell)) *
basisF.function(
i,p);
721 const auto mesh =
hho.get_mesh();
724 for (
size_t iT = 0;
iT < mesh->n_cells();
iT++) {
725 Eigen::VectorXd
XTF =
Xh.restr(
iT);
726 value +=
XTF.transpose() * aT[
iT] *
XTF;
The BoundaryConditions class provides definition of boundary conditions.
Definition BoundaryConditions.hpp:129
const std::string type(const Face &face) const
Test the boundary condition of an face.
Definition BoundaryConditions.cpp:81
const std::string name() const
Returns the complete name of the boundary condition.
Definition BoundaryConditions.hpp:178
const size_t n_dir_faces() const
Returns the number of Dirichlet faces.
Definition BoundaryConditions.hpp:160
Definition elementquad.hpp:55
Family of functions expressed as linear combination of the functions of a given basis.
Definition basis.hpp:389
The HHO_Diffusion class provides tools to implement the HHO method for the diffusion problem.
Definition HHO_Diffusion.hpp:64
Definition hybridcore.hpp:174
Definition hybridcore.hpp:87
Class to describe a mesh.
Definition MeshND.hpp:17
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:2224
std::function< T(const VectorRd &, const Cell *)> CellFType
type for function of point. T is the return type of the function
Definition basis.hpp:58
std::function< T(const VectorRd &)> FType
type for function of point. T is the return type of the function
Definition basis.hpp:55
Eigen::Matrix3d MatrixRd
Definition basis.hpp:51
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:353
@ Matrix
Definition basis.hpp:67
static void parallel_for(unsigned nb_elements, std::function< void(size_t start, size_t end)> functor, bool use_threads=true)
Generic function to execute threaded processes.
Definition parallel_for.hpp:58
bool use_threads
Definition HHO_DiffAdvecReac.hpp:47
size_t L
Definition HHO_DiffAdvecReac.hpp:46
size_t K
Definition HHO_DiffAdvecReac.hpp:46
double get_itime(size_t idx) const
various intermediate assembly times
Definition HHO_Diffusion.hpp:105
double EnergyNorm(HybridCore &hho, const UVector Xh)
Discrete energy norm (associated to the diffusion operator) of an hybrid function.
Definition HHO_Diffusion.hpp:720
const size_t get_ntotal_face_dofs()
Total number of face DOFs over the entire mesh.
Definition HHO_Diffusion.hpp:119
const size_t get_ndir_face_dofs()
Total number of face DOFs for Dirichlet faces.
Definition HHO_Diffusion.hpp:121
UVector solve(HybridCore &hho)
Definition HHO_Diffusion.hpp:379
const size_t get_nlocal_cell_dofs()
Number of DOFs in each cell.
Definition HHO_Diffusion.hpp:111
const size_t get_nlocal_face_dofs()
Number of DOFs on each face.
Definition HHO_Diffusion.hpp:113
void assemble(HybridCore &hho)
Assemble and solve the scheme.
Definition HHO_Diffusion.hpp:209
double get_solving_error() const
residual after solving the scheme
Definition HHO_Diffusion.hpp:100
const size_t get_ntotal_dofs()
Total number of degrees of freedom over the entire mesh.
Definition HHO_Diffusion.hpp:123
double get_assembly_time() const
cpu time to assemble the scheme
Definition HHO_Diffusion.hpp:90
const size_t get_nhighorder_dofs()
Number of DOFs per cell for high-order (K+1) polynomials.
Definition HHO_Diffusion.hpp:115
const size_t get_ntotal_cell_dofs()
Total number of cell DOFs over the entire mesh.
Definition HHO_Diffusion.hpp:117
double get_solving_time() const
cpu time to solve the scheme
Definition HHO_Diffusion.hpp:95
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:179
size_t const DimPoly(int m)
Eigen::VectorXd & asVectorXd() const
Return the values as an Eigen vector.
Definition hybridcore.hpp:97
Face< dimension > * face(std::size_t index) const
get a constant pointer to a face using its global index
Definition MeshND.hpp:196
std::size_t n_faces() const
number of faces in the mesh.
Definition MeshND.hpp:59
std::size_t n_cells() const
number of cells in the mesh.
Definition MeshND.hpp:60
Cell< dimension > * cell(std::size_t index) const
get a constant pointer to a cell using its global index
Definition MeshND.hpp:197
std::vector< Cell< dimension > * > get_cells() const
lists the cells in the mesh.
Definition MeshND.hpp:88
QuadratureRule generate_quadrature_rule(const Cell &T, const int doe, const bool force_split)
Generate quadrature rule on mesh element.
Definition quadraturerule.cpp:11
std::vector< QuadratureNode > QuadratureRule
Definition quadraturerule.hpp:61
Definition PastixInterface.hpp:16
Definition ddr-magnetostatics.hpp:41
MeshND::VectorRd< 2 > VectorRd
Definition Mesh2D.hpp:14
MeshND::Face< 2 > Face
Definition Mesh2D.hpp:12
MeshND::Cell< 2 > Cell
Definition Mesh2D.hpp:13
Description of one node and one weight from a quadrature rule.
Definition quadraturerule.hpp:47