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));
86 return mui(k,l) * sin(k *
PI * p.x()) * sin(l *
PI * p.y());
92 k *
PI * cos(k *
PI * p.x()) * sin(l *
PI * p.y()),
93 l *
PI * sin(k *
PI * p.x()) * cos(l *
PI * p.y())
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
148 const bool & use_exact_source,
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;
237 Eigen::VectorXd load_operator(
const double tps,
const size_t iT,
const source_function_type & source)
const;
241 Eigen::VectorXd residual_scheme(
const double dt,
const UVector& Xh,
const std::vector<Eigen::VectorXd> & RHS_nl,
const UVector& Ih_W,
const ReactionType & mu_squared)
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),
289 for (
size_t iT = 0; iT < mesh->
n_cells(); iT++) {
291 size_t n_local_dofs = 1 + n_edgesT;
293 DiffT[iT] = diffusion_operator(iT);
294 MassT[iT] = Eigen::MatrixXd::Zero(n_local_dofs, n_local_dofs);
295 MassT[iT](0,0) = (1-_weight) * measT;
296 MassT[iT].bottomRightCorner(n_edgesT, n_edgesT) = _weight * (measT / n_edgesT) * Eigen::MatrixXd::Identity(n_edgesT, n_edgesT);
305 const bool & use_exact_source,
315 if (use_exact_source){
317 source_term = [&](
const VectorRd & p,
const Cell* cell)->
double {
318 double exp_W = exp(W(p));
319 double exp_minus_W = 1./exp_W;
320 VectorRd grad_exp_W = exp(W(p)) * grad_W(p);
322 double val = time_der_exact_solution(t, p)
323 - exp_minus_W * zeta(exp_W * exact_solution(t, p),
"hess") *
325 grad_exp_W * exact_solution(t, p) + exp_W * grad_exact_solution(t, p, cell)
327 - exp_minus_W * zeta(exp_W * exact_solution(t, p),
"der") *
329 Delta_exp_W(p) * exact_solution(t, p) + 2 * grad_exp_W.dot(grad_exact_solution(t,p,cell))
330 - exp_W * minus_Lapl_exact_solution(t, p, cell)
332 + 0.5 * mu_squared(p) * exact_solution(t, p);
338 source_term = [&](
const VectorRd & p,
const Cell* cell)->
double {
return 0.; };
351 boost::timer::cpu_timer timer;
352 boost::timer::cpu_timer timerint;
354 size_t n_edges_dofs = mesh->
n_edges();
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++) {
360 RHS_nl.push_back(dt * load_operator(tps, iT, source) + MassT[iT]*Xn.
restr(iT));
364 constexpr double tol = 1e-10;
365 constexpr size_t maxiter = 400;
373 Eigen::VectorXd DirBC = Eigen::VectorXd::Zero(n_cell_dofs + n_edges_dofs);
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();
381 DirBC(n_cell_dofs + iF) += quadrule.w * zeta(exp(W(quadrule.vector())) * exact_solution(tps, quadrule.vector()),
"fct");
383 DirBC(n_cell_dofs + iF) += quadrule.w * exact_solution(tps, quadrule.vector());
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());
394 Eigen::VectorXd RES = residual_scheme(dt, Xhprev, RHS_nl, Ih_W, mu_squared);
395 std::vector<double> residual(maxiter, 1.0);
396 residual[iter] = RES.norm();
398 while ( (iter==0) || ( (iter < maxiter) && (residual[iter] > tol) ) ){
403 Eigen::SparseMatrix<double> GlobMat(n_edges_dofs, n_edges_dofs);
404 std::vector<Eigen::Triplet<double>> triplets_GlobMat;
405 Eigen::VectorXd GlobRHS = RES.tail(n_edges_dofs);
408 Eigen::SparseMatrix<double> ScMat(n_cell_dofs, n_edges_dofs);
409 std::vector<Eigen::Triplet<double>> triplets_ScMat;
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);
415 size_t n_edgesT =
T->n_edges();
418 Eigen::VectorXd WT = Ih_W.
restr(iT);
419 Eigen::MatrixXd exp_minus_WT = exp(-WT.array()).matrix().asDiagonal();
422 Eigen::VectorXd XTprev = Xhprev.
restr(iT);
424 Eigen::MatrixXd MatZetaprime_expWT_XTprev = Zetaprime_expWT_XTprev.asDiagonal();
427 Eigen::MatrixXd ReacT = MassT[iT];
428 ReacT(0,0) *= 0.5 * mu_squared(
T->center_mass());
429 for (
size_t i=0;
i<n_edgesT;
i++){
430 ReacT(
i+1,
i+1) *= 0.5 * mu_squared(
T->edge(
i)->center_mass());
433 Eigen::MatrixXd MatT = dt * exp_minus_WT * DiffT[iT] * MatZetaprime_expWT_XTprev + MassT[iT] + dt * ReacT;
434 Eigen::MatrixXd ATT = MatT.topLeftCorner(1, 1);
435 Eigen::MatrixXd ATF = MatT.topRightCorner(1, n_edgesT);
436 Eigen::MatrixXd AFT = MatT.bottomLeftCorner(n_edgesT, 1);
437 Eigen::MatrixXd AFF = MatT.bottomRightCorner(n_edgesT, n_edgesT);
439 Eigen::PartialPivLU<Eigen::MatrixXd> invATT;
442 Eigen::MatrixXd invATT_ATF = invATT.solve(ATF);
443 Eigen::VectorXd RES_cell = RES.segment(iT, 1);
444 Eigen::VectorXd invATT_RES_cell = invATT.solve(RES_cell);
447 Eigen::MatrixXd MatF = Eigen::MatrixXd::Zero(n_edgesT, n_edgesT);
448 Eigen::VectorXd bF = Eigen::VectorXd::Zero(n_edgesT);
449 MatF = AFF - AFT * invATT_ATF;
450 bF = - AFT * invATT_RES_cell;
453 ScRHS.segment(iT, 1) = invATT_RES_cell;
455 for (
size_t i = 0;
i < 1;
i++){
456 size_t iGlobal = iT +
i;
457 for (
size_t j = 0;
j < n_edgesT;
j++){
458 size_t jGlobal =
T->edge(
j)->global_index();
459 triplets_ScMat.emplace_back(iGlobal, jGlobal, invATT_ATF(
i,
j));
464 for (
size_t i = 0;
i < n_edgesT;
i++){
465 size_t iGlobal =
T->edge(
i)->global_index();
466 for (
size_t j = 0;
j < n_edgesT;
j++){
467 size_t jGlobal =
T->edge(
j)->global_index();
468 triplets_GlobMat.emplace_back(iGlobal, jGlobal, MatF(
i,
j));
470 GlobRHS(iGlobal) += bF(
i);
476 GlobMat.setFromTriplets(std::begin(triplets_GlobMat), std::end(triplets_GlobMat));
477 ScMat.setFromTriplets(std::begin(triplets_ScMat), std::end(triplets_ScMat));
483 size_t n_edge_unknowns = mesh->n_edges() - m_BC.
n_dir_edges();
484 Eigen::SparseMatrix<double>
A = GlobMat.topLeftCorner(n_edge_unknowns, n_edge_unknowns);
486 Eigen::VectorXd B = GlobRHS.head(n_edge_unknowns);
489 _assembly_time += double(timerint.elapsed().wall);
493 Eigen::VectorXd dX_edge_unknowns;
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;
501 dX_edge_unknowns = solver.solve(B);
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;
513 dX_edge_unknowns = solver.solve(B);
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);
522 dX.segment(n_cell_dofs, n_edge_unknowns) = dX_edge_unknowns;
523 dX.head(n_cell_dofs) = ScRHS - ScMat * dX.tail(n_edges_dofs);
528 Xh.
asVectorXd().head(n_cell_dofs + n_edge_unknowns) = relax*dX.head(n_cell_dofs + n_edge_unknowns) + Xhprev.
asVectorXd().head(n_cell_dofs + n_edge_unknowns);
532 Eigen::VectorXd RES_temp = residual_scheme(dt, Xh, RHS_nl, Ih_W, mu_squared);
533 double residual_temp = RES_temp.norm();
535 if (iter > 1 && residual_temp > 10*residual[iter-1]){
541 relax = std::min(1.0, 1.2*relax);
545 residual[iter] = residual_temp;
548 _solution_time += double(timerint.elapsed().wall);
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.; };
573 Delta_exp_W = [&](
const VectorRd & p)->
double {
return 0.; };
574 mu_squared = [](
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(); };
581 Delta_exp_W = [&](
const VectorRd & p)->
double {
return 5*exp(W(p)); };
582 mu_squared = [](
const VectorRd & p)->
double {
return 0.; };
586 if(verbose) { std::cout <<
"[main] Wiener process = sin(pi x)sin(pi y)" << std::endl; }
591 Delta_exp_W = [&](
const VectorRd & p)->
double {
592 return exp(W(p)) * (
Delta_mui_ei(1,1,p) + grad_W(p).squaredNorm());
594 mu_squared = [](
const VectorRd & p)->
double {
return std::pow(
mui_ei(1,1,p), 2); };
598 if(verbose) { std::cout <<
"[main] Wiener process = cos(t) * sin(pi x)sin(pi y)" << std::endl; }
599 W = [&](
const VectorRd & p)->
double {
return cos(t) *
mui_ei(1,1,p); };
603 Delta_exp_W = [&](
const VectorRd & p)->
double {
604 return exp(W(p)) * ( cos(t) *
Delta_mui_ei(1,1,p) + grad_W(p).squaredNorm() );
606 mu_squared = [](
const VectorRd & p)->
double {
return std::pow(
mui_ei(1,1,p), 2); };
610 std::cout <<
"[main] Wiener process unknown" << std::endl;
621 size_t nb_eig = Wtime.size();
624 std::normal_distribution<double> Nd{0, sqrt(dt)};
625 for (
size_t k=0; k<nb_eig; ++k){
626 for (
size_t l=0; l<nb_eig; ++l){
627 Wtime[k][l] += Nd(m_gen);
632 W = [&, nb_eig](
const VectorRd & p)->
double {
634 for (
size_t k=0; k<nb_eig; ++k){
635 for (
size_t l=0; l<nb_eig; ++l){
636 val += Wtime[k][l] *
mui_ei(k+1, l+1, p);
643 for (
size_t k=0; k<nb_eig; ++k){
644 for (
size_t l=0; l<nb_eig; ++l){
650 Delta_exp_W = [&, nb_eig](
const VectorRd & p)->
double {
651 double Delta_Wp = 0.;
652 VectorRd grad_Wp = VectorRd::Zero();
653 for (
size_t k=0; k<nb_eig; ++k){
654 for (
size_t l=0; l<nb_eig; ++l){
659 return exp(W(p)) * (Delta_Wp + grad_Wp.squaredNorm());
661 mu_squared = [&, nb_eig](
const VectorRd & p)->
double {
663 for (
size_t k=0; k<nb_eig; ++k){
664 for (
size_t l=0; l<nb_eig; ++l){
665 val += std::pow(
mui_ei(k+1, l+1, p), 2);
673 for (
size_t k=0; k<nb_eig; ++k){
674 for (
size_t l=0; l<nb_eig; ++l){
675 I_W.
asVectorXd() += Wtime[k][l] * Ih_eigs[k][l];
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;
713 size_t n_edges_dofs = Y.size() - n_cell_dofs;
717 size_t end = n_cell_dofs + n_edges_dofs;
721 }
else if (_weight == 1){
723 end = n_cell_dofs + n_edges_dofs;
727 for (
size_t i = start;
i <
end;
i++){
728 ZetaY(
i) = zeta(exp(W(
i)) * Y(
i), type);
730 ZetaY(
i) *= exp(W(
i));
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();
756 const size_t n_edgesT =
T->n_edges();
758 size_t local_dofs = 1 + n_edgesT;
759 Eigen::MatrixXd StiffT = Eigen::MatrixXd::Zero(local_dofs, local_dofs);
762 Eigen::Vector2d xT =
T->center_mass();
763 Eigen::Matrix2d kappaT = kappa(xT,
T);
766 Eigen::MatrixXd nablaK = Eigen::MatrixXd::Zero(dim, local_dofs);
767 for (
size_t iE=0; iE < n_edgesT; iE++){
768 Edge* E =
T->edge(iE);
769 double mE = E->measure();
770 nablaK.block(0, iE+1, dim, 1) = mE *
T->edge_normal(iE);
775 for (
size_t iE=0; iE < n_edgesT; iE++){
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();
781 double dTE = (xE-xT).dot(nTE);
782 double mTE = mE * dTE / dim;
785 Eigen::MatrixXd stabE = Eigen::MatrixXd::Zero(1, local_dofs);
788 stabE -= (xE-xT).transpose() * nablaK;
791 Eigen::MatrixXd GRAD = nablaK + (pow(dim, 0.5)/dTE) * nTE * stabE;
794 StiffT += mTE * GRAD.transpose() * kappaT * GRAD;
801Eigen::VectorXd StochStefanPME::load_operator(
const double tps,
const size_t iT,
const source_function_type & source)
const {
804 Cell*
T = mesh->cell(iT);
805 size_t n_edgesT =
T->n_edges();
806 size_t local_dofs = 1 + n_edgesT;
809 if (MassT.size() < iT ||
size_t(MassT[iT].rows()) != local_dofs){
810 m_output <<
"Called load_operator without creating MassT[iT]\n";
813 Eigen::VectorXd fvec = Eigen::VectorXd::Zero(1 + n_edgesT);
814 for (
size_t i = 0;
i < local_dofs;
i++){
817 node =
T->center_mass();
819 node =
T->edge(
i-1)->center_mass();
821 fvec(
i) = source(node,
T);
824 Eigen::VectorXd load = MassT[iT] * fvec;
832 if (
T->is_boundary()){
833 for (
size_t ilF = 0; ilF <
T->n_edges(); ilF++) {
834 Edge* edge =
T->edge(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{
860 Eigen::VectorXd RES = Eigen::VectorXd::Zero(mesh->
n_cells() + mesh->
n_edges());
863 size_t n_cell_dofs = mesh->
n_cells();
864 for (
size_t iT = 0; iT < mesh->
n_cells(); iT++){
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];
878 ReacT(0,0) *= 0.5 * mu_squared(
T->center_mass());
879 for (
size_t i=0;
i<n_edgesT;
i++){
880 ReacT(
i+1,
i+1) *= 0.5 * mu_squared(
T->edge(
i)->center_mass());
883 Eigen::VectorXd REST = RHS_nl[iT] - (dt * exp_minus_WT * DiffT[iT] * Zeta_expWT_XT + (MassT[iT] + dt * ReacT) * XT);
885 for (
size_t ilE = 0; ilE < n_edgesT; ilE++){
886 size_t iE =
T->edge(ilE)->global_index();
887 RES(n_cell_dofs + iE) += REST(1+ilE);
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);
921 Eigen::VectorXd XTF_powerp = (XTF.array().abs()).pow(p);
923 value += (MassT[iT] * XTF_powerp.matrix() ).sum();
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
Compute max and min eigenvalues of all matrices for i
Definition compute_eigs.m:5
end
Definition compute_eigs.m:12
Eigen::Vector2d VectorRd
Definition basis.hpp:55
static const double PI
Definition ddr-klplate.hpp:187
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
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
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:76
Polytope< DIMENSION > Cell
Definition Polytope2D.hpp:151
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:88
Polytope< 1 > Edge
A Face is a Polytope with object_dim = DIMENSION - 1.
Definition Polytope2D.hpp:147
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
if(strcmp(field, 'real')) % real valued entries T
Definition mmread.m:93
for j
Definition mmread.m:174
Definition ddr-klplate.hpp:27
static auto v
Definition ddrcore-test.hpp:32
Description of one node and one weight from a quadrature rule.
Definition quadraturerule.hpp:41