18#include <boost/program_options.hpp>
19#include <boost/timer/timer.hpp>
56 assert((
size_t)(m_values.size()) == n_total_dofs);
60 inline Eigen::VectorXd
asVectorXd()
const {
return m_values; }
72 return m_values.head(n_total_cell_velocity_dofs +
73 n_total_face_velocity_dofs);
78 return m_values.segment(n_total_cell_velocity_dofs + n_total_face_velocity_dofs, n_total_pressure_dofs);
83 return m_values.segment( n_total_cell_velocity_dofs + n_total_face_velocity_dofs + n_total_pressure_dofs, n_total_cell_magnetic_dofs + n_total_face_magnetic_dofs);
88 return m_values.tail(n_total_lagrange_dofs);
93 Eigen::VectorXd
XTF = Eigen::VectorXd::Zero(n_local_velocity_dofs(
iT));
95 XTF.head(n_local_cell_velocity_dofs) = m_values.segment(
iT * n_local_cell_velocity_dofs, n_local_cell_velocity_dofs);
98 size_t global_offset = n_total_cell_velocity_dofs + m_mesh_ptr->
cell(
iT)->face(
iTF)->global_index() * n_local_face_velocity_dofs;
99 size_t local_offset = n_local_cell_velocity_dofs +
iTF * n_local_face_velocity_dofs;
108 size_t offset = n_total_cell_velocity_dofs + n_total_face_velocity_dofs +
iT * n_local_pressure_dofs;
110 return m_values.segment(
offset, n_local_pressure_dofs);
115 Eigen::VectorXd
XTF = Eigen::VectorXd::Zero(n_local_magnetic_dofs(
iT));
117 size_t offset = n_total_cell_velocity_dofs + n_total_face_velocity_dofs + n_total_pressure_dofs;
119 XTF.head(n_local_cell_magnetic_dofs) = m_values.segment(
offset +
iT * n_local_cell_magnetic_dofs, n_local_cell_magnetic_dofs);
122 size_t global_offset =
offset + n_total_cell_magnetic_dofs + m_mesh_ptr->
cell(
iT)->face(
iTF)->global_index() * n_local_face_magnetic_dofs;
123 size_t local_offset = n_local_cell_magnetic_dofs +
iTF * n_local_face_magnetic_dofs;
132 size_t offset = n_total_cell_velocity_dofs + n_total_face_velocity_dofs + n_total_pressure_dofs + n_total_cell_magnetic_dofs + n_total_face_magnetic_dofs +
iT * n_local_lagrange_dofs;
134 return m_values.segment(
offset, n_local_lagrange_dofs);
139 Eigen::VectorXd
XTF = Eigen::VectorXd::Zero( n_local_velocity_dofs(
iT) + n_local_pressure_dofs + n_local_magnetic_dofs(
iT) + n_local_lagrange_dofs);
143 XTF.segment(n_local_velocity_dofs(
iT) + n_local_pressure_dofs, n_local_magnetic_dofs(
iT)) = this->
magnetic_restr(iT);
152 assert(m_cell_deg ==
b.get_cell_deg() || m_face_deg ==
b.get_face_deg());
153 return SolutionVector(m_values +
b.asVectorXd(), m_mesh_ptr, m_cell_deg, m_face_deg);
159 assert(m_cell_deg ==
b.get_cell_deg() || m_face_deg ==
b.get_face_deg());
160 return SolutionVector(m_values -
b.asVectorXd(), m_mesh_ptr, m_cell_deg, m_face_deg);
164 double operator()(
size_t index)
const {
return m_values(index); }
170 mutable Eigen::VectorXd m_values;
171 const Mesh *m_mesh_ptr;
173 const size_t m_cell_deg;
174 const size_t m_face_deg;
176 static const size_t dim = 3;
178 const size_t n_cells = m_mesh_ptr->
n_cells();
179 const size_t n_faces = m_mesh_ptr->
n_faces();
181 const size_t n_local_cell_velocity_dofs = dim *
DimPoly<Cell>(m_cell_deg);
182 const size_t n_local_cell_magnetic_dofs = dim *
DimPoly<Cell>(m_cell_deg);
183 const size_t n_local_face_velocity_dofs = dim *
DimPoly<Face>(m_face_deg);
184 const size_t n_local_face_magnetic_dofs = dim *
DimPoly<Face>(m_face_deg);
185 const size_t n_local_pressure_dofs =
DimPoly<Cell>(m_cell_deg);
186 const size_t n_local_lagrange_dofs =
DimPoly<Cell>(m_cell_deg);
188 const size_t n_total_cell_velocity_dofs = n_cells * n_local_cell_velocity_dofs;
189 const size_t n_total_cell_magnetic_dofs = n_cells * n_local_cell_magnetic_dofs;
190 const size_t n_total_face_velocity_dofs = n_faces * n_local_face_velocity_dofs;
191 const size_t n_total_face_magnetic_dofs = n_faces * n_local_face_magnetic_dofs;
192 const size_t n_total_pressure_dofs = n_cells * n_local_pressure_dofs;
193 const size_t n_total_lagrange_dofs = n_cells * n_local_lagrange_dofs;
195 const size_t n_total_dofs = n_total_cell_velocity_dofs + n_total_cell_magnetic_dofs + n_total_face_velocity_dofs + n_total_face_magnetic_dofs + n_total_pressure_dofs + n_total_lagrange_dofs;
197 inline size_t n_local_velocity_dofs(
const size_t iT)
const
199 return n_local_cell_velocity_dofs + m_mesh_ptr->
cell(
iT)->n_faces() * n_local_face_velocity_dofs;
202 inline size_t n_local_magnetic_dofs(
const size_t iT)
const
204 return n_local_cell_magnetic_dofs + m_mesh_ptr->
cell(
iT)->n_faces() * n_local_face_magnetic_dofs;
222 Eigen::MatrixXd convective_term(Cell *cell, std::vector<Eigen::MatrixXd>
tplus_k, std::vector<Eigen::MatrixXd>
tminus_k, Eigen::VectorXd u);
235 static const size_t dim = 3;
239 const size_t n_cells = mesh_ptr->
n_cells();
240 const size_t n_faces = mesh_ptr->
n_faces();
241 const size_t n_bdry_faces = mesh_ptr->
n_b_faces();
245 const size_t n_local_highorder_scalar_dofs =
DimPoly<Cell>(m_K + 1);
247 const size_t n_local_cell_vector_dofs = dim *
DimPoly<Cell>(m_L);
248 const size_t n_local_face_vector_dofs = dim *
DimPoly<Face>(m_K);
249 const size_t n_local_highorder_vector_dofs = dim *
DimPoly<Cell>(m_K + 1);
251 const size_t n_total_cell_scalar_dofs = n_local_cell_scalar_dofs * n_cells;
254 const size_t n_total_cell_vector_dofs = n_local_cell_vector_dofs * n_cells;
255 const size_t n_total_face_vector_dofs = n_local_face_vector_dofs * n_faces;
259 Eigen::SparseMatrix<double> inv_LTll_LTlg;
260 Eigen::SparseMatrix<double> LTgl;
261 Eigen::SparseMatrix<double> LTgg;
263 Eigen::VectorXd inv_LTll_rTl;
265 std::vector<Eigen::MatrixXd> AT;
266 std::vector<Eigen::MatrixXd> RT;
296 for (
size_t iT = 0;
iT < n_cells; ++
iT)
317 Eigen::MatrixXd
vec_MTT = Eigen::MatrixXd::Zero(n_local_cell_vector_dofs, n_local_cell_vector_dofs);
319 for (
size_t d = 0;
d < dim;
d++)
321 for (
size_t i = 0;
i < n_local_cell_scalar_dofs;
i++)
323 for (
size_t j = 0;
j < n_local_cell_scalar_dofs;
j++)
335 Cell *cell = mesh_ptr->
cell(
iT);
340 for (
size_t iTF = 0;
iTF < cell->n_faces();
iTF++)
342 const size_t offset_F =
iTF * n_local_face_vector_dofs;
348 boost::extents[n_local_face_vector_dofs][
quadF.size()]);
350 for (
size_t d = 0;
d < dim;
d++)
352 VectorRd
eF = VectorRd::Zero();
357 eF = cell->face(
iTF)->normal();
361 eF = cell->face(
iTF)->edge(0)->tangent();
366 eF = (cell->face(
iTF)->normal()).
cross(cell->face(
iTF)->edge(0)->tangent());
375 for (
size_t i = 0;
i < n_local_face_scalar_dofs;
i++)
385 double hT = cell->diam();
449 Eigen::VectorXd
values = Eigen::VectorXd::Zero(2 * (n_total_cell_vector_dofs + n_total_face_vector_dofs + n_total_cell_scalar_dofs));
450 for (
size_t iT = 0;
iT < n_cells; ++
iT)
453 Cell *cell = mesh_ptr->
cell(
iT);
459 values.segment(
iT * n_local_cell_vector_dofs, n_local_cell_vector_dofs) =
local_Ikv.head(n_local_cell_vector_dofs);
460 for (
size_t iTF = 0;
iTF < cell->n_faces(); ++
iTF)
462 values.segment(n_total_cell_vector_dofs + cell->face(
iTF)->global_index() * n_local_face_vector_dofs, n_local_face_vector_dofs) =
local_Ikv.segment(n_local_cell_vector_dofs +
iTF * n_local_face_vector_dofs, n_local_face_vector_dofs);
464 values.segment(n_total_cell_vector_dofs + n_total_face_vector_dofs +
iT * n_local_cell_scalar_dofs, n_local_cell_scalar_dofs) =
local_pikp;
466 size_t magnetic_offset = n_total_cell_vector_dofs + n_total_face_vector_dofs + n_total_cell_scalar_dofs;
468 for (
size_t iTF = 0;
iTF < cell->n_faces(); ++
iTF)
470 values.segment(
magnetic_offset + n_total_cell_vector_dofs + cell->face(
iTF)->global_index() * n_local_face_vector_dofs, n_local_face_vector_dofs) =
local_Ikm.segment(n_local_cell_vector_dofs +
iTF * n_local_face_vector_dofs, n_local_face_vector_dofs);
492 return (
MTT.ldlt()).solve(
RHS);
510 for (
size_t i = 0;
i < n_local_cell_scalar_dofs;
i++)
519 const size_t offset_F = n_local_cell_vector_dofs +
iTF * n_local_face_vector_dofs;
528 for (
size_t k = 0;
k < dim;
k++)
535 eF = cell->face(
iTF)->normal();
539 eF = cell->face(
iTF)->edge(0)->tangent();
544 eF = (cell->face(
iTF)->normal()).
cross(cell->face(
iTF)->edge(0)->tangent());
553 for (
size_t i = 0;
i < n_local_face_scalar_dofs;
i++)
582 for (
size_t k = 0;
k < dim;
k++)
586 for (
size_t i = 0;
i < n_local_cell_scalar_dofs;
i++)
601 const size_t offset_F = n_local_cell_vector_dofs +
iTF * n_local_face_vector_dofs;
613 for (
size_t k = 0;
k < dim;
k++)
623 eF = cell->face(
iTF)->normal();
627 eF = cell->face(
iTF)->edge(0)->tangent();
632 eF = (cell->face(
iTF)->normal()).
cross(cell->face(
iTF)->edge(0)->tangent());
641 for (
size_t i = 0;
i < n_local_face_scalar_dofs;
i++)
645 for (
size_t i = 0;
i < n_local_cell_scalar_dofs;
i++)
675 Eigen::MatrixXd
vec_MTT = Eigen::MatrixXd::Zero(n_local_cell_vector_dofs, n_local_highorder_vector_dofs);
677 Eigen::MatrixXd
vec_StiffT = Eigen::MatrixXd::Zero(n_local_highorder_vector_dofs, n_local_highorder_vector_dofs);
679 for (
size_t k = 0;
k < dim;
k++)
681 for (
size_t i = 0;
i < n_local_highorder_scalar_dofs;
i++)
683 for (
size_t j = 0;
j < n_local_highorder_scalar_dofs;
j++)
685 if (
i < n_local_cell_scalar_dofs)
694 Eigen::MatrixXd
LT = (
vec_MTT.topRightCorner(dim, n_local_highorder_vector_dofs)).
transpose();
695 Eigen::MatrixXd
LTtLT =
LT * (
LT.transpose());
699 RT_RHS.topLeftCorner(n_local_highorder_vector_dofs, n_local_cell_vector_dofs) =
vec_StiffT.topLeftCorner(n_local_highorder_vector_dofs, n_local_cell_vector_dofs) +
scalT *
LTtLT.topLeftCorner(n_local_highorder_vector_dofs, n_local_cell_vector_dofs);
703 const size_t offset_F = n_local_cell_vector_dofs +
iTF * n_local_face_vector_dofs;
718 for (
size_t k = 0;
k < dim;
k++)
728 eF = cell->face(
iTF)->normal();
732 eF = cell->face(
iTF)->edge(0)->tangent();
737 eF = (cell->face(
iTF)->normal()).
cross(cell->face(
iTF)->edge(0)->tangent());
746 for (
size_t i = 0;
i < n_local_face_scalar_dofs;
i++)
750 for (
size_t i = 0;
i < n_local_highorder_scalar_dofs;
i++)
752 if (
i < n_local_cell_scalar_dofs)
768 return RT[cell->global_index()].transpose() *
vec_StiffT * RT[cell->global_index()];
771Eigen::MatrixXd MHDModel::th_ijk_plus_th_ikj(Cell *cell,
ElementQuad &
elquad,
size_t k)
784 if (
k < n_local_cell_vector_dofs)
803 for (
size_t d = 0;
d < dim; ++
d)
807 for (
size_t i = 0;
i < n_local_cell_scalar_dofs;
i++)
836 const size_t offset_F = n_local_cell_vector_dofs +
iTF * n_local_face_vector_dofs;
850 for (
size_t d = 0;
d < dim; ++
d)
860 eF = cell->face(
iTF)->normal();
864 eF = cell->face(
iTF)->edge(0)->tangent();
869 eF = (cell->face(
iTF)->normal()).
cross(cell->face(
iTF)->edge(0)->tangent());
881 for (
size_t i = 0;
i < n_local_cell_scalar_dofs;
i++)
886 for (
size_t i = 0;
i < n_local_face_scalar_dofs;
i++)
910 size_t iTF = (
k - n_local_cell_vector_dofs) / n_local_face_vector_dofs;
911 size_t k_basis = (
k - n_local_cell_vector_dofs) % n_local_face_vector_dofs;
919 eF = cell->face(
iTF)->normal();
923 eF = cell->face(
iTF)->edge(0)->tangent();
928 eF = (cell->face(
iTF)->normal()).
cross(cell->face(
iTF)->edge(0)->tangent());
945 for (
size_t d = 0;
d < dim; ++
d)
947 for (
size_t i = 0;
i < n_local_cell_scalar_dofs;
i++)
967Eigen::MatrixXd MHDModel::th_ijk_minus_th_ikj(Cell *cell,
ElementQuad &
elquad,
size_t k)
980 if (
k < n_local_cell_vector_dofs)
999 for (
size_t d = 0;
d < dim; ++
d)
1003 for (
size_t i = 0;
i < n_local_cell_scalar_dofs;
i++)
1024 const size_t offset_F = n_local_cell_vector_dofs +
iTF * n_local_face_vector_dofs;
1038 for (
size_t d = 0;
d < dim; ++
d)
1045 eF = cell->face(
iTF)->normal();
1049 eF = cell->face(
iTF)->edge(0)->tangent();
1054 eF = (cell->face(
iTF)->normal()).
cross(cell->face(
iTF)->edge(0)->tangent());
1066 for (
size_t i = 0;
i < n_local_cell_scalar_dofs;
i++)
1071 for (
size_t i = 0;
i < n_local_face_scalar_dofs;
i++)
1090 size_t iTF = (
k - n_local_cell_vector_dofs) / n_local_face_vector_dofs;
1091 size_t k_basis = (
k - n_local_cell_vector_dofs) % n_local_face_vector_dofs;
1099 eF = cell->face(
iTF)->normal();
1103 eF = cell->face(
iTF)->edge(0)->tangent();
1108 eF = (cell->face(
iTF)->normal()).
cross(cell->face(
iTF)->edge(0)->tangent());
1124 for (
size_t d = 0;
d < dim; ++
d)
1126 for (
size_t i = 0;
i < n_local_cell_scalar_dofs;
i++)
1142Eigen::MatrixXd MHDModel::convective_term(Cell *cell, std::vector<Eigen::MatrixXd>
tplus_k, std::vector<Eigen::MatrixXd>
tminus_k, Eigen::VectorXd u)
1175 Eigen::MatrixXd
vec_MTT = Eigen::MatrixXd::Zero(n_local_cell_vector_dofs, n_local_highorder_vector_dofs);
1176 Eigen::MatrixXd
vec_StiffT = Eigen::MatrixXd::Zero(n_local_cell_vector_dofs, n_local_cell_vector_dofs);
1178 for (
size_t k = 0;
k < dim;
k++)
1180 for (
size_t i = 0;
i < n_local_cell_scalar_dofs;
i++)
1182 for (
size_t j = 0;
j < n_local_highorder_scalar_dofs;
j++)
1184 if (
j < n_local_cell_scalar_dofs)
1193 Eigen::MatrixXd
diffT = (
vec_MTT.topLeftCorner(n_local_cell_vector_dofs, n_local_cell_vector_dofs).ldlt()).solve(
vec_MTT) * RT[cell->global_index()];
1194 diffT.topLeftCorner(n_local_cell_vector_dofs, n_local_cell_vector_dofs) -= Eigen::MatrixXd::Identity(n_local_cell_vector_dofs, n_local_cell_vector_dofs);
1206 const size_t offset_F =
iTF * n_local_face_vector_dofs;
1217 for (
size_t d = 0;
d < dim;
d++)
1227 eF = cell->face(
iTF)->normal();
1231 eF = cell->face(
iTF)->edge(0)->tangent();
1236 eF = (cell->face(
iTF)->normal()).
cross(cell->face(
iTF)->edge(0)->tangent());
1245 for (
size_t i = 0;
i < n_local_face_scalar_dofs;
i++)
1249 for (
size_t i = 0;
i < n_local_highorder_scalar_dofs;
i++)
1259 Eigen::MatrixXd
LOCAL_SCALING = (1.0 / (cell->diam())) * Eigen::MatrixXd::Identity(n_local_face_vector_dofs, n_local_face_vector_dofs);
1261 for (
size_t i = 0;
i < n_local_face_vector_dofs; ++
i)
1263 for (
size_t j = 0;
j < n_local_face_vector_dofs; ++
j)
1268 for (
size_t k = 0;
k < n_local_highorder_vector_dofs; ++
k)
1279 Eigen::BiCGSTAB<Eigen::SparseMatrix<double>>
solver;
1308 for (
size_t k = 0;
k < dim;
k++)
1315 for (
size_t i = 0;
i < n_local_cell_scalar_dofs;
i++)
1330 std::vector<Eigen::VectorXd>
LTf(n_cells);
1331 std::vector<Eigen::VectorXd>
LTg(n_cells);
1332 std::vector<Eigen::MatrixXd>
DT(n_cells);
1334 std::vector<std::vector<Eigen::MatrixXd>>
Tplus_k(n_cells);
1335 std::vector<std::vector<Eigen::MatrixXd>>
Tminus_k(n_cells);
1337 std::cout <<
" Assembling local matrices\n";
1348 ElementQuad elquad(m_hho,
iT, std::max(3 * m_L, m_L + m_K + 1) + 1, std::max(3 * m_K, m_K + m_K + 1) + 1);
1350 Cell *cell = mesh_ptr->
cell(
iT);
1352 AT[
iT] = gradient_term(cell,
elquad);
1353 AT[
iT] = AT[
iT] + stabilisation_term(cell,
elquad);
1357 size_t n_local_vector_dofs = n_local_cell_vector_dofs + cell->n_faces() * n_local_face_vector_dofs;
1372 for (
size_t iT = 0;
iT < n_cells; ++
iT)
1381 size_t n_magnetic_dofs = n_total_cell_vector_dofs + n_total_face_vector_dofs + n_total_cell_scalar_dofs;
1382 size_t n_velocity_dofs = n_total_cell_vector_dofs + n_total_face_vector_dofs + n_total_cell_scalar_dofs;
1397 std::cout <<
" Solving scheme using Newton method\n";
1410 std::vector<Eigen::VectorXd>
local_RHS(n_cells);
1413 std::vector<Eigen::MatrixXd>
local_LTgl(n_cells);
1414 std::vector<Eigen::MatrixXd>
local_LTgg(n_cells);
1416 Eigen::VectorXd inv_LTll_rTl = Eigen::VectorXd::Zero(
n_implicit_dofs);
1423 Cell *cell = mesh_ptr->
cell(
iT);
1430 Eigen::VectorXd
uT =
SOL.restr(
iT);
1454 Eigen::MatrixXd
GMAT = A + 0.5 *
BMAT;
1456 Eigen::VectorXd G =
GMAT *
uT;
1457 G.segment(0, n_local_cell_vector_dofs) -=
LTf[
iT];
1485 local_LTll.block(0, 0, n_local_cell_vector_dofs, n_local_cell_vector_dofs) =
local_DG.block(0, 0, n_local_cell_vector_dofs, n_local_cell_vector_dofs);
1486 local_LTll.block(0, n_local_cell_vector_dofs, n_local_cell_vector_dofs, n_local_cell_scalar_dofs - 1) =
local_DG.block(0,
n_local_vector_dofs + 1, n_local_cell_vector_dofs, n_local_cell_scalar_dofs - 1);
1487 local_LTll.block(n_local_cell_vector_dofs, 0, n_local_cell_scalar_dofs - 1, n_local_cell_vector_dofs) =
local_DG.block(
n_local_vector_dofs + 1, 0, n_local_cell_scalar_dofs - 1, n_local_cell_vector_dofs);
1570 Eigen::PartialPivLU<Eigen::MatrixXd>
solver;
1580 inv_LTll_rTl.segment(
iT * n_local_cell_vector_dofs, n_local_cell_vector_dofs) =
local_inv_LTll_rTl.segment(0, n_local_cell_vector_dofs);
1581 inv_LTll_rTl.segment(n_total_cell_vector_dofs +
iT * (n_local_cell_scalar_dofs - 1), n_local_cell_scalar_dofs - 1) =
local_inv_LTll_rTl.segment(n_local_cell_vector_dofs, n_local_cell_scalar_dofs - 1);
1599 Eigen::VectorXd
rTg = Eigen::VectorXd::Zero(
n_unknowns + 2);
1601 for (
size_t iT = 0;
iT < n_cells; ++
iT)
1603 Cell *cell = mesh_ptr->
cell(
iT);
1619 size_t iF = cell->face(
iTF)->global_index();
1629 for (
size_t i = 0;
i < n_local_face_vector_dofs;
i++)
1631 for (
size_t j = 0;
j < n_local_cell_vector_dofs;
j++)
1643 for (
size_t j = 0;
j < n_local_cell_scalar_dofs - 1;
j++)
1653 size_t jF = cell->face(
jTF)->global_index();
1659 for (
size_t j = 0;
j < n_local_face_vector_dofs;
j++)
1694 triplets_LTgg.emplace_back(n_total_face_vector_dofs +
iT, n_total_face_vector_dofs +
iT, std::pow((cell->diam() /
double(m_K + 1)), m_K + 2));
1710 for (
size_t i = 0;
i < n_local_face_vector_dofs; ++
i)
1715 if ((m_u_bc ==
'D') || ((m_u_bc ==
'H') &&
i % dim == 0))
1724 if ((m_b_bc ==
'D') || ((m_b_bc ==
'H') &&
i % dim == 0))
1736 inv_LTll_LTlg.prune(0.0);
1744 Eigen::SparseMatrix<double>
condensed_SysMat = LTgg - LTgl * inv_LTll_LTlg;
1754 Eigen::VectorXd
RHS =
rTg - LTgl * inv_LTll_rTl;
1763 Eigen::VectorXd
deltaU = Eigen::VectorXd::Zero(n_total_dofs);
1765 deltaU.segment(0, n_total_cell_vector_dofs) =
implicit_terms.segment(0, n_total_cell_vector_dofs);
1766 deltaU.segment(n_total_cell_vector_dofs, n_total_face_vector_dofs) =
condensed_terms.segment(0, n_total_face_vector_dofs);
1771 for (
size_t iT = 0;
iT < n_cells; ++
iT)
1773 deltaU(n_total_cell_vector_dofs + n_total_face_vector_dofs +
iT * n_local_cell_scalar_dofs) =
condensed_terms(n_total_face_vector_dofs +
iT);
1776 deltaU.segment(n_total_cell_vector_dofs + n_total_face_vector_dofs +
iT * n_local_cell_scalar_dofs + 1, n_local_cell_scalar_dofs - 1) =
implicit_terms.segment(n_total_cell_vector_dofs +
iT * (n_local_cell_scalar_dofs - 1), n_local_cell_scalar_dofs - 1);
1797 for (
size_t i = 0;
i < n_local_face_scalar_dofs;
i++)
1813 size_t offset = n_total_cell_vector_dofs + n_total_face_vector_dofs + n_total_cell_scalar_dofs +
internal_vector_dofs +
ibF * n_local_face_vector_dofs;
1816 for (
size_t i = 0;
i < n_local_face_scalar_dofs;
i++)
1825 Eigen::VectorXd residual = Eigen::VectorXd::Zero(n_total_dofs);
1831 Cell *cell = mesh_ptr->
cell(
iT);
1838 Eigen::VectorXd
uT =
SOL.restr(
iT);
1861 Eigen::MatrixXd
GMAT = A + 0.5 *
BMAT;
1863 Eigen::VectorXd G =
GMAT *
uT;
1864 G.segment(0, n_local_cell_vector_dofs) -=
LTf[
iT];
1867 residual.segment(
iT * n_local_cell_vector_dofs, n_local_cell_vector_dofs) = G.head(n_local_cell_vector_dofs);
1870 size_t global_magnetic_offset = n_total_cell_vector_dofs + n_total_face_vector_dofs + n_total_cell_scalar_dofs;
1895 std::cout <<
" It. " <<
i <<
":";
1900 std::cout <<
"Failed to converge\n";
constexpr double tol
Definition BoundaryConditions.cpp:15
Definition elementquad.hpp:55
Definition hybridcore.hpp:174
This structure is a wrapper to allow a given code to select various linear solvers.
Definition linearsolver.hpp:106
Definition HHO_MHD.hpp:209
Class to describe a mesh.
Definition MeshND.hpp:17
boost::multi_array< T, 2 > BasisQuad
type for bases evaluated on quadrature nodes
Definition basis.hpp:61
std::function< T(const VectorRd &)> FType
type for function of point. T is the return type of the function
Definition basis.hpp:55
Eigen::VectorXd integrate(const FType< T > &f, const BasisQuad< T > &B, const QuadratureRule &qr, size_t n_rows=0)
Computes the vector of integrals (f, phi_i)
Definition basis.hpp:2626
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
size_t L
Definition HHO_DiffAdvecReac.hpp:46
size_t K
Definition HHO_DiffAdvecReac.hpp:46
Eigen::VectorXd lagrange_restr(size_t iT) const
Definition HHO_MHD.hpp:130
SolutionVector solve_with_static_cond(FType< VectorRd > f_source, FType< VectorRd > g_source, double visc, double diff, double tol, LinearSolver< Eigen::SparseMatrix< double > > &solver, bool threading=true)
Definition HHO_MHD.hpp:1327
MHDModel(HybridCore &, size_t, size_t, char, char)
Definition HHO_MHD.hpp:476
void set_values(Eigen::VectorXd values) const
Return the values as an Eigen vector.
Definition HHO_MHD.hpp:62
const size_t get_face_deg() const
Return the face degree.
Definition HHO_MHD.hpp:68
std::vector< double > compute_errors(SolutionVector interpolant, SolutionVector discrete, double visc, double diff)
Definition HHO_MHD.hpp:269
Eigen::VectorXd pressure_restr(size_t iT) const
Definition HHO_MHD.hpp:106
SolutionVector operator-(const SolutionVector &b) const
Overloads the subtraction: subtracts the coefficients.
Definition HHO_MHD.hpp:157
Eigen::VectorXd magnetic_restr(size_t iT) const
Definition HHO_MHD.hpp:113
Eigen::VectorXd lagrange_values() const
Definition HHO_MHD.hpp:86
Eigen::VectorXd pressure_values() const
Definition HHO_MHD.hpp:76
SolutionVector(Eigen::VectorXd values, const Mesh *mesh_ptr, const size_t cell_deg, const size_t face_deg)
Definition HHO_MHD.hpp:48
Eigen::VectorXd velocity_values() const
Definition HHO_MHD.hpp:70
Eigen::VectorXd magnetic_values() const
Definition HHO_MHD.hpp:81
SolutionVector operator+(const SolutionVector &b) const
Overloads the addition: adds the coefficients.
Definition HHO_MHD.hpp:150
const size_t get_cell_deg() const
Return the cell degree.
Definition HHO_MHD.hpp:65
double operator()(size_t index) const
Overloads the (): returns the corresponding coefficient.
Definition HHO_MHD.hpp:164
Eigen::VectorXd velocity_restr(size_t iT) const
Definition HHO_MHD.hpp:91
Eigen::VectorXd asVectorXd() const
Return the values as an Eigen vector.
Definition HHO_MHD.hpp:60
SolutionVector global_interpolant(FType< VectorRd > velocity, FType< double > pressure, FType< VectorRd > magnetic)
Definition HHO_MHD.hpp:447
Eigen::VectorXd restr(size_t iT) const
Definition HHO_MHD.hpp:137
const size_t DimPoly< Face >(const int m)
Compute the size of the basis of 2-variate polynomials up to degree m.
Definition hybridcore.hpp:68
const Mesh * get_mesh() const
Returns a pointer to the mesh.
Definition hybridcore.hpp:198
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
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::size_t n_b_faces() const
number of boundary faces in the mesh.
Definition MeshND.hpp:77
std::size_t n_i_faces() const
number of internal faces in the mesh.
Definition MeshND.hpp:82
std::vector< QuadratureNode > QuadratureRule
Definition quadraturerule.hpp:61
Definition ddr-magnetostatics.hpp:41
MeshND::VectorRd< 2 > VectorRd
Definition Mesh2D.hpp:14
Definition HHO_MHD.hpp:42