13#ifndef _HMM_STEFANPME_TRANSIENT_HPP
14#define _HMM_STEFANPME_TRANSIENT_HPP
20#include <boost/timer/timer.hpp>
23#include <Eigen/Sparse>
72 std::string solver_type,
73 std::ostream & output = std::cout
98 return double(_assembly_time) * pow(10, -9);
102 return double(_solving_time) * pow(10, -9);
106 return double(_itime[
idx]) * pow(10, -9);
110 return _solving_error;
124 Eigen::MatrixXd diffusion_operator(
const size_t iT)
const;
127 Eigen::VectorXd load_operator(
const double tps,
const size_t iT)
const;
131 Eigen::VectorXd residual_scheme(
const double dt,
const UVector&
Xh)
const;
140 const double _weight;
141 const std::string solver_type;
142 std::ostream & m_output;
145 std::vector<Eigen::MatrixXd> DiffT;
146 std::vector<Eigen::MatrixXd> MassT;
147 std::vector<Eigen::VectorXd> RightHandSideT;
150 size_t _assembly_time;
151 size_t _solving_time;
152 double _solving_error;
153 mutable std::vector<size_t> _itime = std::vector<size_t>(10, 0);
163 exact_solution(exact_solution),
164 grad_exact_solution(grad_exact_solution),
167 solver_type(solver_type),
175 RightHandSideT.resize(mesh->
n_cells());
180 DiffT[
iT] = diffusion_operator(
iT);
182 MassT[
iT](0,0) = (1-_weight) *
measT;
190 boost::timer::cpu_timer
timer;
194 size_t n_cell_dofs = mesh->n_cells();
197 for (
size_t iT = 0;
iT < mesh->n_cells();
iT++) {
198 RightHandSideT[
iT] =
dt * load_operator(
tps,
iT) + MassT[
iT]*
Xn.restr(
iT);
202 constexpr double tol = 1
e-8;
203 constexpr size_t maxiter = 400;
212 for (
size_t ibF = 0;
ibF < mesh->n_b_edges();
ibF++){
213 Edge* edge = mesh->b_edge(
ibF);
214 if (m_BC.
type(*edge)==
"dir"){
215 size_t iF = edge->global_index();
225 DirBC(n_cell_dofs +
iF) /= mesh->b_edge(
ibF)->measure();
229 Xhprev.asVectorXd().tail(mesh->n_b_edges()) =
DirBC.tail(mesh->n_b_edges());
234 std::vector<double> residual(
maxiter, 1.0);
248 Eigen::VectorXd ScRHS = Eigen::VectorXd::Zero(n_cell_dofs);
251 for (
size_t iT = 0;
iT < mesh->n_cells();
iT++) {
252 Cell* cell = mesh->cell(
iT);
266 Eigen::MatrixXd
ATT =
MatT.topLeftCorner(1, 1);
271 Eigen::PartialPivLU<Eigen::MatrixXd>
invATT;
280 Eigen::VectorXd
bF = Eigen::VectorXd::Zero(
n_edgesT);
288 for (
size_t i = 0;
i < 1;
i++){
291 size_t jGlobal = cell->edge(
j)->global_index();
298 size_t iGlobal = cell->edge(
i)->global_index();
300 size_t jGlobal = cell->edge(
j)->global_index();
322 Eigen::BiCGSTAB<Eigen::SparseMatrix<double> >
solver;
326 Eigen::VectorXd
dX = Eigen::VectorXd::Zero(n_cell_dofs +
n_edges_dofs);
348 Xhprev.asVectorXd() =
Xh.asVectorXd();
353 m_output <<
" ...Iteration: " <<
iter <<
"; residual = " << residual[
iter] <<
"; relax = "<<
relax <<
"\n";
372 Eigen::VectorXd
ZetaY;
377 }
else if (type ==
"der" || type ==
"nlin"){
378 ZetaY = Eigen::VectorXd::Ones(
Y.size());
380 m_output <<
"type unknown in apply_nonlinearity: " << type <<
"\n";
386 size_t n_cell_dofs = 0;
396 for (
size_t i = 0;
i < n_cell_dofs;
i++){
399 }
else if (_weight == 1){
425Eigen::MatrixXd HMM_StefanPME_Transient::diffusion_operator(
const size_t iT)
const {
428 size_t dim = mesh->
dim();
429 Cell*
T = mesh->cell(
iT);
430 double mT =
T->measure();
437 Eigen::Vector2d
xT =
T->center_mass();
443 Edge* E =
T->edge(
iE);
444 double mE = E->measure();
451 Edge* E =
T->edge(
iE);
452 Eigen::Vector2d
xE = E->center_mass();
453 Eigen::Vector2d
nTE =
T->edge_normal(
iE);
454 double mE = E->measure();
480Eigen::VectorXd HMM_StefanPME_Transient::load_operator(
const double tps,
const size_t iT)
const {
489 m_output <<
"Called load_operator without creating MassT[iT]\n";
492 Eigen::VectorXd
fvec = Eigen::VectorXd::Zero(1 +
n_edgesT);
496 node =
T->center_mass();
498 node =
T->edge(
i-1)->center_mass();
511 if (
T->is_boundary()){
512 for (
size_t ilF = 0;
ilF <
T->n_edges();
ilF++) {
514 if (m_BC.
type(*edge)==
"neu"){
515 if (edge->is_boundary()){
516 const auto&
nTF =
T->edge_normal(
ilF);
519 return zeta(exact_solution(
tps,
p),
"der") *
nTF.dot(kappa(
p.x(),
p.y(),
T) * grad_exact_solution(
tps,
p,
T));
536Eigen::VectorXd HMM_StefanPME_Transient::residual_scheme(
const double dt,
const UVector&
Xh)
const{
542 size_t n_cell_dofs = mesh->
n_cells();
547 Eigen::VectorXd
XT =
Xh.restr(
iT);
553 size_t iE =
T->edge(
ilE)->global_index();
572 for (
size_t iT = 0;
iT < mesh-> n_cells();
iT++) {
573 Eigen::VectorXd
XTF =
Xh.restr(
iT);
574 value +=
XTF.transpose() * MassT[
iT] *
XTF;
585 for (
size_t iT = 0;
iT < mesh-> n_cells();
iT++) {
586 Eigen::VectorXd
XTF =
Xh.restr(
iT);
593 return std::pow(value, 1.0/
p);
600 for (
size_t iT = 0;
iT < mesh-> n_cells();
iT++) {
601 Eigen::VectorXd
XTF =
Xh.restr(
iT);
602 value +=
XTF.transpose() * DiffT[
iT] *
XTF;
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 size_t n_dir_edges() const
Returns the number of Dirichlet edges.
Definition BoundaryConditions.hpp:70
The vector Xh manipulated in the resolution has mixed components, corresponding either to the unknown...
Definition HMM_StefanPME_transient.hpp:53
Definition hybridcore.hpp:179
Definition hybridcore.hpp:82
std::function< double(double, std::string)> nonlinearity_function_type
type for nonlinear function
Definition TestCaseNonLinearity.hpp:48
for i
Definition convergence_analysis.m:48
dt
Definition convergence_analysis.m:120
for j
Definition convergence_analysis.m:19
Eigen::Vector2d VectorRd
Definition basis.hpp:55
std::function< VectorRd(const double &, const VectorRd &, const Cell *)> grad_function_type
type for gradient
Definition HMM_StefanPME_transient.hpp:59
std::function< double(const double &, const VectorRd &)> solution_function_type
type for solution
Definition HMM_StefanPME_transient.hpp:57
Eigen::MatrixXd get_MassT(size_t iT) const
Mass matrix in cell iT.
Definition HMM_StefanPME_transient.hpp:117
std::function< double(const double &, const VectorRd &, const Cell *)> source_function_type
type for source
Definition HMM_StefanPME_transient.hpp:58
HMM_StefanPME_Transient(HybridCore &hmm, tensor_function_type kappa, source_function_type source, BoundaryConditions BC, solution_function_type exact_solution, grad_function_type grad_exact_solution, TestCaseNonLinearity::nonlinearity_function_type zeta, double weight, std::string solver_type, std::ostream &output=std::cout)
Constructor of the class.
Definition HMM_StefanPME_transient.hpp:158
double get_assembly_time() const
cpu time to assemble the scheme
Definition HMM_StefanPME_transient.hpp:97
double get_solving_error() const
residual after solving the scheme
Definition HMM_StefanPME_transient.hpp:109
double get_itime(size_t idx) const
various intermediate assembly times
Definition HMM_StefanPME_transient.hpp:105
UVector iterate(const double tps, const double dt, const UVector &Xn)
Execute one time iteration.
Definition HMM_StefanPME_transient.hpp:188
double get_solving_time() const
cpu time to solve the scheme
Definition HMM_StefanPME_transient.hpp:101
std::function< Eigen::Matrix2d(const double, const double, const Cell *)> tensor_function_type
type for diffusion tensor (does not depend on time)
Definition HMM_StefanPME_transient.hpp:60
double EnergyNorm(const UVector &Xh) const
Discrete energy norm (associated to the diffusion operator)
Definition HMM_StefanPME_transient.hpp:596
double Lp_MassLumped(const UVector &Xh, double p) const
Mass-lumped Lp norm of a function given by a vector.
Definition HMM_StefanPME_transient.hpp:581
double L2_MassLumped(const UVector &Xh) const
Mass-lumped L2 norm of a function given by a vector.
Definition HMM_StefanPME_transient.hpp:568
size_t get_nb_newton() const
number of Newton iterations
Definition HMM_StefanPME_transient.hpp:113
Eigen::VectorXd apply_nonlinearity(const Eigen::VectorXd &Y, const std::string type) const
Compute non-linearity on vector (depends if weight=0, weight=1 or weight\in (0,1) )
Definition HMM_StefanPME_transient.hpp:365
const size_t DimPoly< Cell >(const int m)
Compute the size of the basis of 2-variate polynomials up to degree m.
Definition hybridcore.hpp:63
Eigen::VectorXd & asVectorXd() const
Return the values as an Eigen vector.
Definition hybridcore.hpp:92
const Mesh * get_mesh() const
Returns a pointer to the mesh.
Definition hybridcore.hpp:201
double measure() const
Return the Lebesgue measure of the Polytope.
Definition Polytope2D.hpp:77
Polytope< DIMENSION > Cell
Definition Polytope2D.hpp:152
std::size_t dim() const
dimension of the mesh
Definition Mesh2D.hpp:58
Cell * cell(std::size_t index) const
get a constant pointer to a cell using its global index
Definition Mesh2D.hpp:178
size_t n_edges() const
Return the number of edges of the Polytope.
Definition Polytope2D.hpp:89
Polytope< 1 > Edge
A Face is a Polytope with object_dim = DIMENSION - 1.
Definition Polytope2D.hpp:148
std::size_t n_cells() const
number of cells in the mesh.
Definition Mesh2D.hpp:63
std::size_t n_edges() const
number of edges in the mesh.
Definition Mesh2D.hpp:61
std::vector< QuadratureNode > QuadratureRule
Definition quadraturerule.hpp:55
QuadratureRule generate_quadrature_rule(const Cell &T, const int doe, const bool force_split)
Generate quadrature rule on mesh element.
Definition quadraturerule.cpp:10
depending on the Matrix Market format indicated by or array(dense array storage). The data will be duplicated % as appropriate if symmetry is indicated in the header. % % Optionally
if(strcmp(field, 'real')) % real valued entries T
Definition mmread.m:93
Definition mhd-solutions.hpp:9
Description of one node and one weight from a quadrature rule.
Definition quadraturerule.hpp:41