20#include <igl/per_face_normals.h>
25 using namespace assembler;
26 using namespace basis;
30 void flattened_tensor_coeffs(
const Eigen::MatrixXd &S, Eigen::MatrixXd &X)
34 X.resize(S.rows(), 3);
39 else if (S.cols() == 9)
42 X.resize(S.rows(), 6);
52 logger().error(
"Invalid tensor dimensions.");
59 const bool is_problem_scalar,
60 const std::vector<basis::ElementBases> &bases,
61 const std::vector<basis::ElementBases> &gbases,
62 const Eigen::MatrixXd &pts,
63 const Eigen::MatrixXi &
faces,
64 const Eigen::MatrixXd &fun,
65 const bool compute_avg,
66 Eigen::MatrixXd &result)
70 logger().error(
"Solve the problem first!");
75 const Mesh3D &mesh3d =
dynamic_cast<const Mesh3D &
>(mesh);
77 Eigen::MatrixXd points, uv;
78 Eigen::VectorXd weights;
81 if (!is_problem_scalar)
84 igl::AABB<Eigen::MatrixXd, 3> tree;
85 tree.init(pts,
faces);
87 result.resize(
faces.rows(), actual_dim);
88 result.setConstant(std::numeric_limits<double>::quiet_NaN());
99 const int face_id = mesh3d.
cell_face(e, lf);
120 for (
size_t j = 0; j < bs.
bases.size(); ++j)
125 for (
int d = 0; d < actual_dim; ++d)
127 for (
size_t g = 0; g < v.
global.size(); ++g)
129 loc_val(d) += (v.
global[g].val * v.
val.array() * fun(v.
global[g].index * actual_dim + d) * weights.array()).sum();
135 Eigen::RowVector3d C;
138 const double dist = tree.squared_distance(pts,
faces, bary, I, C);
139 assert(dist < 1e-16);
141 assert(std::isnan(result(I, 0)));
143 result.row(I) = loc_val / weights.sum();
145 result.row(I) = loc_val;
150 assert(counter == result.rows());
155 const bool is_problem_scalar,
157 const std::vector<basis::ElementBases> &bases,
158 const std::vector<basis::ElementBases> &gbases,
159 const Eigen::VectorXi &disc_orders,
160 const std::map<int, Eigen::MatrixXd> &polys,
161 const std::map<
int, std::pair<Eigen::MatrixXd, Eigen::MatrixXi>> &polys_3d,
166 const Eigen::MatrixXd &fun,
167 std::vector<assembler::Assembler::NamedMatrix> &result_scalar,
168 std::vector<assembler::Assembler::NamedMatrix> &result_tensor,
169 const bool use_sampler,
170 const bool boundary_only)
172 result_scalar.clear();
173 result_tensor.clear();
177 logger().error(
"Solve the problem first!");
180 if (is_problem_scalar)
182 logger().error(
"Define a tensor problem!");
186 assert(!is_problem_scalar);
189 std::vector<Eigen::MatrixXd> avg_scalar;
191 Eigen::MatrixXd areas(n_bases, 1);
194 std::vector<std::pair<std::string, Eigen::MatrixXd>> tmp_s;
195 Eigen::MatrixXd local_val;
198 for (
int i = 0; i < int(bases.size()); ++i)
202 Eigen::MatrixXd local_pts;
224 vals.compute(i, actual_dim == 3, bases[i], gbases[i]);
226 const double area = (
vals.det.array() *
quadrature.weights.array()).sum();
233 for (
size_t j = 0; j < bs.
bases.size(); ++j)
236 if (b.
global().size() > 1)
239 auto &global = b.
global().front();
240 areas(global.index) += area;
243 if (avg_scalar.empty())
245 avg_scalar.resize(tmp_s.size());
246 for (
auto &m : avg_scalar)
248 m.resize(n_bases, 1);
253 for (
int k = 0; k < tmp_s.size(); ++k)
255 local_val = tmp_s[k].second;
257 for (
size_t j = 0; j < bs.
bases.size(); ++j)
260 if (b.
global().size() > 1)
263 auto &global = b.
global().front();
264 avg_scalar[k](global.index) += local_val(j) * area;
269 for (
auto &m : avg_scalar)
271 m.array() /= areas.array();
274 result_scalar.resize(tmp_s.size());
275 for (
int k = 0; k < tmp_s.size(); ++k)
277 result_scalar[k].first = tmp_s[k].first;
279 avg_scalar[k], result_scalar[k].second, use_sampler, boundary_only);
286 const bool is_problem_scalar,
287 const std::vector<basis::ElementBases> &bases,
288 const std::vector<basis::ElementBases> &gbases,
289 const Eigen::VectorXi &disc_orders,
291 const Eigen::MatrixXd &fun,
293 Eigen::MatrixXd &result,
294 Eigen::VectorXd &von_mises)
303 logger().error(
"Solve the problem first!");
306 if (is_problem_scalar)
308 logger().error(
"Define a tensor problem!");
313 assert(!is_problem_scalar);
315 Eigen::MatrixXd local_val, local_stress, local_mises;
317 int num_quadr_pts = 0;
318 result.resize(disc_orders.sum(), actual_dim == 2 ? 3 : 6);
320 von_mises.resize(disc_orders.sum(), 1);
331 f.get_quadrature(disc_orders(e), quadr);
336 f.get_quadrature(disc_orders(e), quadr);
344 f.get_quadrature(disc_orders(e), quadr);
349 f.get_quadrature(disc_orders(e), quadr);
357 std::vector<std::pair<std::string, Eigen::MatrixXd>> tmp_s, tmp_t;
362 local_mises = tmp_s[0].second;
363 local_val = tmp_t[0].second;
365 if (num_quadr_pts + local_val.rows() >= result.rows())
367 result.conservativeResize(
368 std::max(num_quadr_pts + local_val.rows() + 1, 2 * result.rows()),
370 von_mises.conservativeResize(result.rows(), von_mises.cols());
372 flattened_tensor_coeffs(local_val, local_stress);
373 result.block(num_quadr_pts, 0, local_stress.rows(), local_stress.cols()) = local_stress;
374 von_mises.block(num_quadr_pts, 0, local_mises.rows(), local_mises.cols()) = local_mises;
375 num_quadr_pts += local_val.rows();
377 result.conservativeResize(num_quadr_pts, result.cols());
378 von_mises.conservativeResize(num_quadr_pts, von_mises.cols());
383 const bool is_problem_scalar,
384 const std::vector<basis::ElementBases> &bases,
385 const Eigen::VectorXi &disc_orders,
386 const std::map<int, Eigen::MatrixXd> &polys,
387 const std::map<
int, std::pair<Eigen::MatrixXd, Eigen::MatrixXi>> &polys_3d,
390 const Eigen::MatrixXd &fun,
391 Eigen::MatrixXd &result,
392 const bool use_sampler,
393 const bool boundary_only)
396 if (!is_problem_scalar)
399 polys, polys_3d, sampler, n_points,
400 fun, result, use_sampler, boundary_only);
405 const std::vector<basis::ElementBases> &gbasis,
406 const std::vector<basis::ElementBases> &basis,
407 const Eigen::VectorXi &disc_orders,
408 const std::map<int, Eigen::MatrixXd> &polys,
409 const std::map<
int, std::pair<Eigen::MatrixXd, Eigen::MatrixXi>> &polys_3d,
412 const Eigen::MatrixXd &fun,
413 Eigen::Vector<bool, -1> &result,
414 const bool use_sampler,
415 const bool boundary_only)
419 logger().error(
"Solve the problem first!");
423 result.setZero(n_points);
427 Eigen::MatrixXi vis_faces_poly, vis_edges_poly;
431 for (
int i = 0; i < int(basis.size()); ++i)
434 Eigen::MatrixXd local_pts;
448 sampler.
sample_polyhedron(polys_3d.at(i).first, polys_3d.at(i).second, local_pts, vis_faces_poly, vis_edges_poly);
450 sampler.
sample_polygon(polys.at(i), local_pts, vis_faces_poly, vis_edges_poly);
475 if (std::find(invalidList.begin(), invalidList.end(), i) != invalidList.end())
476 result.segment(index, local_pts.rows()).array() =
true;
477 index += local_pts.rows();
483 const int actual_dim,
484 const std::vector<basis::ElementBases> &basis,
485 const Eigen::VectorXi &disc_orders,
486 const std::map<int, Eigen::MatrixXd> &polys,
487 const std::map<
int, std::pair<Eigen::MatrixXd, Eigen::MatrixXi>> &polys_3d,
490 const Eigen::MatrixXd &fun,
491 Eigen::MatrixXd &result,
492 const bool use_sampler,
493 const bool boundary_only)
497 logger().error(
"Solve the problem first!");
501 std::vector<AssemblyValues> tmp;
503 result.resize(n_points, actual_dim);
507 Eigen::MatrixXi vis_faces_poly, vis_edges_poly;
509 for (
int i = 0; i < int(basis.size()); ++i)
512 Eigen::MatrixXd local_pts;
526 sampler.
sample_polyhedron(polys_3d.at(i).first, polys_3d.at(i).second, local_pts, vis_faces_poly, vis_edges_poly);
528 sampler.
sample_polygon(polys.at(i), local_pts, vis_faces_poly, vis_edges_poly);
553 Eigen::MatrixXd local_res = Eigen::MatrixXd::Zero(local_pts.rows(), actual_dim);
555 for (
size_t j = 0; j < bs.
bases.size(); ++j)
559 for (
int d = 0; d < actual_dim; ++d)
561 for (
size_t ii = 0; ii < b.
global().size(); ++ii)
562 local_res.col(d) += b.
global()[ii].val * tmp[j].val * fun(b.
global()[ii].index * actual_dim + d);
566 result.block(index, 0, local_res.rows(), actual_dim) = local_res;
567 index += local_res.rows();
573 const bool is_problem_scalar,
574 const std::vector<basis::ElementBases> &bases,
575 const std::vector<basis::ElementBases> &gbases,
577 const Eigen::MatrixXd &local_pts,
578 const Eigen::MatrixXd &fun,
579 Eigen::MatrixXd &result,
580 Eigen::MatrixXd &result_grad)
583 if (!is_problem_scalar)
586 local_pts, fun, result, result_grad);
591 const int actual_dim,
592 const std::vector<basis::ElementBases> &bases,
593 const std::vector<basis::ElementBases> &gbases,
595 const Eigen::MatrixXd &local_pts,
596 const Eigen::MatrixXd &fun,
597 Eigen::MatrixXd &result,
598 Eigen::MatrixXd &result_grad)
602 logger().error(
"Solve the problem first!");
606 assert(local_pts.cols() == mesh.
dimension());
607 assert(fun.cols() == 1);
615 result.resize(
vals.val.rows(), actual_dim);
618 result_grad.resize(
vals.val.rows(), mesh.
dimension() * actual_dim);
619 result_grad.setZero();
621 const int n_loc_bases = int(
vals.basis_values.size());
623 for (
int i = 0; i < n_loc_bases; ++i)
625 const auto &
val =
vals.basis_values[i];
627 for (
size_t ii = 0; ii <
val.global.size(); ++ii)
629 for (
int d = 0; d < actual_dim; ++d)
631 result.col(d) +=
val.global[ii].val * fun(
val.global[ii].index * actual_dim + d) *
val.val;
632 result_grad.block(0, d *
val.grad_t_m.cols(), result_grad.rows(),
val.grad_t_m.cols()) +=
val.global[ii].val * fun(
val.global[ii].index * actual_dim + d) *
val.grad_t_m;
642 logger().error(
"Solve the problem first!");
646 assert(fun.cols() == 1);
648 result.resize(
vals.val.rows(), actual_dim);
651 result_grad.resize(
vals.val.rows(), dim * actual_dim);
652 result_grad.setZero();
654 const int n_loc_bases = int(
vals.basis_values.size());
656 for (
int i = 0; i < n_loc_bases; ++i)
658 const auto &
val =
vals.basis_values[i];
660 for (
size_t ii = 0; ii <
val.global.size(); ++ii)
662 for (
int d = 0; d < actual_dim; ++d)
664 result.col(d) +=
val.global[ii].val * fun(
val.global[ii].index * actual_dim + d) *
val.val;
665 result_grad.block(0, d *
val.grad_t_m.cols(), result_grad.rows(),
val.grad_t_m.cols()) +=
val.global[ii].val * fun(
val.global[ii].index * actual_dim + d) *
val.grad_t_m;
673 const bool is_problem_scalar,
674 const std::vector<basis::ElementBases> &bases,
675 const std::vector<basis::ElementBases> &gbases,
676 const Eigen::VectorXi &disc_orders,
677 const std::map<int, Eigen::MatrixXd> &polys,
678 const std::map<
int, std::pair<Eigen::MatrixXd, Eigen::MatrixXi>> &polys_3d,
681 const Eigen::MatrixXd &fun,
683 const bool use_sampler,
684 const bool boundary_only)
688 logger().error(
"Solve the problem first!");
692 assert(!is_problem_scalar);
694 Eigen::MatrixXi vis_faces_poly, vis_edges_poly;
696 std::vector<std::pair<std::string, Eigen::MatrixXd>> tmp_s;
698 for (
int i = 0; i < int(bases.size()); ++i)
705 Eigen::MatrixXd local_pts;
716 sampler.
sample_polyhedron(polys_3d.at(i).first, polys_3d.at(i).second, local_pts, vis_faces_poly, vis_edges_poly);
718 sampler.
sample_polygon(polys.at(i), local_pts, vis_faces_poly, vis_edges_poly);
745 for (
const auto &s : tmp_s)
746 if (std::isnan(s.second.norm()))
755 const bool is_problem_scalar,
756 const std::vector<basis::ElementBases> &bases,
757 const std::vector<basis::ElementBases> &gbases,
758 const Eigen::VectorXi &disc_orders,
759 const std::map<int, Eigen::MatrixXd> &polys,
760 const std::map<
int, std::pair<Eigen::MatrixXd, Eigen::MatrixXi>> &polys_3d,
764 const Eigen::MatrixXd &fun,
766 std::vector<assembler::Assembler::NamedMatrix> &result,
767 const bool use_sampler,
768 const bool boundary_only)
772 logger().error(
"Solve the problem first!");
778 assert(!is_problem_scalar);
782 Eigen::MatrixXi vis_faces_poly, vis_edges_poly;
783 std::vector<std::pair<std::string, Eigen::MatrixXd>> tmp_s;
785 for (
int i = 0; i < int(bases.size()); ++i)
792 Eigen::MatrixXd local_pts;
803 sampler.
sample_polyhedron(polys_3d.at(i).first, polys_3d.at(i).second, local_pts, vis_faces_poly, vis_edges_poly);
805 sampler.
sample_polygon(polys.at(i), local_pts, vis_faces_poly, vis_edges_poly);
834 result.resize(tmp_s.size());
835 for (
int k = 0; k < tmp_s.size(); ++k)
837 result[k].first = tmp_s[k].first;
838 result[k].second.resize(n_points, 1);
842 for (
int k = 0; k < tmp_s.size(); ++k)
844 assert(local_pts.rows() == tmp_s[k].second.rows());
845 result[k].second.block(index, 0, tmp_s[k].second.rows(), 1) = tmp_s[k].second;
847 index += local_pts.rows();
853 const bool is_problem_scalar,
854 const std::vector<basis::ElementBases> &bases,
855 const std::vector<basis::ElementBases> &gbases,
856 const Eigen::VectorXi &disc_orders,
857 const std::map<int, Eigen::MatrixXd> &polys,
858 const std::map<
int, std::pair<Eigen::MatrixXd, Eigen::MatrixXi>> &polys_3d,
862 const Eigen::MatrixXd &fun,
864 std::vector<assembler::Assembler::NamedMatrix> &result,
865 const bool use_sampler,
866 const bool boundary_only)
870 logger().error(
"Solve the problem first!");
877 assert(!is_problem_scalar);
881 Eigen::MatrixXi vis_faces_poly, vis_edges_poly;
882 std::vector<std::pair<std::string, Eigen::MatrixXd>> tmp_t;
884 for (
int i = 0; i < int(bases.size()); ++i)
891 Eigen::MatrixXd local_pts;
902 sampler.
sample_polyhedron(polys_3d.at(i).first, polys_3d.at(i).second, local_pts, vis_faces_poly, vis_edges_poly);
904 sampler.
sample_polygon(polys.at(i), local_pts, vis_faces_poly, vis_edges_poly);
933 result.resize(tmp_t.size());
934 for (
int k = 0; k < tmp_t.size(); ++k)
936 result[k].first = tmp_t[k].first;
937 result[k].second.resize(n_points, actual_dim * actual_dim);
941 for (
int k = 0; k < tmp_t.size(); ++k)
943 assert(local_pts.rows() == tmp_t[k].second.rows());
944 result[k].second.block(index, 0, tmp_t[k].second.rows(), tmp_t[k].second.cols()) = tmp_t[k].second;
946 index += local_pts.rows();
952 const std::shared_ptr<mesh::MeshNodes> mesh_nodes)
954 Eigen::MatrixXd func;
955 func.setZero(n_bases, mesh_nodes->node_position(0).size());
957 for (
int i = 0; i < n_bases; i++)
958 func.row(i) = mesh_nodes->node_position(i);
965 const std::shared_ptr<mesh::MeshNodes> mesh_nodes,
966 const Eigen::MatrixXd &grad)
972 const std::vector<basis::ElementBases> &bases,
973 const std::vector<basis::ElementBases> &gbases,
974 const Eigen::MatrixXd &fun,
976 const int actual_dim)
978 Eigen::VectorXd result;
979 result.setZero(actual_dim);
980 for (
int e = 0; e < bases.size(); ++e)
985 Eigen::MatrixXd u, grad_u;
989 result += u.transpose() *
da;
ElementAssemblyValues vals
std::vector< Eigen::VectorXi > faces
virtual void compute_scalar_value(const OutputData &data, std::vector< NamedMatrix > &result) const
virtual void compute_tensor_value(const OutputData &data, std::vector< NamedMatrix > &result) const
stores per local bases evaluations
std::vector< basis::Local2Global > global
stores per element basis values at given quadrature points and geometric mapping
void compute(const int el_index, const bool is_volume, const Eigen::MatrixXd &pts, const basis::ElementBases &basis, const basis::ElementBases &gbasis)
computes the per element values at the local (ref el) points (pts) sets basis_values,...
Represents one basis function and its gradient.
const std::vector< Local2Global > & global() const
Stores the basis functions for a given element in a mesh (facet in 2d, cell in 3d).
void evaluate_bases(const Eigen::MatrixXd &uv, std::vector< assembler::AssemblyValues > &basis_values) const
evaluate stored bases at given points on the reference element saves results to basis_values
std::vector< Basis > bases
one basis function per node in the element
static Eigen::MatrixXd generate_linear_field(const int n_bases, const std::shared_ptr< mesh::MeshNodes > mesh_nodes, const Eigen::MatrixXd &grad)
bool check_scalar_value(const mesh::Mesh &mesh, const bool is_problem_scalar, const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &gbases, const Eigen::VectorXi &disc_orders, const std::map< int, Eigen::MatrixXd > &polys, const std::map< int, std::pair< Eigen::MatrixXd, Eigen::MatrixXi > > &polys_3d, const assembler::Assembler &assembler, const utils::RefElementSampler &sampler, const Eigen::MatrixXd &fun, const double t, const bool use_sampler, const bool boundary_only)
checks if mises are not nan
static void interpolate_at_local_vals(const mesh::Mesh &mesh, const bool is_problem_scalar, const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &gbases, const int el_index, const Eigen::MatrixXd &local_pts, const Eigen::MatrixXd &fun, Eigen::MatrixXd &result, Eigen::MatrixXd &result_grad)
interpolate solution and gradient at element (calls interpolate_at_local_vals with sol)
static void compute_stress_at_quadrature_points(const mesh::Mesh &mesh, const bool is_problem_scalar, const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &gbases, const Eigen::VectorXi &disc_orders, const assembler::Assembler &assembler, const Eigen::MatrixXd &fun, const double t, Eigen::MatrixXd &result, Eigen::VectorXd &von_mises)
compute von mises stress at quadrature points for the function fun, also compute the interpolated fun...
static Eigen::MatrixXd get_bases_position(const int n_bases, const std::shared_ptr< mesh::MeshNodes > mesh_nodes)
static void interpolate_boundary_function(const mesh::Mesh &mesh, const bool is_problem_scalar, const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &gbases, const Eigen::MatrixXd &pts, const Eigen::MatrixXi &faces, const Eigen::MatrixXd &fun, const bool compute_avg, Eigen::MatrixXd &result)
computes integrated solution (fun) per surface face.
static void mark_flipped_cells(const mesh::Mesh &mesh, const std::vector< basis::ElementBases > &gbasis, const std::vector< basis::ElementBases > &basis, const Eigen::VectorXi &disc_orders, const std::map< int, Eigen::MatrixXd > &polys, const std::map< int, std::pair< Eigen::MatrixXd, Eigen::MatrixXi > > &polys_3d, const utils::RefElementSampler &sampler, const int n_points, const Eigen::MatrixXd &fun, Eigen::Vector< bool, -1 > &result, const bool use_sampler, const bool boundary_only)
static void interpolate_function(const mesh::Mesh &mesh, const bool is_problem_scalar, const std::vector< basis::ElementBases > &bases, const Eigen::VectorXi &disc_orders, const std::map< int, Eigen::MatrixXd > &polys, const std::map< int, std::pair< Eigen::MatrixXd, Eigen::MatrixXi > > &polys_3d, const utils::RefElementSampler &sampler, const int n_points, const Eigen::MatrixXd &fun, Eigen::MatrixXd &result, const bool use_sampler, const bool boundary_only)
interpolate the function fun.
static void average_grad_based_function(const mesh::Mesh &mesh, const bool is_problem_scalar, const int n_bases, const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &gbases, const Eigen::VectorXi &disc_orders, const std::map< int, Eigen::MatrixXd > &polys, const std::map< int, std::pair< Eigen::MatrixXd, Eigen::MatrixXi > > &polys_3d, const assembler::Assembler &assembler, const utils::RefElementSampler &sampler, const double t, const int n_points, const Eigen::MatrixXd &fun, std::vector< assembler::Assembler::NamedMatrix > &result_scalar, std::vector< assembler::Assembler::NamedMatrix > &result_tensor, const bool use_sampler, const bool boundary_only)
computes scalar quantity of funtion (ie von mises for elasticity and norm of velocity for fluid) the ...
static Eigen::VectorXd integrate_function(const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &gbases, const Eigen::MatrixXd &fun, const int dim, const int actual_dim)
static void compute_scalar_value(const mesh::Mesh &mesh, const bool is_problem_scalar, const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &gbases, const Eigen::VectorXi &disc_orders, const std::map< int, Eigen::MatrixXd > &polys, const std::map< int, std::pair< Eigen::MatrixXd, Eigen::MatrixXi > > &polys_3d, const assembler::Assembler &assembler, const utils::RefElementSampler &sampler, const int n_points, const Eigen::MatrixXd &fun, const double t, std::vector< assembler::Assembler::NamedMatrix > &result, const bool use_sampler, const bool boundary_only)
computes scalar quantity of funtion (ie von mises for elasticity and norm of velocity for fluid)
static void compute_tensor_value(const mesh::Mesh &mesh, const bool is_problem_scalar, const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &gbases, const Eigen::VectorXi &disc_orders, const std::map< int, Eigen::MatrixXd > &polys, const std::map< int, std::pair< Eigen::MatrixXd, Eigen::MatrixXi > > &polys_3d, const assembler::Assembler &assembler, const utils::RefElementSampler &sampler, const int n_points, const Eigen::MatrixXd &fun, const double t, std::vector< assembler::Assembler::NamedMatrix > &result, const bool use_sampler, const bool boundary_only)
compute tensor quantity (ie stress tensor or velocy)
virtual int n_cell_faces(const int c_id) const =0
virtual int cell_face(const int c_id, const int lf_id) const =0
Abstract mesh class to capture 2d/3d conforming and non-conforming meshes.
int n_elements() const
utitlity to return the number of elements, cells or faces in 3d and 2d
virtual RowVectorNd face_barycenter(const int f) const =0
face barycenter
bool is_cube(const int el_id) const
checks if element is cube compatible
virtual bool is_boundary_face(const int face_global_id) const =0
is face boundary
bool is_simplex(const int el_id) const
checks if element is simples compatible
virtual bool is_volume() const =0
checks if mesh is volume
int dimension() const
utily for dimension
virtual bool is_boundary_element(const int element_global_id) const =0
is cell boundary
static void quadrature_for_quad_face(int index, int order, const int gid, const mesh::Mesh &mesh, Eigen::MatrixXd &uv, Eigen::MatrixXd &points, Eigen::VectorXd &weights)
static void quadrature_for_tri_face(int index, int order, const int gid, const mesh::Mesh &mesh, Eigen::MatrixXd &uv, Eigen::MatrixXd &points, Eigen::VectorXd &weights)
void sample_polygon(const Eigen::MatrixXd &poly, Eigen::MatrixXd &pts, Eigen::MatrixXi &faces, Eigen::MatrixXi &edges) const
const Eigen::MatrixXd & simplex_points() const
void sample_polyhedron(const Eigen::MatrixXd &vertices, const Eigen::MatrixXi &f, Eigen::MatrixXd &pts, Eigen::MatrixXi &faces, Eigen::MatrixXi &edges) const
const Eigen::MatrixXd & cube_points() const
void q_nodes_2d(const int q, Eigen::MatrixXd &val)
void p_nodes_2d(const int p, Eigen::MatrixXd &val)
void p_nodes_3d(const int p, Eigen::MatrixXd &val)
void q_nodes_3d(const int q, Eigen::MatrixXd &val)
std::vector< int > count_invalid(const int dim, const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &gbases, const Eigen::VectorXd &u)
Eigen::VectorXd flatten(const Eigen::MatrixXd &X)
Flatten rowwises.
spdlog::logger & logger()
Retrieves the current logger.
Eigen::Matrix< double, 1, Eigen::Dynamic, Eigen::RowMajor, 1, 3 > RowVectorNd