PolyFEM
Loading...
Searching...
No Matches
NodeSelectionUtils.cpp
Go to the documentation of this file.
2
6
7#include <cassert>
8#include <algorithm>
9#include <iterator>
10#include <set>
11#include <vector>
12
13namespace polyfem
14{
15 namespace
16 {
17 template <typename T>
18 Eigen::VectorXi eigen_vec_from_iterable(const T &iterable)
19 {
20 Eigen::VectorXi out;
21 out.resize(iterable.size());
22
23 int counter = 0;
24 for (int v : iterable)
25 {
26 out[counter] = v;
27 ++counter;
28 }
29 return out;
30 }
31
33 bool is_selected(const std::vector<int> &selection, int id)
34 {
35 if (selection.empty())
36 {
37 return true;
38 }
39 return (std::find(selection.begin(), selection.end(), id) != selection.end());
40 }
41 } // namespace
42
43 Eigen::VectorXi select_interior_nodes(
44 const legacy::State &state,
45 const std::vector<int> &volume_selection)
46 {
47 auto &mesh = state.mesh;
48
49 std::set<int> node_ids{};
50 for (int e = 0; e < mesh->n_elements(); ++e)
51 {
52 int body_id = mesh->get_body_id(e);
53 if (!is_selected(volume_selection, body_id))
54 {
55 continue;
56 }
57
58 for (int i = 0; i < mesh->dimension() + 1; ++i)
59 {
60 const int vid = mesh->element_vertex(e, i);
61 if (!mesh->is_boundary_vertex(vid))
62 {
63 node_ids.insert(vid);
64 }
65 }
66 }
67
68 Eigen::VectorXi nodes = eigen_vec_from_iterable(node_ids);
69 std::sort(nodes.begin(), nodes.end());
70 return nodes;
71 }
72
73 Eigen::VectorXi select_boundary_nodes(
74 const legacy::State &state,
75 const std::vector<int> &surface_selection)
76 {
77 auto &mesh = state.mesh;
78
79 std::set<int> node_ids{};
80 for (const auto &lb : state.total_local_boundary)
81 {
82 for (int i = 0; i < lb.size(); ++i)
83 {
84 int primitive_global_id = lb.global_primitive_id(i);
85 int boundary_id = mesh->get_boundary_id(primitive_global_id);
86
87 if (!is_selected(surface_selection, boundary_id))
88 {
89 continue;
90 }
91
92 for (int n = 0; n < mesh->dimension(); ++n)
93 {
94 node_ids.insert(mesh->boundary_element_vertex(primitive_global_id, n));
95 }
96 }
97 }
98
99 Eigen::VectorXi nodes = eigen_vec_from_iterable(node_ids);
100 std::sort(nodes.begin(), nodes.end());
101 return nodes;
102 }
103
105 const legacy::State &state,
106 const std::vector<int> &exclude_surface_selections)
107 {
108 auto &mesh = state.mesh;
109
110 if (!mesh->is_simplicial())
111 {
112 log_and_throw_adjoint_error("select_boundary_node_dofs_excluding_surfaces only supports simplices!");
113 }
114
115 std::set<int> excluded_node_ids{};
116 std::set<int> all_node_ids{};
117 for (const auto &lb : state.total_local_boundary)
118 {
119 int e = lb.element_id();
120 for (int i = 0; i < lb.size(); ++i)
121 {
122 int primitive_global_id = lb.global_primitive_id(i);
123 int boundary_id = mesh->get_boundary_id(primitive_global_id);
124
125 assert(mesh->is_simplex(e));
126 if (std::count(exclude_surface_selections.begin(), exclude_surface_selections.end(), boundary_id) != 0)
127 {
128 for (int n = 0; n < mesh->dimension(); ++n)
129 {
130 excluded_node_ids.insert(mesh->boundary_element_vertex(primitive_global_id, n));
131 }
132 }
133
134 for (int n = 0; n < mesh->dimension(); ++n)
135 {
136 all_node_ids.insert(mesh->boundary_element_vertex(primitive_global_id, n));
137 }
138 }
139 }
140
141 std::vector<int> node_ids;
142 std::set_difference(all_node_ids.begin(), all_node_ids.end(),
143 excluded_node_ids.begin(), excluded_node_ids.end(),
144 std::back_inserter(node_ids));
145
146 std::sort(node_ids.begin(), node_ids.end());
147 return eigen_vec_from_iterable(node_ids);
148 }
149
150} // namespace polyfem
main class that contains the polyfem solver and all its state
Definition State.hpp:114
std::unique_ptr< mesh::Mesh > mesh
current mesh, it can be a Mesh2D or Mesh3D
Definition State.hpp:594
std::vector< mesh::LocalBoundary > total_local_boundary
mapping from elements to nodes for all mesh
Definition State.hpp:559
Eigen::VectorXi select_boundary_nodes_excluding_surfaces(const legacy::State &state, const std::vector< int > &exclude_surface_selections)
Select all boundary nodes (vertex id) except surface.
Eigen::VectorXi select_interior_nodes(const legacy::State &state, const std::vector< int > &volume_selection)
Select interior nodes (vertex id).
Eigen::VectorXi select_boundary_nodes(const legacy::State &state, const std::vector< int > &surface_selection)
Select boundary nodes (vertex id).
void log_and_throw_adjoint_error(const std::string &msg)
Definition Logger.cpp:79