26 const std::vector<basis::ElementBases> &bases,
27 const std::shared_ptr<mesh::MeshNodes> &mesh_nodes,
28 const Eigen::MatrixXd &affine_matrix,
29 const double tol): affine_matrix_(affine_matrix)
31 const int dim = affine_matrix.rows();
34 Eigen::MatrixXd
V = extract_vertices(mesh_nodes) * affine_matrix.inverse().transpose();
35 auto boundary_nodes = mesh_nodes->boundary_nodes();
39 const double bbox_size = (max - min).maxCoeff();
40 for (
int d = 0; d < dim; d++)
42 const double eps = tol * bbox_size;
44 Eigen::VectorXi index_map;
45 index_map.setConstant(n_bases, 1, -1);
47 Eigen::VectorXi dependent_map(n_bases);
48 dependent_map.setConstant(-1);
53 for (
int d = 0; d < dim; d++)
55 std::set<int> dependent_ids, target_ids;
56 for (
int bid : boundary_nodes)
58 if (
V(bid, d) > max(d) - eps)
59 target_ids.insert(bid);
60 else if (
V(bid, d) < min(d) + eps)
61 dependent_ids.insert(bid);
64 for (
int i : dependent_ids)
66 bool found_target =
false;
67 for (
int j : target_ids)
70 projected_diff(d) = 0;
71 if (projected_diff.norm() < eps)
86 for (
int i = 0; i < dependent_map.size(); i++)
88 if (dependent_map(i) >= 0)
97 for (
int d = 0; d < dim; d++)
98 for (
int i = 0; i < dependent_map.size(); i++)
99 if (dependent_map(i) >= 0 && dependent_map(dependent_map(i)) >= 0)
100 dependent_map(i) = dependent_map(dependent_map(i));
103 int independent_dof = 0;
104 for (
int i = 0; i < dependent_map.size(); i++)
106 if (dependent_map(i) < 0)
107 index_map(i) = independent_dof++;
110 for (
int i = 0; i < dependent_map.size(); i++)
111 if (dependent_map(i) >= 0)
112 index_map(i) = index_map(dependent_map(i));
114 const int old_size = index_map.size();
116 for (
int i = 0; i < old_size; i++)
126 auto index_map = [&](
int id){
134 std::vector<Eigen::Triplet<double>>
entries;
136 for (
int k = 0; k < A.outerSize(); k++)
138 for (StiffnessMatrix::InnerIterator it(A,k); it; ++it)
140 entries.emplace_back(index_map(it.row()), index_map(it.col()), it.value());
145 std::swap(A_periodic, A);
147 return independent_dof;
154 auto index_map = [&](
int id){
162 Eigen::MatrixXd b_periodic;
163 b_periodic.setZero(index_map(b.rows()), b.cols());
165 for (
int k = 0; k < b.rows(); k++)
166 b_periodic.row(index_map(k)) += b.row(k);
168 for (
int k = 0; k < b.rows(); k++)
169 b_periodic.row(index_map(k)) = b.row(k);
175 std::vector<int> boundary_nodes_reduced = boundary_nodes;
178 for (
int i = 0; i < boundary_nodes_reduced.size(); i++)
181 std::sort(boundary_nodes_reduced.begin(), boundary_nodes_reduced.end());
182 auto it = std::unique(boundary_nodes_reduced.begin(), boundary_nodes_reduced.end());
183 boundary_nodes_reduced.resize(std::distance(boundary_nodes_reduced.begin(), it));
185 return boundary_nodes_reduced;