2#include <element_validity.hpp>
9using namespace element_validity;
15 template <
int n,
int s,
int p>
18 const Eigen::MatrixXd &cp,
22 std::vector<int> hierarchy;
23 StaticValidator<n,s,p> check(n_threads);
24 const auto flag_ = check.isValid(cp, &hierarchy, &invalid_id);
25 const bool flag = flag_ == Validity::valid;
28 for (
const auto i : hierarchy) {
30 dst = &(dst->
child(i));
36 template <
int n,
int s,
int p>
39 const Eigen::MatrixXd &cp1,
40 const Eigen::MatrixXd &cp2,
43 std::vector<int> hierarchy;
44 ContinuousValidator<n,s,p> check(n_threads);
45 check.setPrecisionTarget(1);
46 const auto flag_ = check.maxTimeStep(cp1, cp2, &hierarchy, &invalid_id);
50 template <
int n,
int s,
int p>
53 const Eigen::MatrixXd &cp1,
54 const Eigen::MatrixXd &cp2,
61 std::vector<int> hierarchy;
62 ContinuousValidator<n,s,p> check(n_threads);
63 typename ContinuousValidator<n,s,p>::Info info;
64 step = check.maxTimeStep(
65 cp1, cp2, &hierarchy, &invalid_id, &invalid_step, &info
67 gaveUp = !info.success();
70 for (
const auto i : hierarchy) {
72 dst = &(dst->
child(i));
77 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)
80 n_elem = bases.size();
81 Eigen::MatrixXd local_pts;
86 const int n_basis_per_cell = local_pts.rows();
87 Eigen::MatrixXd cp = Eigen::MatrixXd::Zero(n_elem * n_basis_per_cell, dim);
88 for (
int e = 0; e < n_elem; ++e)
91 vals.
compute(e, dim == 3, local_pts, bases[e], gbases[e]);
95 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();
97 Eigen::MatrixXd mapped;
98 gbases[e].eval_geom_mapping(local_pts, mapped);
99 cp.middleRows(e * n_basis_per_cell, n_basis_per_cell) += mapped;
106 Eigen::MatrixXd local_pts;
116 vals.
compute(0, dim == 3, local_pts, basis, gbasis);
119 cp += g.val *
vals.
basis_values[j].val * u.segment(g.index * dim, dim).transpose();
126 const Eigen::MatrixXd &cp,
127 const Eigen::MatrixXd &uv)
129 if (cp.cols() == 2) {
132 JacobianEvaluator<2, 2, 1> evaluator(cp);
133 return evaluator.eval(uv, 0);
136 JacobianEvaluator<2, 2, 2> evaluator(cp);
137 return evaluator.eval(uv, 0);
140 JacobianEvaluator<2, 2, 3> evaluator(cp);
141 return evaluator.eval(uv, 0);
144 JacobianEvaluator<2, 2, 4> evaluator(cp);
145 return evaluator.eval(uv, 0);
147 default:
throw std::invalid_argument(
"Order not supported");
153 JacobianEvaluator<3, 3, 1> evaluator(cp);
154 return evaluator.eval(uv, 0);
157 JacobianEvaluator<3, 3, 2> evaluator(cp);
158 return evaluator.eval(uv, 0);
161 JacobianEvaluator<3, 3, 3> evaluator(cp);
162 return evaluator.eval(uv, 0);
168 default:
throw std::invalid_argument(
"Order not supported");
175 const std::vector<basis::ElementBases> &bases,
176 const std::vector<basis::ElementBases> &gbases,
177 const Eigen::VectorXd &u)
179 const int order = std::max(bases[0].bases.front().order(), gbases[0].bases.front().order());
180 const int n_basis_per_cell = std::max(bases[0].bases.size(), gbases[0].bases.size());
181 const Eigen::MatrixXd cp =
extract_nodes(dim, bases, gbases, u, order);
183 std::vector<int> invalidList;
186 if (cp.cols() == 2) {
189 StaticValidator<2, 2, 1> check(n_threads);
190 check.isValid(cp,
nullptr,
nullptr, &invalidList);
194 StaticValidator<2, 2, 2> check(n_threads);
195 check.isValid(cp,
nullptr,
nullptr, &invalidList);
199 StaticValidator<2, 2, 3> check(n_threads);
200 check.isValid(cp,
nullptr,
nullptr, &invalidList);
204 StaticValidator<2, 2, 4> check(n_threads);
205 check.isValid(cp,
nullptr,
nullptr, &invalidList);
208 default:
throw std::invalid_argument(
"Order not supported");
214 StaticValidator<3, 3, 1> check(n_threads);
215 check.isValid(cp,
nullptr,
nullptr, &invalidList);
219 StaticValidator<3, 3, 2> check(n_threads);
220 check.isValid(cp,
nullptr,
nullptr, &invalidList);
224 StaticValidator<3, 3, 3> check(n_threads);
225 check.isValid(cp,
nullptr,
nullptr, &invalidList);
233 default:
throw std::invalid_argument(
"Order not supported");
240 std::tuple<bool, int, Tree>
243 const std::vector<basis::ElementBases> &bases,
244 const std::vector<basis::ElementBases> &gbases,
245 const Eigen::VectorXd &u,
246 const double threshold)
248 const int order = std::max(bases[0].bases.front().order(), gbases[0].bases.front().order());
249 const int n_basis_per_cell = std::max(bases[0].bases.size(), gbases[0].bases.size());
250 Eigen::MatrixXd cp =
extract_nodes(dim, bases, gbases, u, order);
261 flag = check_static<2, 2, 1>(n_threads, cp, invalid_id, tree);
264 flag = check_static<2, 2, 2>(n_threads, cp, invalid_id, tree);
267 flag = check_static<2, 2, 3>(n_threads, cp, invalid_id, tree);
270 flag = check_static<2, 2, 4>(n_threads, cp, invalid_id, tree);
273 throw std::invalid_argument(
"Order not supported");
279 flag = check_static<3, 3, 1>(n_threads, cp, invalid_id, tree);
282 flag = check_static<3, 3, 2>(n_threads, cp, invalid_id, tree);
285 flag = check_static<3, 3, 3>(n_threads, cp, invalid_id, tree);
291 throw std::invalid_argument(
"Order not supported");
295 return {flag, invalid_id, tree};
300 const std::vector<basis::ElementBases> &bases,
301 const std::vector<basis::ElementBases> &gbases,
302 const Eigen::VectorXd &u1,
303 const Eigen::VectorXd &u2,
304 const double threshold)
306 const int order = std::max(bases[0].bases.front().order(), gbases[0].bases.front().order());
307 const int n_basis_per_cell = std::max(bases[0].bases.size(), gbases[0].bases.size());
309 const Eigen::MatrixXd cp1 =
extract_nodes(dim, bases, gbases, u1, order);
310 const Eigen::MatrixXd cp2 =
extract_nodes(dim, bases, gbases, u2, order);
318 return check_transient<2, 2, 1>(n_threads, cp1, cp2, invalid_id);
320 return check_transient<2, 2, 2>(n_threads, cp1, cp2, invalid_id);
322 return check_transient<2, 2, 3>(n_threads, cp1, cp2, invalid_id);
324 return check_transient<2, 2, 4>(n_threads, cp1, cp2, invalid_id);
326 throw std::invalid_argument(
"Order not supported");
332 return check_transient<3, 3, 1>(n_threads, cp1, cp2, invalid_id);
334 return check_transient<3, 3, 2>(n_threads, cp1, cp2, invalid_id);
336 return check_transient<3, 3, 3>(n_threads, cp1, cp2, invalid_id);
340 throw std::invalid_argument(
"Order not supported");
347 const std::vector<basis::ElementBases> &bases,
348 const std::vector<basis::ElementBases> &gbases,
349 const Eigen::VectorXd &u1,
350 const Eigen::VectorXd &u2,
353 const int order = std::max(bases[0].bases.front().order(), gbases[0].bases.front().order());
354 const int n_basis_per_cell = std::max(bases[0].bases.size(), gbases[0].bases.size());
355 Eigen::MatrixXd cp1 =
extract_nodes(dim, bases, gbases, u1, order);
356 Eigen::MatrixXd cp2 =
extract_nodes(dim, bases, gbases, u2, order);
363 double invalid_step = 1.;
371 check_transient<2, 2, 1>(n_threads, cp1, cp2, step, invalid_id, invalid_step, gaveUp, tree);
374 check_transient<2, 2, 2>(n_threads, cp1, cp2, step, invalid_id, invalid_step, gaveUp, tree);
377 check_transient<2, 2, 3>(n_threads, cp1, cp2, step, invalid_id, invalid_step, gaveUp, tree);
380 check_transient<2, 2, 4>(n_threads, cp1, cp2, step, invalid_id, invalid_step, gaveUp, tree);
383 throw std::invalid_argument(
"Order not supported");
389 check_transient<3, 3, 1>(n_threads, cp1, cp2, step, invalid_id, invalid_step, gaveUp, tree);
392 check_transient<3, 3, 2>(n_threads, cp1, cp2, step, invalid_id, invalid_step, gaveUp, tree);
395 check_transient<3, 3, 3>(n_threads, cp1, cp2, step, invalid_id, invalid_step, gaveUp, tree);
401 throw std::invalid_argument(
"Order not supported");
408 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)