27 #ifndef _HHO_DIFFUSION_HPP
28 #define _HHO_DIFFUSION_HPP
34 #include <boost/timer/timer.hpp>
37 #include <Eigen/Sparse>
38 #include <Eigen/Dense>
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);
127 Eigen::MatrixXd diffusion_operator(
HybridCore& hho,
const size_t iT,
const ElementQuad& elquad)
const;
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),
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),
200 GlobRHS(Eigen::VectorXd::Zero(m_ntotal_face_dofs)),
201 ScRHS(Eigen::VectorXd::Zero(m_ntotal_cell_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;
218 std::vector<Eigen::Triplet<double>> triplets_GlobMat;
219 std::vector<Eigen::Triplet<double>> triplets_ScBe;
223 std::vector<std::vector<Eigen::Triplet<double>>> cell_triplets_GlobMat;
224 std::vector<std::vector<Eigen::Triplet<double>>> cell_triplets_ScBe;
225 std::vector<Eigen::VectorXd> cell_source(mesh->
n_cells());
226 cell_triplets_GlobMat.resize(mesh->
n_cells());
227 cell_triplets_ScBe.resize(mesh->
n_cells());
228 size_t size_triplets_GlobMat = 0;
229 size_t size_triplets_ScBe = 0;
234 std::function<void(
size_t,
size_t)> construct_all_local_contributions
235 = [&](
size_t start,
size_t end)->
void
237 for (
size_t iT = start; iT < end; iT++) {
241 size_t nlocal_faces = iCell->n_faces();
242 size_t face_dofs = nlocal_faces * m_nlocal_face_dofs;
245 size_t doeT = m_Ldeg + m_K + 1;
246 size_t doeF = 2*m_K + 1;
249 aT[iT] = diffusion_operator(hho, iT, elquad);
250 Eigen::VectorXd bT = load_operator(hho, iT, elquad);
253 Eigen::MatrixXd MatF = Eigen::MatrixXd::Zero(face_dofs,face_dofs);
254 cell_source[iT] = Eigen::VectorXd::Zero(face_dofs);
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);
262 Eigen::MatrixXd AFF = aT[iT].bottomRightCorner(face_dofs, face_dofs);
264 Eigen::PartialPivLU<Eigen::MatrixXd> invATT;
267 Eigen::MatrixXd invATT_ATF = invATT.solve(ATF);
268 Eigen::VectorXd invATT_bTcell = invATT.solve(bT.head(m_nlocal_cell_dofs));
269 MatF = AFF - ATF.transpose() * invATT_ATF;
271 cell_source[iT] = bT.tail(face_dofs) - ATF.transpose() * invATT_bTcell;
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++) {
276 for (
size_t jlF = 0; jlF < nlocal_faces; jlF++) {
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;
281 cell_triplets_ScBe[iT].emplace_back(iT * m_nlocal_cell_dofs + i, jGlobal, invATT_ATF(i, jLocal));
285 size_triplets_ScBe += cell_triplets_ScBe[iT].size();
291 Eigen::MatrixXd red_matT = Eigen::MatrixXd::Zero(1+nlocal_faces,nlocal_faces);
295 for (
size_t ilF = 0; ilF < nlocal_faces; ilF++){
296 VectorRd xF = iCell->face(ilF)->center_mass();
297 size_t iF = iCell->face(ilF)->global_index();
299 red_matT(0,ilF) *= phiF_cst / phiT_cst;
301 red_matT.bottomRightCorner(nlocal_faces,nlocal_faces) = Eigen::MatrixXd::Identity(nlocal_faces,nlocal_faces);
303 cell_source[iT] = red_matT.transpose() * bT;
304 MatF = red_matT.transpose() * aT[iT] * red_matT;
307 for (
size_t jlF = 0; jlF < nlocal_faces; jlF++) {
308 const size_t jF = iCell->face(jlF)->global_index();
309 const size_t jGlobal = jF * m_nlocal_face_dofs;
310 cell_triplets_ScBe[iT].emplace_back(iT, jGlobal, red_matT(0,jlF));
312 size_triplets_ScBe += cell_triplets_ScBe[iT].size();
317 for (
size_t ilF = 0; ilF < nlocal_faces; ilF++) {
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;
322 for (
size_t jlF = 0; jlF < nlocal_faces; jlF++) {
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;
327 cell_triplets_GlobMat[iT].emplace_back(iGlobal, jGlobal, MatF(iLocal, jLocal));
332 size_triplets_GlobMat += cell_triplets_GlobMat[iT].size();
341 triplets_ScBe.reserve(size_triplets_ScBe);
342 triplets_GlobMat.reserve(size_triplets_GlobMat);
343 for (
size_t iT = 0; iT < mesh->
n_cells(); iT++){
344 for (
size_t i = 0; i < cell_triplets_ScBe[iT].size(); i++){
345 triplets_ScBe.push_back(cell_triplets_ScBe[iT][i]);
347 for (
size_t i = 0; i < cell_triplets_GlobMat[iT].size(); i++){
348 triplets_GlobMat.push_back(cell_triplets_GlobMat[iT][i]);
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;
356 GlobRHS(iGlobal) += cell_source[iT](iLocal);
361 if (m_BC.
name()==
"Neumann"){
363 triplets_GlobMat.erase(std::remove_if(std::begin(triplets_GlobMat), std::end(triplets_GlobMat),
364 [](
const auto& x) {
return (x.row() == 0); }), std::end(triplets_GlobMat));
365 triplets_GlobMat.emplace_back(0, 0, 1);
370 GlobMat.setFromTriplets(std::begin(triplets_GlobMat), std::end(triplets_GlobMat));
371 ScBeMat.setFromTriplets(std::begin(triplets_ScBe), std::end(triplets_ScBe));
375 _assembly_time = timer.elapsed().wall;
382 boost::timer::cpu_timer timer;
391 size_t n_unknowns = 0;
392 size_t n_fixed_dofs = 0;
393 Eigen::SparseMatrix<double> A;
395 Eigen::VectorXd UDir;
397 if (m_BC.
name() !=
"Neumann"){
399 n_unknowns = m_nnondir_face_dofs;
400 n_fixed_dofs = m_ndir_face_dofs;
401 A = GlobMat.topLeftCorner(n_unknowns, n_unknowns);
404 UDir = Eigen::VectorXd::Zero(n_fixed_dofs);
407 size_t n_nondir_faces = mesh->
n_faces() - n_dir_faces;
408 for (
size_t idF = 0; idF < n_dir_faces; idF++){
409 Face* face = mesh->
face(n_nondir_faces + idF);
410 size_t iF = face->global_index();
413 UDir.segment(idF * m_nlocal_face_dofs, m_nlocal_face_dofs) = l2_projection<HybridCore::PolyFaceBasisType>(exact_solution, hho.
FaceBasis(iF), quadF, phiF_quadF);
416 B = GlobRHS.segment(0, n_unknowns) - GlobMat.topRightCorner(n_unknowns, n_fixed_dofs) * UDir;
420 n_unknowns = m_ntotal_face_dofs;
423 UDir = Eigen::VectorXd::Zero(n_fixed_dofs);
428 Eigen::VectorXd xF = Eigen::VectorXd::Zero(n_unknowns);
436 Eigen::BiCGSTAB<Eigen::SparseMatrix<double> > solver;
438 xF = solver.solve(B);
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);
444 Xh.tail(n_fixed_dofs) = UDir;
445 Xh.segment(m_ntotal_cell_dofs, n_unknowns) = xF;
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"){
456 double total_measure = 0;
457 for (
size_t iT = 0; iT < mesh->
n_cells(); iT++){
459 total_measure += T.measure();
463 for (
size_t i = 0; i < basisT.
dimension(); i++){
464 for (
size_t iqn = 0; iqn < quadT.size(); iqn++){
465 average += quadT[iqn].w * Xh(iT * m_nlocal_cell_dofs + i) * basisT.
function(i, quadT[iqn].vector());
469 double average_exact_sol = 0.0;
473 average_exact_sol += qT.w * exact_solution(qT.vector());
476 average_exact_sol /= total_measure;
481 std::function<double(
VectorRd)> AveDiff = [&average_exact_sol,&average](
VectorRd x)->
double
482 {
return average_exact_sol - average;};
488 _solving_time = timer.elapsed().user + timer.elapsed().system;
497 Eigen::MatrixXd HHO_Diffusion::diffusion_operator(
HybridCore &hho,
const size_t iT,
const ElementQuad &elquad)
const {
499 boost::timer::cpu_timer timeint;
502 Cell* cell = mesh->cell(iT);
503 const size_t nfacesT = cell->n_faces();
506 size_t local_dofs = m_nlocal_cell_dofs + nfacesT * m_nlocal_face_dofs;
513 return kappa(cell->center_mass(), cell);
522 boost::multi_array<double, 2> phiT_quadT = elquad.
get_phiT_quadT();
523 boost::multi_array<VectorRd, 2> dphiT_quadT = elquad.
get_dphiT_quadT();
526 boost::multi_array<VectorRd, 2> kappaT_dphiT_quadT( boost::extents[dphiT_quadT.shape()[0]][quadT.size()] );
527 for (
size_t i = 0; i < dphiT_quadT.shape()[0]; i++){
528 for (
size_t iqn = 0; iqn < quadT.size(); iqn++){
529 kappaT_dphiT_quadT[i][iqn] = kappaT(quadT[iqn].vector()) * dphiT_quadT[i][iqn];
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));
542 Eigen::MatrixXd StiffT =
compute_gram_matrix(kappaT_dphiT_quadT, dphiT_quadT, quadT,
"sym");
544 _itime[1] += timeint.elapsed().user + timeint.elapsed().system;
548 Eigen::MatrixXd MTT =
compute_gram_matrix(phiT_quadT, phiT_quadT, quadT, m_nlocal_cell_dofs, m_nhighorder_dofs,
"sym");
550 _itime[2] += timeint.elapsed().user + timeint.elapsed().system;
554 Eigen::VectorXd LT = (MTT.row(0)).transpose();
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);
562 for (
size_t ilF = 0; ilF < nfacesT; ilF++) {
564 const size_t offset_F = m_nlocal_cell_dofs + ilF * m_nlocal_face_dofs;
565 const auto& nTF = cell->face_normal(ilF);
569 size_t nbqF = quadF.size();
571 boost::multi_array<double, 2> phiT_quadF = elquad.
get_phiT_quadF(ilF);
572 boost::multi_array<double, 2> phiF_quadF = elquad.
get_phiF_quadF(ilF);
573 boost::multi_array<VectorRd, 2> dphiT_quadF = elquad.
get_dphiT_quadF(ilF);
578 std::vector<VectorRd> quadF_kappaT_nTF(nbqF, VectorRd::Zero());
579 for (
size_t iqn = 0; iqn < nbqF; iqn++){
580 quadF_kappaT_nTF[iqn] = quadF[iqn].w * kappaT(quadF[iqn].vector())*nTF;
582 for (
size_t i = 1; i < m_nhighorder_dofs; i++) {
584 for (
size_t iqn = 0; iqn < nbqF; iqn++){
586 double contrib_i = dphiT_quadF[i][iqn].dot(quadF_kappaT_nTF[iqn]);
588 for (
size_t j = 0; j < m_nlocal_cell_dofs; j++) {
590 BP(i,j) -= contrib_i * phiT_quadF[j][iqn];
592 for (
size_t j = 0; j < m_nlocal_face_dofs; j++) {
594 BP(i, offset_F + j) += contrib_i * phiF_quadF[j][iqn];
601 MFT[ilF] =
compute_gram_matrix(phiF_quadF, phiT_quadF, quadF, m_nlocal_face_dofs, m_nhighorder_dofs,
"nonsym");
606 double scalT = StiffT.trace() / std::pow(LT.norm(), 2);
607 BP.topLeftCorner(m_nhighorder_dofs, m_nlocal_cell_dofs) += scalT * LTtLT.topLeftCorner(m_nhighorder_dofs, m_nlocal_cell_dofs);
608 Eigen::MatrixXd PT = ((StiffT+scalT*LTtLT).ldlt()).
solve(BP);
610 _itime[3] += timeint.elapsed().user + timeint.elapsed().system;
614 Eigen::MatrixXd ATF = PT.transpose() * StiffT * PT;
619 Eigen::MatrixXd STF = Eigen::MatrixXd::Zero(local_dofs, local_dofs);
622 Eigen::MatrixXd MTT_LL = MTT.topLeftCorner(m_nlocal_cell_dofs, m_nlocal_cell_dofs);
623 Eigen::MatrixXd deltaTL = MTT_LL.ldlt().solve( MTT * PT );
624 deltaTL.topLeftCorner(m_nlocal_cell_dofs, m_nlocal_cell_dofs) -= Eigen::MatrixXd::Identity(m_nlocal_cell_dofs, m_nlocal_cell_dofs);
626 for (
size_t ilF = 0; ilF < nfacesT; ilF++) {
628 double dTF = cell->face(ilF)->diam();
631 VectorRd xF = cell->face(ilF)->center_mass();
635 const VectorRd &nTF = cell->face_normal(ilF);
636 const double kappa_TF = (kappa(xF, cell) * nTF).dot(nTF);
639 Eigen::MatrixXd MFFinv = MFF[ilF].inverse();
640 Eigen::MatrixXd deltaTFK = MFFinv * MFT[ilF] * PT;
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);
645 Eigen::MatrixXd deltaTFK_minus_deltaTL = deltaTFK - MFFinv * MFT[ilF].topLeftCorner(m_nlocal_face_dofs, m_nlocal_cell_dofs) * deltaTL;
647 STF += (kappa_TF / dTF) * deltaTFK_minus_deltaTL.transpose() * MFF[ilF] * deltaTFK_minus_deltaTL;
650 _itime[5] += timeint.elapsed().user + timeint.elapsed().system;
653 ATF += mesh->dim() * STF;
664 Eigen::VectorXd HHO_Diffusion::load_operator(
HybridCore &hho,
const size_t iT,
const ElementQuad &elquad)
const {
667 Cell* cell = mesh->cell(iT);
668 size_t cell_face_dofs = m_nlocal_cell_dofs + cell->n_faces()*m_nlocal_face_dofs;
669 Eigen::VectorXd b = Eigen::VectorXd::Zero(cell_face_dofs);
673 size_t nbq = quadT.size();
674 boost::multi_array<double, 2> phiT_quadT = elquad.
get_phiT_quadT();
677 Eigen::ArrayXd weight_source_quad = Eigen::ArrayXd::Zero(nbq);
678 for (
size_t iqn = 0; iqn < nbq; iqn++){
679 weight_source_quad(iqn) = quadT[iqn].w * source(quadT[iqn].vector(), cell);
682 for (
size_t i=0; i < m_nlocal_cell_dofs; i++){
683 for (
size_t iqn = 0; iqn < quadT.size(); iqn++){
684 b(i) += weight_source_quad[iqn] * phiT_quadT[i][iqn];
689 if (cell->is_boundary()){
691 for (
size_t ilF = 0; ilF < cell->n_faces(); ilF++) {
692 Face* F = cell->face(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);
709 b(offset_F + i) += qF.w * Kgrad_n(qF.vector());
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:43
const std::string type(Face &face) const
Test the boundary condition of an face.
Definition: BoundaryConditions.cpp:31
const std::string name() const
Returns the complete name of the boundary condition.
Definition: BoundaryConditions.hpp:68
const size_t n_dir_faces() const
Returns the number of Dirichlet faces.
Definition: BoundaryConditions.hpp:63
Definition: elementquad.hpp:55
Family of functions expressed as linear combination of the functions of a given basis.
Definition: basis.hpp:388
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:2189
FunctionValue function(size_t i, const VectorRd &x) const
Evaluate the i-th function at point x.
Definition: basis.hpp:427
std::function< T(const VectorRd &, const Cell *)> CellFType
type for function of point. T is the return type of the function
Definition: basis.hpp:57
std::function< T(const VectorRd &)> FType
type for function of point. T is the return type of the function
Definition: basis.hpp:54
size_t dimension() const
Dimension of the family. This is actually the number of functions in the family, not necessarily line...
Definition: basis.hpp:421
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:339
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)
const boost::multi_array< VectorRd, 2 > & get_dphiT_quadF(size_t ilF) const
Returns values of gradients of cell basis functions at face quadrature nodes, for face with local num...
Definition: elementquad.hpp:103
Eigen::VectorXd compute_weights(size_t iT) const
Computes the weights to get cell values from face values when l=-1.
Definition: hybridcore.cpp:175
Eigen::VectorXd restr(size_t iT) const
Extract the restriction of the unknowns corresponding to cell iT and its faces.
Definition: hybridcore.cpp:28
const boost::multi_array< double, 2 > & get_phiT_quadF(size_t ilF) const
Returns values of cell basis functions at face quadrature nodes, for face with local number ilF.
Definition: elementquad.hpp:91
const boost::multi_array< VectorRd, 2 > & get_dphiT_quadT() const
Returns values of gradients of cell basis functions at cell quadrature nodes.
Definition: elementquad.hpp:85
const boost::multi_array< double, 2 > get_phiF_quadF(size_t ilF) const
Returns values of face basis functions at face quadrature nodes, for face with local number ilF.
Definition: elementquad.hpp:97
const PolyFaceBasisType & FaceBasis(size_t iF) const
Return face basis for face with global index iF.
Definition: hybridcore.hpp:215
const QuadratureRule & get_quadF(size_t ilF) const
Returns quadrature rules on face with local number ilF.
Definition: elementquad.hpp:73
const boost::multi_array< double, 2 > & get_phiT_quadT() const
Returns values of cell basis functions at cell quadrature nodes.
Definition: elementquad.hpp:79
Eigen::VectorXd & asVectorXd() const
Return the values as an Eigen vector.
Definition: hybridcore.hpp:97
UVector interpolate(const ContinuousFunction &f, const int deg_cell, const size_t deg_face, size_t doe) const
Compute the interpolant in the discrete space of a continuous function.
Definition: hybridcore.hpp:298
const QuadratureRule & get_quadT() const
Returns quadrature rules in cell.
Definition: elementquad.hpp:67
const Mesh * get_mesh() const
Returns a pointer to the mesh.
Definition: hybridcore.hpp:198
const PolyCellBasisType & CellBasis(size_t iT) const
Return cell basis for element with global index iT.
Definition: hybridcore.hpp:207
std::vector< Cell< dimension > * > get_cells() const
lists the cells in the mesh.
Definition: MeshND.hpp:88
std::size_t n_faces() const
number of faces in the mesh.
Definition: MeshND.hpp:59
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_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
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: ddr-magnetostatics.hpp:40
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