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);
135 Eigen::MatrixXd diffusion_operator(
HybridCore& hho,
const size_t iT,
const ElementQuad& elquad)
const;
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)),
195 _deg_kappa(deg_kappa),
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),
211 GlobRHS(
Eigen::VectorXd::Zero(m_ntotal_edge_dofs)),
212 ScRHS(
Eigen::VectorXd::Zero(m_ntotal_cell_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;
229 std::vector<Eigen::Triplet<double>> triplets_GlobMat;
230 std::vector<Eigen::Triplet<double>> triplets_ScBe;
234 std::vector<std::vector<Eigen::Triplet<double>>> cell_triplets_GlobMat;
235 std::vector<std::vector<Eigen::Triplet<double>>> cell_triplets_ScBe;
236 std::vector<Eigen::VectorXd> cell_source(mesh->
n_cells());
237 cell_triplets_GlobMat.resize(mesh->
n_cells());
238 cell_triplets_ScBe.resize(mesh->
n_cells());
239 size_t size_triplets_GlobMat = 0;
240 size_t size_triplets_ScBe = 0;
245 std::function<void(
size_t,
size_t)> construct_all_local_contributions
246 = [&](
size_t start,
size_t end)->
void
248 for (
size_t iT = start; iT <
end; iT++) {
249 Cell* iCell = mesh->
cell(iT);
252 size_t nlocal_edges = iCell->
n_edges();
253 size_t edge_dofs = nlocal_edges * m_nlocal_edge_dofs;
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;
260 aT[iT] = diffusion_operator(hho, iT, elquad);
261 Eigen::VectorXd bT = load_operator(hho, iT, elquad);
264 Eigen::MatrixXd MatF = Eigen::MatrixXd::Zero(edge_dofs,edge_dofs);
265 cell_source[iT] = Eigen::VectorXd::Zero(edge_dofs);
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);
273 Eigen::MatrixXd AFF = aT[iT].bottomRightCorner(edge_dofs, edge_dofs);
275 Eigen::PartialPivLU<Eigen::MatrixXd> invATT;
278 Eigen::MatrixXd invATT_ATF = invATT.solve(ATF);
279 Eigen::VectorXd invATT_bTcell = invATT.solve(bT.head(m_nlocal_cell_dofs));
280 MatF = AFF - ATF.transpose() * invATT_ATF;
282 cell_source[iT] = bT.tail(edge_dofs) - ATF.transpose() * invATT_bTcell;
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++) {
287 for (
size_t jlF = 0; jlF < nlocal_edges; jlF++) {
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;
292 cell_triplets_ScBe[iT].emplace_back(iT * m_nlocal_cell_dofs +
i, jGlobal, invATT_ATF(
i, jLocal));
296 size_triplets_ScBe += cell_triplets_ScBe[iT].size();
302 Eigen::MatrixXd red_matT = Eigen::MatrixXd::Zero(1+nlocal_edges,nlocal_edges);
306 for (
size_t ilF = 0; ilF < nlocal_edges; ilF++){
307 VectorRd xF = iCell->edge(ilF)->center_mass();
308 size_t iF = iCell->edge(ilF)->global_index();
310 red_matT(0,ilF) *= phiF_cst / phiT_cst;
312 red_matT.bottomRightCorner(nlocal_edges,nlocal_edges) = Eigen::MatrixXd::Identity(nlocal_edges,nlocal_edges);
314 cell_source[iT] = red_matT.transpose() * bT;
315 MatF = red_matT.transpose() * aT[iT] * red_matT;
318 for (
size_t jlF = 0; jlF < nlocal_edges; jlF++) {
319 const size_t jF = iCell->edge(jlF)->global_index();
320 const size_t jGlobal = jF * m_nlocal_edge_dofs;
321 cell_triplets_ScBe[iT].emplace_back(iT, jGlobal, red_matT(0,jlF));
323 size_triplets_ScBe += cell_triplets_ScBe[iT].size();
328 for (
size_t ilF = 0; ilF < nlocal_edges; ilF++) {
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;
333 for (
size_t jlF = 0; jlF < nlocal_edges; jlF++) {
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;
338 cell_triplets_GlobMat[iT].emplace_back(iGlobal, jGlobal, MatF(iLocal, jLocal));
343 size_triplets_GlobMat += cell_triplets_GlobMat[iT].size();
352 triplets_ScBe.reserve(size_triplets_ScBe);
353 triplets_GlobMat.reserve(size_triplets_GlobMat);
354 for (
size_t iT = 0; iT < mesh->
n_cells(); iT++){
355 for (
size_t i = 0;
i < cell_triplets_ScBe[iT].size();
i++){
356 triplets_ScBe.push_back(cell_triplets_ScBe[iT][
i]);
358 for (
size_t i = 0;
i < cell_triplets_GlobMat[iT].size();
i++){
359 triplets_GlobMat.push_back(cell_triplets_GlobMat[iT][
i]);
361 Cell&
T = *mesh->
cell(iT);
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;
367 GlobRHS(iGlobal) += cell_source[iT](iLocal);
372 if (m_BC.
name()==
"Neumann"){
374 triplets_GlobMat.erase(std::remove_if(std::begin(triplets_GlobMat), std::end(triplets_GlobMat),
375 [](
const auto& x) {
return (x.row() == 0); }), std::end(triplets_GlobMat));
376 triplets_GlobMat.emplace_back(0, 0, 1);
381 GlobMat.setFromTriplets(std::begin(triplets_GlobMat), std::end(triplets_GlobMat));
382 ScBeMat.setFromTriplets(std::begin(triplets_ScBe), std::end(triplets_ScBe));
386 _assembly_time = timer.elapsed().wall;
392 boost::timer::cpu_timer timer;
401 size_t n_unknowns = 0;
402 size_t n_fixed_dofs = 0;
404 Eigen::VectorXd UDir;
406 if (m_BC.
name() !=
"Neumann"){
408 n_unknowns = m_nnondir_edge_dofs;
409 n_fixed_dofs = m_ndir_edge_dofs;
410 SysMat = GlobMat.topLeftCorner(n_unknowns, n_unknowns);
413 UDir = Eigen::VectorXd::Zero(n_fixed_dofs);
415 size_t n_nondir_edges = mesh->
n_edges() - n_dir_edges;
416 for (
size_t idF = 0; idF < n_dir_edges; idF++){
417 Edge* edge = mesh->
edge(n_nondir_edges + idF);
421 UDir.segment(idF * m_nlocal_edge_dofs, m_nlocal_edge_dofs) = l2_projection<HybridCore::PolyEdgeBasisType>(exact_solution, hho.
EdgeBasis(iF), quadF, phiF_quadF);
424 B = GlobRHS.segment(0, n_unknowns) - GlobMat.topRightCorner(n_unknowns, n_fixed_dofs) * UDir;
428 n_unknowns = m_ntotal_edge_dofs;
431 UDir = Eigen::VectorXd::Zero(n_fixed_dofs);
436 Eigen::VectorXd xF = Eigen::VectorXd::Zero(n_unknowns);
444 Eigen::BiCGSTAB<Eigen::SparseMatrix<double> > solver;
445 solver.compute(SysMat);
446 xF = solver.solve(B);
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);
452 Xh.tail(n_fixed_dofs) = UDir;
453 Xh.segment(m_ntotal_cell_dofs, n_unknowns) = xF;
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"){
464 double total_measure = 0;
465 for (
size_t iT = 0; iT < mesh->
n_cells(); iT++){
466 Cell&
T = *mesh->
cell(iT);
472 for (
size_t iqn = 0; iqn < quadT.size(); iqn++){
473 average += quadT[iqn].w * Xh(iT * m_nlocal_cell_dofs +
i) * basisT.
function(
i, quadT[iqn].vector());
477 double average_exact_sol = 0.0;
481 average_exact_sol += qT.w * exact_solution(qT.vector());
484 average_exact_sol /= total_measure;
489 std::function<double(
VectorRd)> AveDiff = [&average_exact_sol,&average](
VectorRd x)->
double
490 {
return average_exact_sol - average;};
496 _solving_time = timer.elapsed().user + timer.elapsed().system;
505 Eigen::MatrixXd HHO_LocVarDiff::diffusion_operator(
HybridCore &hho,
const size_t iT,
const ElementQuad &elquad)
const
508 boost::timer::cpu_timer timeint;
512 const size_t dimPKcell_vec = mesh->dim() * dimPKcell;
513 Cell* cell = mesh->cell(iT);
514 const size_t nedgesT = cell->n_edges();
517 size_t local_dofs = m_nlocal_cell_dofs + nedgesT * m_nlocal_edge_dofs;
534 boost::multi_array<double, 2> phiT_quadT = elquad.
get_phiT_quadT();
535 boost::multi_array<VectorRd, 2> dphiT_quadT = elquad.
get_dphiT_quadT();
541 std::vector<MatrixRd> kappaT_quadT(quadT.size());
542 std::transform(quadT.begin(), quadT.end(), kappaT_quadT.begin(),
543 [
this,&cell](
QuadratureNode qr) -> Eigen::MatrixXd { return kappa(qr.vector(), cell); });
548 size_t maxdimPKL = std::max(m_nlocal_cell_dofs, dimPKcell);
550 _itime[0] += timeint.elapsed().user + timeint.elapsed().system;
553 Eigen::MatrixXd MTT =
compute_gram_matrix(phiT_quadT, phiT_quadT, quadT, maxdimPKL, m_nhighorder_dofs,
"sym");
554 Eigen::MatrixXd VecMTT = Eigen::MatrixXd::Zero(dimPKcell_vec, dimPKcell_vec);
555 for (
size_t r=0; r < mesh->dim(); r++){
556 VecMTT.block(r*dimPKcell, r*dimPKcell, dimPKcell, dimPKcell) = MTT.topLeftCorner(dimPKcell, dimPKcell);
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));
565 std::vector<Eigen::MatrixXd> MTT_on_F(nedgesT, Eigen::MatrixXd::Zero(dimPKcell, m_nlocal_cell_dofs));
567 for (
size_t ilF = 0; ilF < nedgesT; ilF++) {
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);
577 MTT_on_F[ilF] =
compute_gram_matrix(phiT_quadF, phiT_quadF, quadF, dimPKcell, m_nlocal_cell_dofs,
"nonsym");
580 _itime[1] += timeint.elapsed().user + timeint.elapsed().system;
586 Eigen::MatrixXd MdphiT_PhiT =
compute_gram_matrix(dphiT_quadT, vec_phiT_quadT, quadT,
"nonsym");
588 _itime[2] += timeint.elapsed().user + timeint.elapsed().system;
594 Eigen::MatrixXd RHS_GT = Eigen::MatrixXd::Zero(dimPKcell_vec, local_dofs);
595 RHS_GT.topLeftCorner(dimPKcell_vec, m_nlocal_cell_dofs) = (MdphiT_PhiT.topLeftCorner(m_nlocal_cell_dofs, dimPKcell_vec)).transpose();
598 for (
size_t r=0; r < mesh->dim(); r++){
599 for (
size_t ilF = 0; ilF < nedgesT; ilF++) {
601 const size_t offset_F = m_nlocal_cell_dofs + ilF * m_nlocal_edge_dofs;
602 const auto& nTF = cell->edge_normal(ilF);
605 RHS_GT.block(r*dimPKcell, 0, dimPKcell, m_nlocal_cell_dofs) -= nTF(r) * MTT_on_F[ilF];
606 RHS_GT.block(r*dimPKcell, offset_F, dimPKcell, m_nlocal_edge_dofs) +=
607 nTF(r) * (MFT[ilF].topLeftCorner(m_nlocal_edge_dofs, dimPKcell)).transpose();
612 Eigen::MatrixXd GT = (VecMTT.ldlt()).
solve(RHS_GT);
619 boost::multi_array<VectorRd, 2> kappa_vec_phiT_quadT;
620 kappa_vec_phiT_quadT.resize( boost::extents[dimPKcell_vec][quadT.size()] );
621 for (
size_t i = 0;
i < dimPKcell_vec;
i++){
622 for (
size_t iqn = 0; iqn < quadT.size(); iqn++){
623 kappa_vec_phiT_quadT[
i][iqn] = kappaT_quadT[iqn] * vec_phiT_quadT[
i][iqn];
626 _itime[3] += timeint.elapsed().user + timeint.elapsed().system;
629 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");
631 _itime[4] += timeint.elapsed().user + timeint.elapsed().system;
634 Eigen::MatrixXd ATF = GT.transpose() * kappaVecMTT * GT;
643 Eigen::MatrixXd RHS_PT = MdphiT_PhiT * GT;
646 Eigen::VectorXd LT = (MTT.row(0)).transpose();
647 Eigen::MatrixXd LTtLT = LT * (LT.transpose());
648 double scalT = StiffT.trace() / std::pow(LT.norm(), 2);
651 RHS_PT.topLeftCorner(m_nhighorder_dofs, m_nlocal_cell_dofs) +=
652 scalT * LTtLT.topLeftCorner(m_nhighorder_dofs, m_nlocal_cell_dofs);
653 Eigen::MatrixXd PT = ((StiffT + scalT*LTtLT).ldlt()).
solve(RHS_PT);
658 Eigen::MatrixXd STF = Eigen::MatrixXd::Zero(local_dofs, local_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);
664 Eigen::MatrixXd deltaTL = MTT_LL.ldlt().solve( MTT_LKp1 * PT );
665 deltaTL.topLeftCorner(m_nlocal_cell_dofs, m_nlocal_cell_dofs) -= Eigen::MatrixXd::Identity(m_nlocal_cell_dofs, m_nlocal_cell_dofs);
667 for (
size_t ilF = 0; ilF < nedgesT; ilF++) {
669 double dTF = cell->edge(ilF)->diam();
672 VectorRd xF = cell->edge(ilF)->center_mass();
676 const VectorRd &nTF = cell->edge_normal(ilF);
677 const double kappa_TF = (kappa(xF, cell) * nTF).dot(nTF);
680 Eigen::MatrixXd MFFinv = MFF[ilF].inverse();
681 Eigen::MatrixXd deltaTFK = MFFinv * MFT[ilF] * PT;
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);
686 Eigen::MatrixXd deltaTFK_minus_deltaTL = deltaTFK - MFFinv * MFT[ilF].topLeftCorner(m_nlocal_edge_dofs, m_nlocal_cell_dofs) * deltaTL;
688 STF += (kappa_TF / dTF) * deltaTFK_minus_deltaTL.transpose() * MFF[ilF] * deltaTFK_minus_deltaTL;
691 _itime[5] += timeint.elapsed().user + timeint.elapsed().system;
694 ATF += mesh->dim() * STF;
705 Eigen::VectorXd HHO_LocVarDiff::load_operator(
HybridCore &hho,
const size_t iT,
const ElementQuad &elquad)
const {
708 Cell* cell = mesh->cell(iT);
709 size_t cell_edge_dofs = m_nlocal_cell_dofs + cell->n_edges()*m_nlocal_edge_dofs;
710 Eigen::VectorXd b = Eigen::VectorXd::Zero(cell_edge_dofs);
714 size_t nbq = quadT.size();
715 boost::multi_array<double, 2> phiT_quadT = elquad.
get_phiT_quadT();
718 Eigen::ArrayXd weight_source_quad = Eigen::ArrayXd::Zero(nbq);
719 for (
size_t iqn = 0; iqn < nbq; iqn++){
720 weight_source_quad(iqn) = quadT[iqn].w * source(quadT[iqn].vector(), cell);
723 for (
size_t i=0;
i < m_nlocal_cell_dofs;
i++){
724 for (
size_t iqn = 0; iqn < quadT.size(); iqn++){
725 b(
i) += weight_source_quad[iqn] * phiT_quadT[
i][iqn];
730 if (cell->is_boundary()){
732 for (
size_t ilF = 0; ilF < cell->n_edges(); ilF++) {
733 Edge* F = cell->edge(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);
750 b(offset_F +
i) += qF.w * Kgrad_n(qF.vector());
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
Compute max and min eigenvalues of all matrices for i
Definition compute_eigs.m:5
end
Definition compute_eigs.m:12
FunctionValue function(size_t i, const VectorRd &x) const
Evaluate the i-th function at point x.
Definition basis.hpp:351
Eigen::Vector2d VectorRd
Definition basis.hpp:55
size_t dimension() const
Dimension of the family. This is actually the number of functions in the family, not necessarily line...
Definition basis.hpp:345
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:225
std::function< T(const VectorRd &)> FType
type for function of point. T is the type of value of the function
Definition basis.hpp:62
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:2288
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:47
size_t L
Definition HHO_DiffAdvecReac.hpp:46
size_t K
Definition HHO_DiffAdvecReac.hpp:46
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
Eigen::VectorXd compute_weights(size_t iT) const
Computes the weights to get cell values from edge values when l=-1.
Definition hybridcore.cpp:138
Eigen::VectorXd restr(size_t iT) const
Extract the restriction of the unknowns corresponding to cell iT and its edges.
Definition hybridcore.cpp:29
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
const QuadratureRule & get_quadT() const
Returns quadrature rules in cell.
Definition elementquad.hpp:61
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:62
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:79
const QuadratureRule & get_quadF(size_t ilF) const
Returns quadrature rules on edge with local number ilF.
Definition elementquad.hpp:67
const PolyEdgeBasisType & EdgeBasis(size_t iE) const
Return edge basis for edge with global index iE.
Definition hybridcore.hpp:218
UVector interpolate(const ContinuousFunction &f, const int deg_cell, const size_t deg_edge, size_t doe) const
Compute the interpolant in the discrete space of a continuous function.
Definition hybridcore.hpp:290
Eigen::VectorXd & asVectorXd() const
Return the values as an Eigen vector.
Definition hybridcore.hpp:92
const boost::multi_array< double, 2 > & get_phiT_quadF(size_t ilF) const
Returns values of cell basis functions at edge quadrature nodes, for edge with local number ilF.
Definition elementquad.hpp:85
const boost::multi_array< double, 2 > get_phiF_quadF(size_t ilF) const
Returns values of edge basis functions at edge quadrature nodes, for edge with local number ilF.
Definition elementquad.hpp:91
size_t const DimPoly(int m)
const boost::multi_array< double, 2 > & get_phiT_quadT() const
Returns values of cell basis functions at cell quadrature nodes.
Definition elementquad.hpp:73
const Mesh * get_mesh() const
Returns a pointer to the mesh.
Definition hybridcore.hpp:201
const PolyCellBasisType & CellBasis(size_t iT) const
Return cell basis for element with global index iT.
Definition hybridcore.hpp:210
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:76
Polytope< DIMENSION > Cell
Definition Polytope2D.hpp:151
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:88
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:147
Polytope< 1 > * edge(const size_t i) const
Return the i-th edge of the Polytope.
Definition Polytope2D.hpp:303
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:73
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
if(strcmp(field, 'real')) % real valued entries T
Definition mmread.m:93
Definition PastixInterface.hpp:16
Definition ddr-klplate.hpp:27
Description of one node and one weight from a quadrature rule.
Definition quadraturerule.hpp:41