2#ifdef POLYFEM_WITH_BEZIER
3#include <element_validity.hpp>
4using namespace element_validity;
18 template <
int n,
int s,
int p>
21 const Eigen::MatrixXd &cp,
25#ifdef POLYFEM_WITH_BEZIER
26 std::vector<int> hierarchy;
27 StaticValidator<n, s, p> check(n_threads);
28 const auto flag_ = check.isValid(cp, &hierarchy, &invalid_id);
29 const bool flag = flag_ == Validity::valid;
33 for (
const auto i : hierarchy)
36 dst = &(dst->
child(i));
46 template <
int n,
int s,
int p>
49 const Eigen::MatrixXd &cp1,
50 const Eigen::MatrixXd &cp2,
53#ifdef POLYFEM_WITH_BEZIER
54 std::vector<int> hierarchy;
55 ContinuousValidator<n, s, p> check(n_threads);
56 check.setPrecisionTarget(1);
57 const auto flag_ = check.maxTimeStep(cp1, cp2, &hierarchy, &invalid_id);
65 template <
int n,
int s,
int p>
68 const Eigen::MatrixXd &cp1,
69 const Eigen::MatrixXd &cp2,
76#ifdef POLYFEM_WITH_BEZIER
77 std::vector<int> hierarchy;
78 ContinuousValidator<n, s, p> check(n_threads);
79 typename ContinuousValidator<n, s, p>::Info info;
80 step = check.maxTimeStep(
81 cp1, cp2, &hierarchy, &invalid_id, &invalid_step, &info);
82 gaveUp = !info.success();
86 for (
const auto i : hierarchy)
89 dst = &(dst->
child(i));
98 Eigen::MatrixXd
extract_nodes(
const int dim,
const std::vector<basis::ElementBases> &bases,
const std::vector<basis::ElementBases> &gbases,
const Eigen::VectorXd &u,
int order,
int n_elem)
101 n_elem = bases.size();
102 Eigen::MatrixXd local_pts;
107 const int n_basis_per_cell = local_pts.rows();
108 Eigen::MatrixXd cp = Eigen::MatrixXd::Zero(n_elem * n_basis_per_cell, dim);
109 for (
int e = 0; e < n_elem; ++e)
112 vals.
compute(e, dim == 3, local_pts, bases[e], gbases[e]);
116 cp.middleRows(e * n_basis_per_cell, n_basis_per_cell) += g.val *
vals.
basis_values[j].val * u.segment(g.index * dim, dim).transpose();
118 Eigen::MatrixXd mapped;
119 gbases[e].eval_geom_mapping(local_pts, mapped);
120 cp.middleRows(e * n_basis_per_cell, n_basis_per_cell) += mapped;
98 Eigen::MatrixXd
extract_nodes(
const int dim,
const std::vector<basis::ElementBases> &bases,
const std::vector<basis::ElementBases> &gbases,
const Eigen::VectorXd &u,
int order,
int n_elem) {
…}
127 Eigen::MatrixXd local_pts;
137 vals.
compute(0, dim == 3, local_pts, basis, gbasis);
140 cp += g.val *
vals.
basis_values[j].val * u.segment(g.index * dim, dim).transpose();
147 const Eigen::MatrixXd &cp,
148 const Eigen::MatrixXd &uv)
150#ifdef POLYFEM_WITH_BEZIER
157 JacobianEvaluator<2, 2, 1> evaluator(cp);
158 return evaluator.eval(uv, 0);
162 JacobianEvaluator<2, 2, 2> evaluator(cp);
163 return evaluator.eval(uv, 0);
167 JacobianEvaluator<2, 2, 3> evaluator(cp);
168 return evaluator.eval(uv, 0);
172 JacobianEvaluator<2, 2, 4> evaluator(cp);
173 return evaluator.eval(uv, 0);
176 throw std::invalid_argument(
"Order not supported");
185 JacobianEvaluator<3, 3, 1> evaluator(cp);
186 return evaluator.eval(uv, 0);
190 JacobianEvaluator<3, 3, 2> evaluator(cp);
191 return evaluator.eval(uv, 0);
195 JacobianEvaluator<3, 3, 3> evaluator(cp);
196 return evaluator.eval(uv, 0);
203 throw std::invalid_argument(
"Order not supported");
208 return Eigen::VectorXd::Zero(uv.rows());
214 const std::vector<basis::ElementBases> &bases,
215 const std::vector<basis::ElementBases> &gbases,
216 const Eigen::VectorXd &u)
218 const int order = std::max(bases[0].bases.front().order(), gbases[0].bases.front().order());
219 const int n_basis_per_cell = std::max(bases[0].bases.size(), gbases[0].bases.size());
220 const Eigen::MatrixXd cp =
extract_nodes(dim, bases, gbases, u, order);
222 std::vector<int> invalidList;
225#ifdef POLYFEM_WITH_BEZIER
232 StaticValidator<2, 2, 1> check(n_threads);
233 check.isValid(cp,
nullptr,
nullptr, &invalidList);
238 StaticValidator<2, 2, 2> check(n_threads);
239 check.isValid(cp,
nullptr,
nullptr, &invalidList);
244 StaticValidator<2, 2, 3> check(n_threads);
245 check.isValid(cp,
nullptr,
nullptr, &invalidList);
250 StaticValidator<2, 2, 4> check(n_threads);
251 check.isValid(cp,
nullptr,
nullptr, &invalidList);
255 throw std::invalid_argument(
"Order not supported");
264 StaticValidator<3, 3, 1> check(n_threads);
265 check.isValid(cp,
nullptr,
nullptr, &invalidList);
270 StaticValidator<3, 3, 2> check(n_threads);
271 check.isValid(cp,
nullptr,
nullptr, &invalidList);
276 StaticValidator<3, 3, 3> check(n_threads);
277 check.isValid(cp,
nullptr,
nullptr, &invalidList);
286 throw std::invalid_argument(
"Order not supported");
296 std::tuple<bool, int, Tree>
299 const std::vector<basis::ElementBases> &bases,
300 const std::vector<basis::ElementBases> &gbases,
301 const Eigen::VectorXd &u,
302 const double threshold)
304 const int order = std::max(bases[0].bases.front().order(), gbases[0].bases.front().order());
305 const int n_basis_per_cell = std::max(bases[0].bases.size(), gbases[0].bases.size());
306 Eigen::MatrixXd cp =
extract_nodes(dim, bases, gbases, u, order);
319 flag = check_static<2, 2, 1>(n_threads, cp, invalid_id, tree);
322 flag = check_static<2, 2, 2>(n_threads, cp, invalid_id, tree);
325 flag = check_static<2, 2, 3>(n_threads, cp, invalid_id, tree);
328 flag = check_static<2, 2, 4>(n_threads, cp, invalid_id, tree);
331 throw std::invalid_argument(
"Order not supported");
339 flag = check_static<3, 3, 1>(n_threads, cp, invalid_id, tree);
342 flag = check_static<3, 3, 2>(n_threads, cp, invalid_id, tree);
345 flag = check_static<3, 3, 3>(n_threads, cp, invalid_id, tree);
351 throw std::invalid_argument(
"Order not supported");
355 return {flag, invalid_id, tree};
360 const std::vector<basis::ElementBases> &bases,
361 const std::vector<basis::ElementBases> &gbases,
362 const Eigen::VectorXd &u1,
363 const Eigen::VectorXd &u2,
364 const double threshold)
366 const int order = std::max(bases[0].bases.front().order(), gbases[0].bases.front().order());
367 const int n_basis_per_cell = std::max(bases[0].bases.size(), gbases[0].bases.size());
369 const Eigen::MatrixXd cp1 =
extract_nodes(dim, bases, gbases, u1, order);
370 const Eigen::MatrixXd cp2 =
extract_nodes(dim, bases, gbases, u2, order);
380 return check_transient<2, 2, 1>(n_threads, cp1, cp2, invalid_id);
382 return check_transient<2, 2, 2>(n_threads, cp1, cp2, invalid_id);
384 return check_transient<2, 2, 3>(n_threads, cp1, cp2, invalid_id);
386 return check_transient<2, 2, 4>(n_threads, cp1, cp2, invalid_id);
388 throw std::invalid_argument(
"Order not supported");
396 return check_transient<3, 3, 1>(n_threads, cp1, cp2, invalid_id);
398 return check_transient<3, 3, 2>(n_threads, cp1, cp2, invalid_id);
400 return check_transient<3, 3, 3>(n_threads, cp1, cp2, invalid_id);
404 throw std::invalid_argument(
"Order not supported");
411 const std::vector<basis::ElementBases> &bases,
412 const std::vector<basis::ElementBases> &gbases,
413 const Eigen::VectorXd &u1,
414 const Eigen::VectorXd &u2,
417 const int order = std::max(bases[0].bases.front().order(), gbases[0].bases.front().order());
418 const int n_basis_per_cell = std::max(bases[0].bases.size(), gbases[0].bases.size());
419 Eigen::MatrixXd cp1 =
extract_nodes(dim, bases, gbases, u1, order);
420 Eigen::MatrixXd cp2 =
extract_nodes(dim, bases, gbases, u2, order);
427 double invalid_step = 1.;
437 check_transient<2, 2, 1>(n_threads, cp1, cp2, step, invalid_id, invalid_step, gaveUp, tree);
440 check_transient<2, 2, 2>(n_threads, cp1, cp2, step, invalid_id, invalid_step, gaveUp, tree);
443 check_transient<2, 2, 3>(n_threads, cp1, cp2, step, invalid_id, invalid_step, gaveUp, tree);
446 check_transient<2, 2, 4>(n_threads, cp1, cp2, step, invalid_id, invalid_step, gaveUp, tree);
449 throw std::invalid_argument(
"Order not supported");
457 check_transient<3, 3, 1>(n_threads, cp1, cp2, step, invalid_id, invalid_step, gaveUp, tree);
460 check_transient<3, 3, 2>(n_threads, cp1, cp2, step, invalid_id, invalid_step, gaveUp, tree);
463 check_transient<3, 3, 3>(n_threads, cp1, cp2, step, invalid_id, invalid_step, gaveUp, tree);
469 throw std::invalid_argument(
"Order not supported");
476 return {step, invalid_id, invalid_step, tree};
ElementAssemblyValues vals
stores per element basis values at given quadrature points and geometric mapping
std::vector< AssemblyValues > basis_values
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,...
Stores the basis functions for a given element in a mesh (facet in 2d, cell in 3d).
void eval_geom_mapping(const Eigen::MatrixXd &samples, Eigen::MatrixXd &mapped) const
Map the sample positions in the parametric domain to the object domain (if the element has no paramet...
size_t num_threads() const
void p_nodes_2d(const int p, Eigen::MatrixXd &val)
void p_nodes_3d(const int p, Eigen::MatrixXd &val)
std::tuple< bool, int, Tree > is_valid(const int dim, const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &gbases, const Eigen::VectorXd &u, const double threshold)
Eigen::VectorXd robust_evaluate_jacobian(const int order, const Eigen::MatrixXd &cp, const Eigen::MatrixXd &uv)
std::tuple< double, int, double, Tree > max_time_step(const int dim, const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &gbases, const Eigen::VectorXd &u1, const Eigen::VectorXd &u2, double precision)
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::MatrixXd extract_nodes(const int dim, const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &gbases, const Eigen::VectorXd &u, int order, int n_elem)
void log_and_throw_error(const std::string &msg)