26 #ifndef _HHO_LOCVARDIFF_HPP
27 #define _HHO_LOCVARDIFF_HPP
33 #include <boost/timer/timer.hpp>
36 #include <Eigen/Sparse>
37 #include <Eigen/Dense>
76 std::string solver_type,
78 std::ostream & output = std::cout
91 return double(_assembly_time) * pow(10, -9);
96 return double(_solving_time) * pow(10, -9);
101 return _solving_error;
106 return double(_itime[idx]) * pow(10, -9);
126 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_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)
183 m_Ldeg(std::max(
L,0)),
185 _deg_kappa(deg_kappa),
188 exact_solution(exact_solution),
189 grad_exact_solution(grad_exact_solution),
190 solver_type(solver_type),
196 m_ntotal_cell_dofs(m_nlocal_cell_dofs * m_hho.get_mesh()->n_cells()),
197 m_ntotal_face_dofs(m_nlocal_face_dofs * m_hho.get_mesh()->n_faces()),
198 m_ndir_face_dofs(m_nlocal_face_dofs * m_BC.n_dir_faces()),
199 m_nnondir_face_dofs(m_nlocal_face_dofs * m_hho.get_mesh()->n_faces() - m_ndir_face_dofs),
200 m_ntotal_dofs(m_ntotal_cell_dofs + m_ntotal_face_dofs),
201 GlobRHS(Eigen::VectorXd::Zero(m_ntotal_face_dofs)),
202 ScRHS(Eigen::VectorXd::Zero(m_ntotal_cell_dofs))
204 m_output <<
"[HHO_LocVarDiff] Initializing" << std::endl;
205 GlobMat.resize(m_ntotal_face_dofs, m_ntotal_face_dofs);
206 ScBeMat.resize(m_ntotal_cell_dofs, m_ntotal_face_dofs);
212 boost::timer::cpu_timer timer;
219 std::vector<Eigen::Triplet<double>> triplets_GlobMat;
220 std::vector<Eigen::Triplet<double>> triplets_ScBe;
224 std::vector<std::vector<Eigen::Triplet<double>>> cell_triplets_GlobMat;
225 std::vector<std::vector<Eigen::Triplet<double>>> cell_triplets_ScBe;
226 std::vector<Eigen::VectorXd> cell_source(mesh->
n_cells());
227 cell_triplets_GlobMat.resize(mesh->
n_cells());
228 cell_triplets_ScBe.resize(mesh->
n_cells());
229 size_t size_triplets_GlobMat = 0;
230 size_t size_triplets_ScBe = 0;
235 std::function<void(
size_t,
size_t)> construct_all_local_contributions
236 = [&](
size_t start,
size_t end)->
void
238 for (
size_t iT = start; iT < end; iT++) {
242 size_t nlocal_faces = iCell->n_faces();
243 size_t face_dofs = nlocal_faces * m_nlocal_face_dofs;
246 size_t doeT = std::max( std::max(m_K,m_Ldeg) + m_K+1 , 2*m_K + _deg_kappa );
247 size_t doeF = 2*m_K + 1;
250 aT[iT] = diffusion_operator(hho, iT, elquad);
251 Eigen::VectorXd bT = load_operator(hho, iT, elquad);
254 Eigen::MatrixXd MatF = Eigen::MatrixXd::Zero(face_dofs,face_dofs);
255 cell_source[iT] = Eigen::VectorXd::Zero(face_dofs);
261 Eigen::MatrixXd ATT = aT[iT].topLeftCorner(m_nlocal_cell_dofs, m_nlocal_cell_dofs);
262 Eigen::MatrixXd ATF = aT[iT].topRightCorner(m_nlocal_cell_dofs, face_dofs);
263 Eigen::MatrixXd AFF = aT[iT].bottomRightCorner(face_dofs, face_dofs);
265 Eigen::PartialPivLU<Eigen::MatrixXd> invATT;
268 Eigen::MatrixXd invATT_ATF = invATT.solve(ATF);
269 Eigen::VectorXd invATT_bTcell = invATT.solve(bT.head(m_nlocal_cell_dofs));
270 MatF = AFF - ATF.transpose() * invATT_ATF;
272 cell_source[iT] = bT.tail(face_dofs) - ATF.transpose() * invATT_bTcell;
275 ScRHS.segment(iT * m_nlocal_cell_dofs, m_nlocal_cell_dofs) = invATT_bTcell;
276 for (
size_t i = 0; i < m_nlocal_cell_dofs; i++) {
277 for (
size_t jlF = 0; jlF < nlocal_faces; jlF++) {
278 const size_t jF = iCell->face(jlF)->global_index();
279 for (
size_t jk = 0; jk < m_nlocal_face_dofs; jk++) {
280 const size_t jLocal = jlF * m_nlocal_face_dofs + jk;
281 const size_t jGlobal = jF * m_nlocal_face_dofs + jk;
282 cell_triplets_ScBe[iT].emplace_back(iT * m_nlocal_cell_dofs + i, jGlobal, invATT_ATF(i, jLocal));
286 size_triplets_ScBe += cell_triplets_ScBe[iT].size();
292 Eigen::MatrixXd red_matT = Eigen::MatrixXd::Zero(1+nlocal_faces,nlocal_faces);
296 for (
size_t ilF = 0; ilF < nlocal_faces; ilF++){
297 VectorRd xF = iCell->face(ilF)->center_mass();
298 size_t iF = iCell->face(ilF)->global_index();
300 red_matT(0,ilF) *= phiF_cst / phiT_cst;
302 red_matT.bottomRightCorner(nlocal_faces,nlocal_faces) = Eigen::MatrixXd::Identity(nlocal_faces,nlocal_faces);
304 cell_source[iT] = red_matT.transpose() * bT;
305 MatF = red_matT.transpose() * aT[iT] * red_matT;
308 for (
size_t jlF = 0; jlF < nlocal_faces; jlF++) {
309 const size_t jF = iCell->face(jlF)->global_index();
310 const size_t jGlobal = jF * m_nlocal_face_dofs;
311 cell_triplets_ScBe[iT].emplace_back(iT, jGlobal, red_matT(0,jlF));
313 size_triplets_ScBe += cell_triplets_ScBe[iT].size();
318 for (
size_t ilF = 0; ilF < nlocal_faces; ilF++) {
319 const size_t iF = iCell->face(ilF)->global_index();
320 for (
size_t ik = 0; ik < m_nlocal_face_dofs; ik++) {
321 const size_t iLocal = ilF * m_nlocal_face_dofs + ik;
322 const size_t iGlobal = iF * m_nlocal_face_dofs + ik;
323 for (
size_t jlF = 0; jlF < nlocal_faces; jlF++) {
324 const size_t jF = iCell->face(jlF)->global_index();
325 for (
size_t jk = 0; jk < m_nlocal_face_dofs; jk++) {
326 const size_t jLocal = jlF * m_nlocal_face_dofs + jk;
327 const size_t jGlobal = jF * m_nlocal_face_dofs + jk;
328 cell_triplets_GlobMat[iT].emplace_back(iGlobal, jGlobal, MatF(iLocal, jLocal));
333 size_triplets_GlobMat += cell_triplets_GlobMat[iT].size();
342 triplets_ScBe.reserve(size_triplets_ScBe);
343 triplets_GlobMat.reserve(size_triplets_GlobMat);
344 for (
size_t iT = 0; iT < mesh->
n_cells(); iT++){
345 for (
size_t i = 0; i < cell_triplets_ScBe[iT].size(); i++){
346 triplets_ScBe.push_back(cell_triplets_ScBe[iT][i]);
348 for (
size_t i = 0; i < cell_triplets_GlobMat[iT].size(); i++){
349 triplets_GlobMat.push_back(cell_triplets_GlobMat[iT][i]);
352 for (
size_t ilF = 0; ilF < T.n_faces(); ilF++) {
353 const size_t iF = T.face(ilF)->global_index();
354 for (
size_t ik = 0; ik < m_nlocal_face_dofs; ik++) {
355 const size_t iLocal = ilF * m_nlocal_face_dofs + ik;
356 const size_t iGlobal = iF * m_nlocal_face_dofs + ik;
357 GlobRHS(iGlobal) += cell_source[iT](iLocal);
362 if (m_BC.
name()==
"Neumann"){
364 triplets_GlobMat.erase(std::remove_if(std::begin(triplets_GlobMat), std::end(triplets_GlobMat),
365 [](
const auto& x) {
return (x.row() == 0); }), std::end(triplets_GlobMat));
366 triplets_GlobMat.emplace_back(0, 0, 1);
371 GlobMat.setFromTriplets(std::begin(triplets_GlobMat), std::end(triplets_GlobMat));
372 ScBeMat.setFromTriplets(std::begin(triplets_ScBe), std::end(triplets_ScBe));
376 _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_LocVarDiff::diffusion_operator(
HybridCore &hho,
const size_t iT,
const ElementQuad &elquad)
const
500 boost::timer::cpu_timer timeint;
504 const size_t dimPKcell_vec = mesh->dim() * dimPKcell;
505 Cell* cell = mesh->cell(iT);
506 const size_t nfacesT = cell->n_faces();
509 size_t local_dofs = m_nlocal_cell_dofs + nfacesT * m_nlocal_face_dofs;
526 boost::multi_array<double, 2> phiT_quadT = elquad.
get_phiT_quadT();
527 boost::multi_array<VectorRd, 2> dphiT_quadT = elquad.
get_dphiT_quadT();
533 std::vector<MatrixRd> kappaT_quadT(quadT.size());
534 std::transform(quadT.begin(), quadT.end(), kappaT_quadT.begin(),
535 [
this,&cell](
QuadratureNode qr) -> Eigen::MatrixXd { return kappa(qr.vector(), cell); });
540 size_t maxdimPKL = std::max(m_nlocal_cell_dofs, dimPKcell);
542 _itime[0] += timeint.elapsed().user + timeint.elapsed().system;
545 Eigen::MatrixXd MTT =
compute_gram_matrix(phiT_quadT, phiT_quadT, quadT, maxdimPKL, m_nhighorder_dofs,
"sym");
546 Eigen::MatrixXd VecMTT = Eigen::MatrixXd::Zero(dimPKcell_vec, dimPKcell_vec);
547 for (
size_t r=0; r < mesh->dim(); r++){
548 VecMTT.block(r*dimPKcell, r*dimPKcell, dimPKcell, dimPKcell) = MTT.topLeftCorner(dimPKcell, dimPKcell);
555 std::vector<Eigen::MatrixXd> MFF(nfacesT, Eigen::MatrixXd::Zero(m_nlocal_face_dofs, m_nlocal_face_dofs));
556 std::vector<Eigen::MatrixXd> MFT(nfacesT, Eigen::MatrixXd::Zero(m_nlocal_face_dofs, m_nhighorder_dofs));
557 std::vector<Eigen::MatrixXd> MTT_on_F(nfacesT, Eigen::MatrixXd::Zero(dimPKcell, m_nlocal_cell_dofs));
559 for (
size_t ilF = 0; ilF < nfacesT; ilF++) {
563 boost::multi_array<double, 2> phiT_quadF = elquad.
get_phiT_quadF(ilF);
564 boost::multi_array<double, 2> phiF_quadF = elquad.
get_phiF_quadF(ilF);
569 MTT_on_F[ilF] =
compute_gram_matrix(phiT_quadF, phiT_quadF, quadF, dimPKcell, m_nlocal_cell_dofs,
"nonsym");
572 _itime[1] += timeint.elapsed().user + timeint.elapsed().system;
578 Eigen::MatrixXd MdphiT_PhiT =
compute_gram_matrix(dphiT_quadT, vec_phiT_quadT, quadT,
"nonsym");
580 _itime[2] += timeint.elapsed().user + timeint.elapsed().system;
586 Eigen::MatrixXd RHS_GT = Eigen::MatrixXd::Zero(dimPKcell_vec, local_dofs);
587 RHS_GT.topLeftCorner(dimPKcell_vec, m_nlocal_cell_dofs) = (MdphiT_PhiT.topLeftCorner(m_nlocal_cell_dofs, dimPKcell_vec)).transpose();
590 for (
size_t r=0; r < mesh->dim(); r++){
591 for (
size_t ilF = 0; ilF < nfacesT; ilF++) {
593 const size_t offset_F = m_nlocal_cell_dofs + ilF * m_nlocal_face_dofs;
594 const auto& nTF = cell->face_normal(ilF);
597 RHS_GT.block(r*dimPKcell, 0, dimPKcell, m_nlocal_cell_dofs) -= nTF(r) * MTT_on_F[ilF];
598 RHS_GT.block(r*dimPKcell, offset_F, dimPKcell, m_nlocal_face_dofs) +=
599 nTF(r) * (MFT[ilF].topLeftCorner(m_nlocal_face_dofs, dimPKcell)).transpose();
604 Eigen::MatrixXd GT = (VecMTT.ldlt()).
solve(RHS_GT);
611 boost::multi_array<VectorRd, 2> kappa_vec_phiT_quadT;
612 kappa_vec_phiT_quadT.resize( boost::extents[dimPKcell_vec][quadT.size()] );
613 for (
size_t i = 0; i < dimPKcell_vec; i++){
614 for (
size_t iqn = 0; iqn < quadT.size(); iqn++){
615 kappa_vec_phiT_quadT[i][iqn] = kappaT_quadT[iqn] * vec_phiT_quadT[i][iqn];
618 _itime[3] += timeint.elapsed().user + timeint.elapsed().system;
621 Eigen::MatrixXd kappaVecMTT =
compute_gram_matrix(kappa_vec_phiT_quadT, vec_phiT_quadT, quadT, vec_phiT_quadT.shape()[0], vec_phiT_quadT.shape()[0],
"sym");
623 _itime[4] += timeint.elapsed().user + timeint.elapsed().system;
626 Eigen::MatrixXd ATF = GT.transpose() * kappaVecMTT * GT;
635 Eigen::MatrixXd RHS_PT = MdphiT_PhiT * GT;
638 Eigen::VectorXd LT = (MTT.row(0)).transpose();
639 Eigen::MatrixXd LTtLT = LT * (LT.transpose());
640 double scalT = StiffT.trace() / std::pow(LT.norm(), 2);
643 RHS_PT.topLeftCorner(m_nhighorder_dofs, m_nlocal_cell_dofs) +=
644 scalT * LTtLT.topLeftCorner(m_nhighorder_dofs, m_nlocal_cell_dofs);
645 Eigen::MatrixXd PT = ((StiffT + scalT*LTtLT).ldlt()).
solve(RHS_PT);
650 Eigen::MatrixXd STF = Eigen::MatrixXd::Zero(local_dofs, local_dofs);
654 Eigen::MatrixXd MTT_LKp1 = MTT.topLeftCorner(m_nlocal_cell_dofs, m_nhighorder_dofs);
655 Eigen::MatrixXd MTT_LL = MTT.topLeftCorner(m_nlocal_cell_dofs, m_nlocal_cell_dofs);
656 Eigen::MatrixXd deltaTL = MTT_LL.ldlt().solve( MTT_LKp1 * PT );
657 deltaTL.topLeftCorner(m_nlocal_cell_dofs, m_nlocal_cell_dofs) -= Eigen::MatrixXd::Identity(m_nlocal_cell_dofs, m_nlocal_cell_dofs);
659 for (
size_t ilF = 0; ilF < nfacesT; ilF++) {
661 double dTF = cell->face(ilF)->diam();
664 VectorRd xF = cell->face(ilF)->center_mass();
668 const VectorRd &nTF = cell->face_normal(ilF);
669 const double kappa_TF = (kappa(xF, cell) * nTF).dot(nTF);
672 Eigen::MatrixXd MFFinv = MFF[ilF].inverse();
673 Eigen::MatrixXd deltaTFK = MFFinv * MFT[ilF] * PT;
674 deltaTFK.block(0, m_nlocal_cell_dofs + ilF * m_nlocal_face_dofs, m_nlocal_face_dofs, m_nlocal_face_dofs) -=
675 Eigen::MatrixXd::Identity(m_nlocal_face_dofs, m_nlocal_face_dofs);
678 Eigen::MatrixXd deltaTFK_minus_deltaTL = deltaTFK - MFFinv * MFT[ilF].topLeftCorner(m_nlocal_face_dofs, m_nlocal_cell_dofs) * deltaTL;
680 STF += (kappa_TF / dTF) * deltaTFK_minus_deltaTL.transpose() * MFF[ilF] * deltaTFK_minus_deltaTL;
684 _itime[5] += timeint.elapsed().user + timeint.elapsed().system;
689 ATF += mesh->dim() * STF;
700 Eigen::VectorXd HHO_LocVarDiff::load_operator(
HybridCore &hho,
const size_t iT,
const ElementQuad &elquad)
const {
703 Cell* cell = mesh->cell(iT);
704 size_t cell_face_dofs = m_nlocal_cell_dofs + cell->n_faces()*m_nlocal_face_dofs;
705 Eigen::VectorXd b = Eigen::VectorXd::Zero(cell_face_dofs);
709 size_t nbq = quadT.size();
710 boost::multi_array<double, 2> phiT_quadT = elquad.
get_phiT_quadT();
713 Eigen::ArrayXd weight_source_quad = Eigen::ArrayXd::Zero(nbq);
714 for (
size_t iqn = 0; iqn < nbq; iqn++){
715 weight_source_quad(iqn) = quadT[iqn].w * source(quadT[iqn].vector(), cell);
718 for (
size_t i=0; i < m_nlocal_cell_dofs; i++){
719 for (
size_t iqn = 0; iqn < quadT.size(); iqn++){
720 b(i) += weight_source_quad[iqn] * phiT_quadT[i][iqn];
725 if (cell->is_boundary()){
727 for (
size_t ilF = 0; ilF < cell->n_faces(); ilF++) {
728 Face* F = cell->face(ilF);
729 if (m_BC.
type(*F)==
"neu"){
730 const size_t iF = F->global_index();
732 if (F->is_boundary()){
734 const size_t offset_F = m_nlocal_cell_dofs + ilF * m_nlocal_face_dofs;
736 const auto& nTF = cell->face_normal(ilF);
739 for (
size_t i = 0; i < m_nlocal_face_dofs; i++){
742 return nTF.dot(kappa(p,cell) * grad_exact_solution(p,cell)) * basisF.function(i,p);
745 b(offset_F + i) += qF.w * Kgrad_n(qF.vector());
760 for (
size_t iT = 0; iT < mesh->n_cells(); iT++) {
761 Eigen::VectorXd XTF = Xh.
restr(iT);
762 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_LocVarDiff class provides tools to implement the HHO method for the diffusion problem.
Definition: HHO_LocVarDiff.hpp:63
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::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_solving_time() const
cpu time to solve the scheme
Definition: HHO_LocVarDiff.hpp:94
UVector solve(HybridCore &hho)
Definition: HHO_LocVarDiff.hpp:380
double EnergyNorm(HybridCore &hho, const UVector Xh)
Discrete energy norm (associated to the diffusion operator) of an hybrid function.
Definition: HHO_LocVarDiff.hpp:756
double get_solving_error() const
residual after solving the scheme
Definition: HHO_LocVarDiff.hpp:99
double get_assembly_time() const
cpu time to assemble the scheme
Definition: HHO_LocVarDiff.hpp:89
const size_t get_nlocal_face_dofs()
Number of DOFs on each face.
Definition: HHO_LocVarDiff.hpp:112
void assemble(HybridCore &hho)
Assemble and solve the scheme.
Definition: HHO_LocVarDiff.hpp:210
const size_t get_nhighorder_dofs()
Number of DOFs per cell for high-order (K+1) polynomials.
Definition: HHO_LocVarDiff.hpp:114
const size_t get_ntotal_cell_dofs()
Total number of cell DOFs over the entire mesh.
Definition: HHO_LocVarDiff.hpp:116
const size_t get_ntotal_dofs()
Total number of degrees of freedom over the entire mesh.
Definition: HHO_LocVarDiff.hpp:122
const size_t get_nlocal_cell_dofs()
Number of DOFs in each cell.
Definition: HHO_LocVarDiff.hpp:110
const size_t get_ndir_face_dofs()
Total number of face DOFs for Dirichlet faces.
Definition: HHO_LocVarDiff.hpp:120
double get_itime(size_t idx) const
various intermediate assembly times
Definition: HHO_LocVarDiff.hpp:104
const size_t get_ntotal_face_dofs()
Total number of face DOFs over the entire mesh.
Definition: HHO_LocVarDiff.hpp:118
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:179
size_t const DimPoly(int m)
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
boost::multi_array< VectorRd, 2 > get_vec_phiT_quadT(size_t degree) const
Builds on the fly the values of vector cell basis functions at cell quadrature nodes....
Definition: elementquad.cpp:61
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
const size_t DimPoly< Cell >(const int m)
Compute the size of the basis of 3-variate polynomials up to degree m.
Definition: hybridcore.hpp:61
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