13#ifndef _HMM_STOCHTRANS_STEFANPME_HPP
14#define _HMM_STOCHTRANS_STEFANPME_HPP
20#include <boost/timer/timer.hpp>
23#include <Eigen/Sparse>
25#include <boost/math/constants/constants.hpp>
36#include <Eigen/PardisoSupport>
77static const double PI = boost::math::constants::pi<double>();
79static std::function<
double(
const size_t &,
const size_t &)>
mui = [](
const size_t &
k,
const size_t &
l)->
double
81 return 1./(std::pow(
k, 2) + std::pow(
l, 2));
99 return -
mui(
k,
l) * (std::pow(
k, 2) + std::pow(
l, 2)) * std::pow(
PI,2) * sin(
k *
PI *
p.x()) * sin(
l *
PI *
p.y());
104static inline double StDev(
const Eigen::VectorXd &
v){
105 return sqrt( (
v.array()*
v.array()).mean() - std::pow(
v.mean(), 2) );
142 std::string solver_type,
143 std::ostream & output = std::cout
157 std::pair<UVector, size_t>
iterate(
192 Eigen::VectorXd
apply_nonlinearity_eW(
const std::string type,
const Eigen::VectorXd &
Y,
const Eigen::VectorXd &
I_W)
const;
209 return double(_assembly_time) * pow(10, -9);
214 return double(_solution_time) * pow(10, -9);
219 return double(_itime[
idx]) * pow(10, -9);
224 return _solving_error;
234 Eigen::MatrixXd diffusion_operator(
const size_t iT)
const;
251 const double _weight;
252 const std::string solver_type;
253 std::ostream & m_output;
256 std::random_device m_rd{};
257 std::mt19937 m_gen{m_rd()};
260 std::vector<Eigen::MatrixXd> DiffT;
261 std::vector<Eigen::MatrixXd> MassT;
264 size_t _assembly_time;
265 size_t _solution_time;
266 double _solving_error;
267 std::vector<double> _itime = std::vector<double>(10, 0.);
272StochStefanPME::StochStefanPME(
HybridCore &hmm,
tensor_function_type kappa,
TestCaseNonLinearity::nonlinearity_function_type zeta,
BoundaryConditions BC,
solution_function_type exact_solution,
grad_function_type grad_exact_solution,
solution_function_type time_der_exact_solution,
lapl_function_type minus_Lapl_exact_solution,
double weight, std::string solver_type, std::ostream & output)
277 exact_solution(exact_solution),
278 grad_exact_solution(grad_exact_solution),
279 time_der_exact_solution(time_der_exact_solution),
280 minus_Lapl_exact_solution(minus_Lapl_exact_solution),
282 solver_type(solver_type),
293 DiffT[
iT] = diffusion_operator(
iT);
295 MassT[
iT](0,0) = (1-_weight) *
measT;
322 double val = time_der_exact_solution(
t,
p)
330 -
exp_W * minus_Lapl_exact_solution(
t,
p, cell)
351 boost::timer::cpu_timer
timer;
355 size_t n_cell_dofs = mesh->n_cells();
358 std::vector<Eigen::VectorXd>
RHS_nl;
359 for (
size_t iT = 0;
iT < mesh->n_cells();
iT++) {
364 constexpr double tol = 1
e-10;
365 constexpr size_t maxiter = 400;
374 for (
size_t ibF = 0;
ibF < mesh->n_b_edges();
ibF++){
375 Edge* edge = mesh->b_edge(
ibF);
376 if (m_BC.
type(*edge)==
"dir"){
377 size_t iF = edge->global_index();
387 DirBC(n_cell_dofs +
iF) /= mesh->b_edge(
ibF)->measure();
391 Xhprev.asVectorXd().tail(mesh->n_b_edges()) =
DirBC.tail(mesh->n_b_edges());
395 std::vector<double> residual(
maxiter, 1.0);
410 Eigen::VectorXd ScRHS = Eigen::VectorXd::Zero(n_cell_dofs);
413 for (
size_t iT = 0;
iT < mesh->n_cells();
iT++) {
414 Cell*
T = mesh->cell(
iT);
418 Eigen::VectorXd
WT =
Ih_W.restr(
iT);
419 Eigen::MatrixXd
exp_minus_WT = exp(-
WT.array()).matrix().asDiagonal();
427 Eigen::MatrixXd
ReacT = MassT[
iT];
434 Eigen::MatrixXd
ATT =
MatT.topLeftCorner(1, 1);
439 Eigen::PartialPivLU<Eigen::MatrixXd>
invATT;
448 Eigen::VectorXd
bF = Eigen::VectorXd::Zero(
n_edgesT);
455 for (
size_t i = 0;
i < 1;
i++){
458 size_t jGlobal =
T->edge(
j)->global_index();
465 size_t iGlobal =
T->edge(
i)->global_index();
467 size_t jGlobal =
T->edge(
j)->global_index();
494 if(solver_type ==
"pardiso"){
496 Eigen::PardisoLU<Eigen::SparseMatrix<double>>
solver;
498 if (
solver.info() != Eigen::Success) {
499 std::cerr <<
"[main] ERROR: Could not factorize matrix" << std::endl;
502 if (
solver.info() != Eigen::Success) {
503 std::cerr <<
"[main] ERROR: Could not solve linear system" << std::endl;
507 Eigen::BiCGSTAB<Eigen::SparseMatrix<double>, Eigen::IncompleteLUT<double> >
solver;
509 if (
solver.info() != Eigen::Success) {
510 std::cerr <<
"[main] ERROR: Could not factorize matrix" << std::endl;
514 if (
solver.info() != Eigen::Success) {
515 std::cerr <<
"[main] ERROR: Could not solve direct system" << std::endl;
521 Eigen::VectorXd
dX = Eigen::VectorXd::Zero(n_cell_dofs +
n_edges_dofs);
543 Xhprev.asVectorXd() =
Xh.asVectorXd();
558 return std::make_pair(
Xh,
iter);
570 if(
verbose) { std::cout <<
"[main] Wiener process = zero" << std::endl; }
571 W = [&](
const VectorRd &
p)->
double {
return 0.; };
578 if(
verbose) { std::cout <<
"[main] Wiener process = x + 2y" << std::endl; }
579 W = [&](
const VectorRd &
p)->
double {
return p.x() + 2*
p.y(); };
586 if(
verbose) { std::cout <<
"[main] Wiener process = sin(pi x)sin(pi y)" << std::endl; }
598 if(
verbose) { std::cout <<
"[main] Wiener process = cos(t) * sin(pi x)sin(pi y)" << std::endl; }
610 std::cout <<
"[main] Wiener process unknown" << std::endl;
624 std::normal_distribution<double>
Nd{0,
sqrt(
dt)};
672 I_W.asVectorXd() = Eigen::VectorXd::Zero(
I_W.asVectorXd().size());
693 Eigen::VectorXd
ZetaY;
698 }
else if (type ==
"der"){
699 ZetaY = Eigen::VectorXd::Ones(
Y.size());
701 m_output <<
"type unknown in apply_nonlinearity: " << type <<
"\n";
707 size_t n_cell_dofs = 0;
721 }
else if (_weight == 1){
750Eigen::MatrixXd StochStefanPME::diffusion_operator(
const size_t iT)
const {
753 size_t dim = mesh->
dim();
754 Cell*
T = mesh->cell(
iT);
755 double mT =
T->measure();
762 Eigen::Vector2d
xT =
T->center_mass();
768 Edge* E =
T->edge(
iE);
769 double mE = E->measure();
776 Edge* E =
T->edge(
iE);
777 Eigen::Vector2d
xE = E->center_mass();
778 Eigen::Vector2d
nTE =
T->edge_normal(
iE);
779 double mE = E->measure();
801Eigen::VectorXd StochStefanPME::load_operator(
const double tps,
const size_t iT,
const source_function_type & source)
const {
810 m_output <<
"Called load_operator without creating MassT[iT]\n";
813 Eigen::VectorXd
fvec = Eigen::VectorXd::Zero(1 +
n_edgesT);
817 node =
T->center_mass();
819 node =
T->edge(
i-1)->center_mass();
832 if (
T->is_boundary()){
833 for (
size_t ilF = 0;
ilF <
T->n_edges();
ilF++) {
835 if (m_BC.
type(*edge)==
"neu"){
836 if (edge->is_boundary()){
837 const auto&
nTF =
T->edge_normal(
ilF);
840 return zeta(exact_solution(
tps,
p),
"der") *
nTF.dot(kappa(
p,
T) * grad_exact_solution(
tps,
p,
T));
857Eigen::VectorXd StochStefanPME::residual_scheme(
const double dt,
const UVector&
Xh,
const std::vector<Eigen::VectorXd> &
RHS_nl,
const UVector&
Ih_W,
const ReactionType &
mu_squared)
const{
863 size_t n_cell_dofs = mesh->
n_cells();
869 Eigen::VectorXd
WT =
Ih_W.restr(
iT);
870 Eigen::MatrixXd
exp_minus_WT = exp(-
WT.array()).matrix().asDiagonal();
873 Eigen::VectorXd
XT =
Xh.restr(
iT);
877 Eigen::MatrixXd
ReacT = MassT[
iT];
886 size_t iE =
T->edge(
ilE)->global_index();
905 for (
size_t iT = 0;
iT < mesh-> n_cells();
iT++) {
906 Eigen::VectorXd
XTF =
Xh.restr(
iT);
907 value +=
XTF.transpose() * MassT[
iT] *
XTF;
918 for (
size_t iT = 0;
iT < mesh-> n_cells();
iT++) {
919 Eigen::VectorXd
XTF =
Xh.restr(
iT);
926 return std::pow(value, 1.0/
p);
933 for (
size_t iT = 0;
iT < mesh-> n_cells();
iT++) {
934 Eigen::VectorXd
XTF =
Xh.restr(
iT);
935 value +=
XTF.transpose() * DiffT[
iT] *
XTF;
945 for (
size_t iT = 0;
iT < mesh-> n_cells();
iT++) {
946 value += (MassT[
iT] *
Xh.restr(
iT)).
sum();
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
Definition hybridcore.hpp:179
The vector Xh manipulated in the resolution has mixed components, corresponding either to the unknown...
Definition HMM_StochTrans_StefanPME.hpp:115
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
end
Definition convergence_analysis.m:110
Create grid points x
Definition generate_cartesian_mesh.m:22
static const double PI
Definition bgg-klplate.hpp:214
Eigen::Vector2d VectorRd
Definition basis.hpp:55
Eigen::MatrixXd get_MassT(size_t iT) const
Mass matrix in cell iT.
Definition HMM_StochTrans_StefanPME.hpp:228
std::vector< std::vector< T > > DoubleVector
Definition HMM_StochTrans_StefanPME.hpp:74
SpatialFunctionType< double > ReactionType
Type for reaction term mu^2.
Definition HMM_StochTrans_StefanPME.hpp:129
std::function< T(const size_t &, const size_t &, const VectorRd &)> EigFunctionType
Type for "eigenfunctions" e_i, depending on two indices k,l.
Definition HMM_StochTrans_StefanPME.hpp:71
double get_itime(size_t idx) const
various intermediate assembly times
Definition HMM_StochTrans_StefanPME.hpp:218
double Integral(const UVector &Xh) const
Integral of a function given by a vector.
Definition HMM_StochTrans_StefanPME.hpp:941
std::function< T(const double &, const VectorRd &)> TemporalSpatialFunctionType
Generic type for function that depends on space and time.
Definition HMM_StochTrans_StefanPME.hpp:63
double EnergyNorm(const UVector &Xh) const
Discrete energy norm (associated to the diffusion operator)
Definition HMM_StochTrans_StefanPME.hpp:929
double get_solving_error() const
residual after solving the scheme
Definition HMM_StochTrans_StefanPME.hpp:223
static std::function< double(const size_t &, const size_t &)> mui
Definition HMM_StochTrans_StefanPME.hpp:79
std::pair< UVector, size_t > iterate(const double tps, const double dt, const UVector &Xn, const UVector &Ih_W, const WienerType &W, const ReactionType &mu_squared, const source_function_type &source)
Execute one time iteration: return the calculated vector, and the number of Newton iterations.
Definition HMM_StochTrans_StefanPME.hpp:349
void SimulateWienerProcess(const double &dt, DoubleVector< double > &Wtime, WienerType &W, const DoubleVector< Eigen::VectorXd > &Ih_eigs, UVector &I_W, GradWienerType &grad_W, WienerType &Delta_exp_W, ReactionType &mu_squared)
Set the Wiener process, random case.
Definition HMM_StochTrans_StefanPME.hpp:619
PiecewiseTemporalSpatialFunctionType< double > lapl_function_type
type for laplacian
Definition HMM_StochTrans_StefanPME.hpp:123
std::function< T(const VectorRd &, const Cell *)> PiecewiseSpatialFunctionType
Generic type for function that depends on space, with formula changing from one cell to the next.
Definition HMM_StochTrans_StefanPME.hpp:60
StochStefanPME(HybridCore &hmm, tensor_function_type kappa, TestCaseNonLinearity::nonlinearity_function_type zeta, BoundaryConditions BC, solution_function_type exact_solution, grad_function_type grad_exact_solution, solution_function_type time_der_exact_solution, lapl_function_type minus_Lapl_exact_solution, double weight, std::string solver_type, std::ostream &output=std::cout)
Constructor of the class.
Definition HMM_StochTrans_StefanPME.hpp:272
std::function< T(const double &, const VectorRd &, const Cell *)> PiecewiseTemporalSpatialFunctionType
Generic type for function that depends on space and time, with formula changing from one cell to the ...
Definition HMM_StochTrans_StefanPME.hpp:66
Eigen::VectorXd apply_nonlinearity_eW(const std::string type, const Eigen::VectorXd &Y, const Eigen::VectorXd &I_W) const
Compute non-linearity and e^W on vector Y (depends if weight=0, weight=1 or weight\in (0,...
Definition HMM_StochTrans_StefanPME.hpp:686
double L2_MassLumped(const UVector &Xh) const
Mass-lumped L2 norm of a function given by a vector.
Definition HMM_StochTrans_StefanPME.hpp:901
double get_solution_time() const
cpu time to solve the linear systems
Definition HMM_StochTrans_StefanPME.hpp:213
static SpatialFunctionType< double > zero_scalar_function
Zero spatial function.
Definition HMM_StochTrans_StefanPME.hpp:68
std::function< T(const VectorRd &)> SpatialFunctionType
Generic type for function that only depends on spatial coordinate.
Definition HMM_StochTrans_StefanPME.hpp:57
PiecewiseSpatialFunctionType< double > source_function_type
type for source (at a given fixed time)
Definition HMM_StochTrans_StefanPME.hpp:121
static double StDev(const Eigen::VectorXd &v)
Definition HMM_StochTrans_StefanPME.hpp:104
PiecewiseSpatialFunctionType< Eigen::Matrix2d > tensor_function_type
type for diffusion tensor (does not depend on time)
Definition HMM_StochTrans_StefanPME.hpp:124
void SetWienerProcess(const int &caseW, const double &t, WienerType &W, UVector &I_W, GradWienerType &grad_W, WienerType &Delta_exp_W, ReactionType &mu_squared, bool verbose=false)
Set the Wiener process, deterministic case.
Definition HMM_StochTrans_StefanPME.hpp:566
static EigFunctionType< double > Delta_mui_ei
Definition HMM_StochTrans_StefanPME.hpp:97
TemporalSpatialFunctionType< double > solution_function_type
type for solution
Definition HMM_StochTrans_StefanPME.hpp:120
double get_assembly_time() const
cpu time to assemble the scheme
Definition HMM_StochTrans_StefanPME.hpp:208
SpatialFunctionType< VectorRd > GradWienerType
type for gradient of Wiener process
Definition HMM_StochTrans_StefanPME.hpp:128
static EigFunctionType< VectorRd > grad_mui_ei
Definition HMM_StochTrans_StefanPME.hpp:89
PiecewiseTemporalSpatialFunctionType< VectorRd > grad_function_type
type for gradient
Definition HMM_StochTrans_StefanPME.hpp:122
SpatialFunctionType< double > WienerType
type for the Wiener process at a fixed time (only variation in space)
Definition HMM_StochTrans_StefanPME.hpp:127
static EigFunctionType< double > mui_ei
Definition HMM_StochTrans_StefanPME.hpp:84
double Lp_MassLumped(const UVector &Xh, double p) const
Mass-lumped Lp norm of a function given by a vector.
Definition HMM_StochTrans_StefanPME.hpp:914
StochStefanPME::source_function_type compute_source(const bool &use_exact_source, const double &t, const WienerType &W, const GradWienerType &grad_W, const WienerType &Delta_exp_W, const ReactionType &mu_squared)
Compute the source to zero or the exact one based on the selected solution and Wiener process.
Definition HMM_StochTrans_StefanPME.hpp:304
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
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 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
static auto v
Definition ddrcore-test.hpp:32
Description of one node and one weight from a quadrature rule.
Definition quadraturerule.hpp:41