27#ifndef _HHO_LOCVARDIFF_HPP
28#define _HHO_LOCVARDIFF_HPP
34#include <boost/timer/timer.hpp>
37#include <Eigen/Sparse>
80 std::string solver_type,
82 std::ostream & output = std::cout
100 return double(_assembly_time) * pow(10, -9);
105 return double(_solving_time) * pow(10, -9);
110 return _solving_error;
115 return double(_itime[
idx]) * pow(10, -9);
155 const std::string solver_type;
156 const bool m_use_threads;
157 std::ostream & m_output;
160 const size_t m_nlocal_cell_dofs;
161 const size_t m_nlocal_edge_dofs;
162 const size_t m_nhighorder_dofs;
163 const size_t m_ntotal_cell_dofs;
164 const size_t m_ntotal_edge_dofs;
165 const size_t m_ndir_edge_dofs;
166 const size_t m_nnondir_edge_dofs;
167 const size_t m_ntotal_dofs;
170 std::vector<Eigen::MatrixXd> aT;
172 Eigen::SparseMatrix<double> GlobMat;
173 Eigen::SparseMatrix<double> SysMat;
176 Eigen::SparseMatrix<double> ScBeMat;
178 Eigen::VectorXd GlobRHS;
179 Eigen::VectorXd ScRHS;
182 size_t _assembly_time;
183 size_t _solving_time;
184 double _solving_error;
185 mutable std::vector<size_t> _itime = std::vector<size_t>(10, 0);
189 HHO_LocVarDiff::HHO_LocVarDiff(
HybridCore&
hho,
size_t K,
int L,
CellFType<MatrixRd> kappa,
size_t deg_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)
193 m_Ldeg(std::
max(
L,0)),
198 exact_solution(exact_solution),
199 grad_exact_solution(grad_exact_solution),
200 solver_type(solver_type),
203 m_nlocal_cell_dofs(
DimPoly<Cell>(m_Ldeg)),
204 m_nlocal_edge_dofs(
DimPoly<Edge>(m_K)),
205 m_nhighorder_dofs(
DimPoly<Cell>(m_K+1)),
206 m_ntotal_cell_dofs(m_nlocal_cell_dofs * m_hho.get_mesh()->n_cells()),
207 m_ntotal_edge_dofs(m_nlocal_edge_dofs * m_hho.get_mesh()->n_edges()),
208 m_ndir_edge_dofs(m_nlocal_edge_dofs * m_BC.n_dir_edges()),
209 m_nnondir_edge_dofs(m_nlocal_edge_dofs * m_hho.get_mesh()->n_edges() - m_ndir_edge_dofs),
210 m_ntotal_dofs(m_ntotal_cell_dofs + m_ntotal_edge_dofs),
214 m_output <<
"[HHO_LocVarDiff] Initializing" << std::endl;
215 GlobMat.resize(m_ntotal_edge_dofs, m_ntotal_edge_dofs);
216 ScBeMat.resize(m_ntotal_cell_dofs, m_ntotal_edge_dofs);
222 boost::timer::cpu_timer
timer;
224 const Mesh* mesh =
hho.get_mesh();
246 = [&](
size_t start,
size_t end)->
void
256 size_t doeT = std::max( std::max(m_K,m_Ldeg) + m_K+1 , 2*m_K + _deg_kappa );
257 size_t doeF = 2*m_K + 1;
271 Eigen::MatrixXd
ATT = aT[
iT].topLeftCorner(m_nlocal_cell_dofs, m_nlocal_cell_dofs);
272 Eigen::MatrixXd
ATF = aT[
iT].topRightCorner(m_nlocal_cell_dofs,
edge_dofs);
275 Eigen::PartialPivLU<Eigen::MatrixXd>
invATT;
285 ScRHS.segment(
iT * m_nlocal_cell_dofs, m_nlocal_cell_dofs) =
invATT_bTcell;
286 for (
size_t i = 0;
i < m_nlocal_cell_dofs;
i++) {
288 const size_t jF =
iCell->edge(
jlF)->global_index();
289 for (
size_t jk = 0;
jk < m_nlocal_edge_dofs;
jk++) {
290 const size_t jLocal =
jlF * m_nlocal_edge_dofs +
jk;
291 const size_t jGlobal =
jF * m_nlocal_edge_dofs +
jk;
319 const size_t jF =
iCell->edge(
jlF)->global_index();
320 const size_t jGlobal =
jF * m_nlocal_edge_dofs;
329 const size_t iF =
iCell->edge(
ilF)->global_index();
330 for (
size_t ik = 0;
ik < m_nlocal_edge_dofs;
ik++) {
331 const size_t iLocal =
ilF * m_nlocal_edge_dofs +
ik;
332 const size_t iGlobal =
iF * m_nlocal_edge_dofs +
ik;
334 const size_t jF =
iCell->edge(
jlF)->global_index();
335 for (
size_t jk = 0;
jk < m_nlocal_edge_dofs;
jk++) {
336 const size_t jLocal =
jlF * m_nlocal_edge_dofs +
jk;
337 const size_t jGlobal =
jF * m_nlocal_edge_dofs +
jk;
362 for (
size_t ilF = 0;
ilF <
T.n_edges();
ilF++) {
363 const size_t iF =
T.
edge(
ilF)->global_index();
364 for (
size_t ik = 0;
ik < m_nlocal_edge_dofs;
ik++) {
365 const size_t iLocal =
ilF * m_nlocal_edge_dofs +
ik;
366 const size_t iGlobal =
iF * m_nlocal_edge_dofs +
ik;
372 if (m_BC.
name()==
"Neumann"){
386 _assembly_time =
timer.elapsed().wall;
391 const Mesh* mesh =
hho.get_mesh();
392 boost::timer::cpu_timer
timer;
404 Eigen::VectorXd UDir;
406 if (m_BC.
name() !=
"Neumann"){
416 for (
size_t idF = 0;
idF < n_dir_edges;
idF++){
444 Eigen::BiCGSTAB<Eigen::SparseMatrix<double> >
solver;
447 std::cout <<
" [solver] #iterations: " <<
solver.iterations() <<
", estimated error: " <<
solver.error() << std::endl;
449 _solving_error = (SysMat *
xF - B).
norm();
451 Eigen::VectorXd
Xh = Eigen::VectorXd::Zero(m_ntotal_dofs);
455 Xh.head(m_ntotal_cell_dofs) = ScRHS - ScBeMat *
Xh.tail(m_ntotal_edge_dofs);
457 Xh.head(m_ntotal_cell_dofs) = ScBeMat *
Xh.tail(m_ntotal_edge_dofs);
461 if (m_BC.
name()==
"Neumann"){
471 for (
size_t i = 0;
i <
basisT.dimension();
i++){
496 _solving_time =
timer.elapsed().user +
timer.elapsed().system;
508 boost::timer::cpu_timer
timeint;
510 const auto mesh =
hho.get_mesh();
513 Cell* cell = mesh->cell(
iT);
514 const size_t nedgesT = cell->n_edges();
543 [
this,&cell](
QuadratureNode qr) -> Eigen::MatrixXd { return kappa(qr.vector(), cell); });
555 for (
size_t r=0;
r < mesh->dim();
r++){
563 std::vector<Eigen::MatrixXd>
MFF(
nedgesT, Eigen::MatrixXd::Zero(m_nlocal_edge_dofs, m_nlocal_edge_dofs));
564 std::vector<Eigen::MatrixXd>
MFT(
nedgesT, Eigen::MatrixXd::Zero(m_nlocal_edge_dofs, m_nhighorder_dofs));
598 for (
size_t r=0;
r < mesh->dim();
r++){
601 const size_t offset_F = m_nlocal_cell_dofs +
ilF * m_nlocal_edge_dofs;
602 const auto&
nTF = cell->edge_normal(
ilF);
647 Eigen::MatrixXd
LTtLT =
LT * (
LT.transpose());
651 RHS_PT.topLeftCorner(m_nhighorder_dofs, m_nlocal_cell_dofs) +=
652 scalT *
LTtLT.topLeftCorner(m_nhighorder_dofs, m_nlocal_cell_dofs);
662 Eigen::MatrixXd
MTT_LKp1 =
MTT.topLeftCorner(m_nlocal_cell_dofs, m_nhighorder_dofs);
663 Eigen::MatrixXd
MTT_LL =
MTT.topLeftCorner(m_nlocal_cell_dofs, m_nlocal_cell_dofs);
665 deltaTL.topLeftCorner(m_nlocal_cell_dofs, m_nlocal_cell_dofs) -= Eigen::MatrixXd::Identity(m_nlocal_cell_dofs, m_nlocal_cell_dofs);
669 double dTF = cell->edge(
ilF)->diam();
682 deltaTFK.block(0, m_nlocal_cell_dofs +
ilF * m_nlocal_edge_dofs, m_nlocal_edge_dofs, m_nlocal_edge_dofs) -=
683 Eigen::MatrixXd::Identity(m_nlocal_edge_dofs, m_nlocal_edge_dofs);
707 const auto mesh =
hho.get_mesh();
708 Cell* cell = mesh->cell(
iT);
709 size_t cell_edge_dofs = m_nlocal_cell_dofs + cell->n_edges()*m_nlocal_edge_dofs;
723 for (
size_t i=0;
i < m_nlocal_cell_dofs;
i++){
730 if (cell->is_boundary()){
732 for (
size_t ilF = 0;
ilF < cell->n_edges();
ilF++) {
734 if (m_BC.
type(*
F)==
"neu"){
735 const size_t iF =
F->global_index();
737 if (
F->is_boundary()){
739 const size_t offset_F = m_nlocal_cell_dofs +
ilF * m_nlocal_edge_dofs;
741 const auto&
nTF = cell->edge_normal(
ilF);
744 for (
size_t i = 0;
i < m_nlocal_edge_dofs;
i++){
747 return nTF.dot(kappa(
p,cell) * grad_exact_solution(
p,cell)) *
basisF.function(
i,
p);
762 const auto mesh =
hho.get_mesh();
765 for (
size_t iT = 0;
iT < mesh->n_cells();
iT++) {
766 Eigen::VectorXd
XTF =
Xh.restr(
iT);
767 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_LocVarDiff class provides tools to implement the HHO method for the diffusion problem.
Definition HHO_LocVarDiff.hpp:65
Definition hybridcore.hpp:179
Definition hybridcore.hpp:82
for i
Definition convergence_analysis.m:48
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
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
double EnergyNorm(HybridCore &hho, const UVector Xh)
Discrete energy norm (associated to the diffusion operator) of an hybrid function.
Definition HHO_LocVarDiff.hpp:761
Eigen::SparseMatrix< double > get_SysMat()
Return the (statically condensed) matrix system.
Definition HHO_LocVarDiff.hpp:93
const size_t get_nhighorder_dofs()
Number of DOFs per cell for high-order (K+1) polynomials.
Definition HHO_LocVarDiff.hpp:123
const size_t get_ntotal_dofs()
Total number of degrees of freedom over the entire mesh.
Definition HHO_LocVarDiff.hpp:131
HHO_LocVarDiff(HybridCore &hho, size_t K, int L, CellFType< MatrixRd > kappa, size_t deg_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_LocVarDiff.hpp:189
const size_t get_nlocal_cell_dofs()
Number of DOFs in each cell.
Definition HHO_LocVarDiff.hpp:119
void assemble(HybridCore &hho)
Assemble and solve the scheme.
Definition HHO_LocVarDiff.hpp:220
double get_itime(size_t idx) const
various intermediate assembly times
Definition HHO_LocVarDiff.hpp:113
double get_solving_error() const
residual after solving the scheme
Definition HHO_LocVarDiff.hpp:108
double get_assembly_time() const
cpu time to assemble the scheme
Definition HHO_LocVarDiff.hpp:98
UVector solve(HybridCore &hho)
Definition HHO_LocVarDiff.hpp:390
const size_t get_nlocal_edge_dofs()
Number of DOFs on each edge.
Definition HHO_LocVarDiff.hpp:121
const size_t get_ntotal_cell_dofs()
Total number of cell DOFs over the entire mesh.
Definition HHO_LocVarDiff.hpp:125
const size_t get_ntotal_edge_dofs()
Total number of edge DOFs over the entire mesh.
Definition HHO_LocVarDiff.hpp:127
double get_solving_time() const
cpu time to solve the scheme
Definition HHO_LocVarDiff.hpp:103
const size_t get_ndir_edge_dofs()
Total number of edge DOFs for Dirichlet edges.
Definition HHO_LocVarDiff.hpp:129
const size_t DimPoly< Cell >(const int m)
Compute the size of the basis of 2-variate polynomials up to degree m.
Definition hybridcore.hpp:63
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