PolyFEM
Loading...
Searching...
No Matches
Jacobian.hpp
Go to the documentation of this file.
1#pragma once
2
4#include <sstream>
5#include <spdlog/fmt/fmt.h>
6
7namespace polyfem::utils
8{
9 class Tree
10 {
11 public:
12 Tree() {}
13 Tree(const Tree &T)
14 {
15 if (T.has_children())
16 {
17 for (int i = 0; i < T.n_children(); i++)
18 this->children.push_back(std::make_unique<Tree>(T.child(i)));
19 }
20 }
22 {
23 if (this != &T)
24 {
25 this->children.clear();
26 if (T.has_children())
27 {
28 for (int i = 0; i < T.n_children(); i++)
29 this->children.push_back(std::make_unique<Tree>(T.child(i)));
30 }
31 }
32 return *this;
33 }
34 bool merge(const Tree &T, int max_depth = 2)
35 {
36 bool flag = false;
37 if (!T.has_children() || max_depth <= 0)
38 return flag;
39 if (!this->has_children())
40 {
41 this->add_children(T.n_children());
42 flag = true;
43 max_depth--;
44 }
45 for (int i = 0; i < T.n_children(); i++)
46 flag = this->child(i).merge(T.child(i), max_depth) || flag;
47 return flag;
48 }
49
50 // Debug print
51 friend std::ostream &operator<<(
52 std::ostream &ost, const Tree &T)
53 {
54 ost << "(";
55 if (T.has_children())
56 {
57 for (int i = 0; i < T.n_children(); i++)
58 ost << T.child(i) << ", ";
59 }
60 ost << ")";
61 return ost;
62 }
63
64 bool has_children() const { return !children.empty(); }
65 int n_children() const { return children.size(); }
66 int depth() const
67 {
68 if (!has_children())
69 return 0;
70 int d = 0;
71 for (int i = 0; i < n_children(); i++)
72 d = std::max(d, child(i).depth());
73 return d + 1;
74 }
75 int n_leaves() const
76 {
77 if (!has_children())
78 return 1;
79 int n = 0;
80 for (int i = 0; i < n_children(); i++)
81 n += child(i).n_leaves();
82 return n;
83 }
84 Tree &child(int i) { return *children[i]; }
85 const Tree &child(int i) const { return *children[i]; }
86 void add_children(int n)
87 {
88 for (int i = 0; i < n; i++)
89 children.push_back(std::make_unique<Tree>());
90 }
91
92 private:
93 std::vector<std::unique_ptr<Tree>> children;
94 };
95
96 Eigen::VectorXd robust_evaluate_jacobian(
97 const int order,
98 const Eigen::MatrixXd &cp,
99 const Eigen::MatrixXd &uv);
100
101 std::vector<int> count_invalid(
102 const int dim,
103 const std::vector<basis::ElementBases> &bases,
104 const std::vector<basis::ElementBases> &gbases,
105 const Eigen::VectorXd &u,
106 const unsigned max_iter = 1'000'000);
107
108 std::tuple<bool, int, Tree> is_valid(
109 const int dim,
110 const std::vector<basis::ElementBases> &bases,
111 const std::vector<basis::ElementBases> &gbases,
112 const Eigen::VectorXd &u,
113 const double threshold = 0,
114 const unsigned max_iter = 1'000'000);
115
116 std::tuple<double, int, double, Tree> max_time_step(
117 const int dim,
118 const std::vector<basis::ElementBases> &bases,
119 const std::vector<basis::ElementBases> &gbases,
120 const Eigen::VectorXd &u1,
121 const Eigen::VectorXd &u2,
122 double precision = .25,
123 double threshold = 0,
124 const unsigned max_iter = 1'000'000);
125
126 Eigen::MatrixXd extract_nodes(const int dim, const basis::ElementBases &basis, const basis::ElementBases &gbasis, const Eigen::VectorXd &u, int order);
127 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 = -1);
128} // namespace polyfem::utils
129
130template <>
131struct fmt::formatter<polyfem::utils::Tree> : fmt::formatter<fmt::string_view>
132{
133 format_context::iterator format(const polyfem::utils::Tree &tree, fmt::format_context &ctx) const
134 {
135 std::ostringstream oss;
136 oss << tree;
137 return fmt::formatter<fmt::string_view>::format(oss.str(), ctx);
138 }
139};
Stores the basis functions for a given element in a mesh (facet in 2d, cell in 3d).
std::vector< std::unique_ptr< Tree > > children
Definition Jacobian.hpp:93
Tree(const Tree &T)
Definition Jacobian.hpp:13
bool merge(const Tree &T, int max_depth=2)
Definition Jacobian.hpp:34
const Tree & child(int i) const
Definition Jacobian.hpp:85
int depth() const
Definition Jacobian.hpp:66
int n_children() const
Definition Jacobian.hpp:65
bool has_children() const
Definition Jacobian.hpp:64
void add_children(int n)
Definition Jacobian.hpp:86
int n_leaves() const
Definition Jacobian.hpp:75
Tree operator=(const Tree &T)
Definition Jacobian.hpp:21
Tree & child(int i)
Definition Jacobian.hpp:84
friend std::ostream & operator<<(std::ostream &ost, const Tree &T)
Definition Jacobian.hpp:51
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, const unsigned max_iter)
Definition Jacobian.cpp:201
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, double threshold, const unsigned max_iter)
Definition Jacobian.cpp:286
Eigen::VectorXd robust_evaluate_jacobian(const int order, const Eigen::MatrixXd &cp, const Eigen::MatrixXd &uv)
Definition Jacobian.cpp:67
std::vector< int > count_invalid(const int dim, const std::vector< basis::ElementBases > &bases, const std::vector< basis::ElementBases > &gbases, const Eigen::VectorXd &u, const unsigned max_iter)
Definition Jacobian.cpp:122
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)
Definition Jacobian.cpp:20
format_context::iterator format(const polyfem::utils::Tree &tree, fmt::format_context &ctx) const
Definition Jacobian.hpp:133