PolyFEM
Loading...
Searching...
No Matches
ElementBases.cpp
Go to the documentation of this file.
2
3namespace polyfem
4{
5 using namespace assembler;
6 namespace basis
7 {
8
10 {
11 for (auto &b : bases)
12 {
13 if (!b.is_complete())
14 return false;
15 }
16
17 return true;
18 }
19 void ElementBases::eval_geom_mapping(const Eigen::MatrixXd &samples, Eigen::MatrixXd &mapped) const
20 {
22 {
23 // mapped = (scaling_ * samples).rowwise() + translation_;
24 mapped = samples;
25 return;
26 }
27
28 mapped = Eigen::MatrixXd::Zero(samples.rows(), samples.cols());
29 std::vector<AssemblyValues> tmp_val;
30 evaluate_bases(samples, tmp_val);
31
32 const int n_local_bases = int(bases.size());
33 for (int j = 0; j < n_local_bases; ++j)
34 {
35 const Basis &b = bases[j];
36 const auto &tmp = tmp_val[j].val;
37
38 for (std::size_t ii = 0; ii < b.global().size(); ++ii)
39 {
40 for (long k = 0; k < tmp.size(); ++k)
41 {
42 mapped.row(k) += tmp(k) * b.global()[ii].node * b.global()[ii].val;
43 }
44 }
45 }
46 }
47
48 void ElementBases::evaluate_bases_default(const Eigen::MatrixXd &uv, std::vector<AssemblyValues> &basis_values) const
49 {
50 basis_values.resize(bases.size());
51
52 // val.resize(uv.rows(), bases.size());
53 // Eigen::MatrixXd tmp;
54
55 for (size_t i = 0; i < bases.size(); ++i)
56 {
57 // bases[i].eval_basis(uv, tmp); // = basis_values[i].val
58 // val.col(i) = tmp;
59
60 bases[i].eval_basis(uv, basis_values[i].val);
61 assert(basis_values[i].val.size() == uv.rows());
62 }
63 }
64
65 void ElementBases::evaluate_grads_default(const Eigen::MatrixXd &uv, std::vector<AssemblyValues> &basis_values) const
66 {
67 basis_values.resize(bases.size());
68
69 // grad.resize(uv.rows(), bases.size());
70 // Eigen::MatrixXd grad_tmp;
71
72 for (size_t i = 0; i < bases.size(); ++i)
73 {
74 // bases[i].eval_grad(uv, grad_tmp);
75 // grad.col(i) = grad_tmp.col(dim);
76
77 bases[i].eval_grad(uv, basis_values[i].grad);
78 assert(basis_values[i].grad.rows() == uv.rows());
79 }
80 }
81
82 void ElementBases::eval_geom_mapping_grads(const Eigen::MatrixXd &samples, std::vector<Eigen::MatrixXd> &grads) const
83 {
84 grads.resize(samples.rows());
85
87 {
88 // * scaling
89 std::fill(grads.begin(), grads.end(), Eigen::MatrixXd::Identity(samples.cols(), samples.cols()));
90 return;
91 }
92
93 Eigen::MatrixXd local_grad;
94
95 const int n_local_bases = int(bases.size());
96 const bool is_volume = samples.cols() == 3;
97 Eigen::MatrixXd dxmv = Eigen::MatrixXd::Zero(samples.rows(), samples.cols());
98 Eigen::MatrixXd dymv = Eigen::MatrixXd::Zero(samples.rows(), samples.cols());
99 Eigen::MatrixXd dzmv = Eigen::MatrixXd::Zero(samples.rows(), samples.cols());
100
101 std::vector<AssemblyValues> tmp_val;
102 evaluate_grads(samples, tmp_val);
103
104 for (int j = 0; j < n_local_bases; ++j)
105 {
106 const Basis &b = bases[j];
107 const auto &grad = tmp_val[j].grad;
108
109 for (std::size_t ii = 0; ii < b.global().size(); ++ii)
110 {
111 for (long k = 0; k < samples.rows(); ++k)
112 {
113 dxmv.row(k) += grad(k, 0) * b.global()[ii].node * b.global()[ii].val;
114 dymv.row(k) += grad(k, 1) * b.global()[ii].node * b.global()[ii].val;
115 if (is_volume)
116 dzmv.row(k) += grad(k, 2) * b.global()[ii].node * b.global()[ii].val;
117 }
118 }
119 }
120
121 Eigen::MatrixXd tmp(samples.cols(), samples.cols());
122
123 for (long k = 0; k < samples.rows(); ++k)
124 {
125 tmp.row(0) = dxmv.row(k);
126 tmp.row(1) = dymv.row(k);
127 if (is_volume)
128 tmp.row(2) = dzmv.row(k);
129
130 grads[k] = tmp;
131 }
132 }
133
134 Eigen::MatrixXd ElementBases::nodes() const
135 {
136 if (bases.size() == 0)
137 return Eigen::MatrixXd();
138 const int dim = bases[0].global()[0].node.size();
139 Eigen::MatrixXd _nodes(bases.size(), dim);
140 for (int i = 0; i < bases.size(); ++i)
141 {
142 assert(bases[i].global().size() == 1);
143 _nodes.row(i) = bases[i].global()[0].node;
144 }
145 return _nodes;
146 }
147 } // namespace basis
148} // namespace polyfem
double val
Definition Assembler.cpp:86
Represents one basis function and its gradient.
Definition Basis.hpp:44
const std::vector< Local2Global > & global() const
Definition Basis.hpp:104
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...
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
bool is_complete() const
Checks if all the bases are complete.
Eigen::MatrixXd nodes() const
Assemble the global nodal positions of the bases.
void evaluate_grads(const Eigen::MatrixXd &uv, std::vector< assembler::AssemblyValues > &basis_values) const
evaluate gradient of stored bases at given points on the reference element saves results to basis_val...
void evaluate_bases_default(const Eigen::MatrixXd &uv, std::vector< assembler::AssemblyValues > &basis_values) const
default to simply calling the Basis evaluation functions
void eval_geom_mapping_grads(const Eigen::MatrixXd &samples, std::vector< Eigen::MatrixXd > &grads) const
Evaluate the gradients of the geometric mapping defined above.
void evaluate_grads_default(const Eigen::MatrixXd &uv, std::vector< assembler::AssemblyValues > &basis_values) const
std::vector< Basis > bases
one basis function per node in the element