39 const int fe_space_id,
40 const std::vector<ElementBases> &bases,
41 const std::vector<LocalBoundary> &local_boundary,
42 std::vector<LocalBoundary> &selected_local_boundary,
43 std::vector<int> &boundary_nodes)
47 selected_local_boundary.clear();
48 boundary_nodes.clear();
54 for (
int i = 0; i < lb.size(); ++i)
56 const int primitive_g_id = lb.global_primitive_id(i);
60 selected_lb.add_boundary_primitive(primitive_g_id, lb[i]);
63 if (!selected_lb.empty())
64 selected_local_boundary.emplace_back(selected_lb);
72 for (
const LocalBoundary &lb : selected_local_boundary)
74 const auto &b = bases[lb.element_id()];
75 for (
int i = 0; i < lb.size(); ++i)
77 const int primitive_global_id = lb.global_primitive_id(i);
78 const auto nodes = b.local_nodes_for_primitive(primitive_global_id, mesh);
80 for (
long n = 0; n < nodes.size(); ++n)
82 auto &bs = b.bases[nodes(n)];
83 for (
size_t g = 0; g < bs.global().size(); ++g)
85 const int base_index = bs.global()[g].index * dim;
86 for (
int d = 0; d < dim; ++d)
89 boundary_nodes.push_back(base_index + d);
96 std::sort(boundary_nodes.begin(), boundary_nodes.end());
97 const auto end = std::unique(boundary_nodes.begin(), boundary_nodes.end());
98 boundary_nodes.resize(std::distance(boundary_nodes.begin(), end));
103 const int fe_space_id,
104 const std::vector<LocalBoundary> &local_boundary,
105 std::unordered_map<
int, std::vector<LocalBoundary>> &local_pressure_cavity)
109 local_pressure_cavity.clear();
113 for (
int i = 0; i < lb.size(); ++i)
115 const int primitive_g_id = lb.global_primitive_id(i);
123 local_pressure_cavity[tag].emplace_back(cavity_lb);
131 const int fe_space_id,
133 std::vector<int> &nodes)
143 for (
int n_id = 0; n_id < n_bases; ++n_id)
148 nodes.push_back(n_id);
150 nodes.push_back(n_id);
157 const std::vector<ElementBases> &bases,
158 const std::vector<ElementBases> &geom_bases,
159 const std::vector<ElementBases> &pressure_bases,
160 std::vector<LocalBoundary> &local_boundary,
161 std::vector<int> &boundary_nodes,
162 std::vector<LocalBoundary> &local_neumann_boundary,
163 std::vector<LocalBoundary> &local_pressure_boundary,
164 std::unordered_map<
int, std::vector<LocalBoundary>> &local_pressure_cavity,
165 std::vector<int> &pressure_boundary_nodes,
166 std::vector<int> &dirichlet_nodes,
167 std::vector<int> &neumann_nodes)
169 std::vector<LocalBoundary> new_local_boundary;
170 std::vector<LocalBoundary> new_local_pressure_dirichlet_boundary;
171 local_neumann_boundary.clear();
172 local_pressure_boundary.clear();
173 local_pressure_cavity.clear();
175 for (
auto it = local_boundary.begin(); it != local_boundary.end(); ++it)
177 const auto &lb = *it;
181 LocalBoundary new_pressure_dirichlet_lb(lb.element_id(), lb.type());
182 for (
int i = 0; i < lb.size(); ++i)
184 LocalBoundary new_pressure_cavity_lb(lb.element_id(), lb.type());
186 const int primitive_g_id = lb.global_primitive_id(i);
193 new_lb.add_boundary_primitive(lb.global_primitive_id(i), lb[i]);
195 new_neumann_lb.add_boundary_primitive(lb.global_primitive_id(i), lb[i]);
197 new_neumann_lb.add_boundary_primitive(lb.global_primitive_id(i), lb[i]);
199 new_pressure_lb.add_boundary_primitive(lb.global_primitive_id(i), lb[i]);
201 new_pressure_cavity_lb.add_boundary_primitive(lb.global_primitive_id(i), lb[i]);
203 new_pressure_dirichlet_lb.add_boundary_primitive(lb.global_primitive_id(i), lb[i]);
205 if (!new_pressure_cavity_lb.empty())
207 if (local_pressure_cavity.find(tag) == local_pressure_cavity.end())
208 local_pressure_cavity[tag] = std::vector<LocalBoundary>();
209 local_pressure_cavity[tag].emplace_back(new_pressure_cavity_lb);
214 new_local_boundary.emplace_back(new_lb);
215 if (!new_neumann_lb.empty())
216 local_neumann_boundary.emplace_back(new_neumann_lb);
217 if (!new_pressure_lb.empty())
218 local_pressure_boundary.emplace_back(new_pressure_lb);
219 if (!new_pressure_dirichlet_lb.empty())
220 new_local_pressure_dirichlet_boundary.emplace_back(new_pressure_dirichlet_lb);
222 local_boundary.clear();
223 std::swap(local_boundary, new_local_boundary);
225 boundary_nodes.clear();
226 pressure_boundary_nodes.clear();
230 for (
auto it = local_boundary.begin(); it != local_boundary.end(); ++it)
232 const auto &lb = *it;
233 const auto &
b = bases[lb.element_id()];
234 for (
int i = 0; i < lb.size(); ++i)
236 const int primitive_global_id = lb.global_primitive_id(i);
237 const auto nodes =
b.local_nodes_for_primitive(primitive_global_id, mesh);
239 for (
long n = 0; n <
nodes.size(); ++n)
241 auto &bs =
b.bases[
nodes(n)];
242 for (
size_t g = 0;
g < bs.global().size(); ++
g)
244 const int base_index = bs.global()[
g].index *
dim;
245 for (
int d = 0; d <
dim; ++d)
248 boundary_nodes.push_back(base_index + d);
255 for (
auto it = new_local_pressure_dirichlet_boundary.begin(); it != new_local_pressure_dirichlet_boundary.end(); ++it)
257 const auto &lb = *it;
258 const auto &
b = pressure_bases[lb.element_id()];
259 for (
int i = 0; i < lb.size(); ++i)
261 const int primitive_global_id = lb.global_primitive_id(i);
262 const auto nodes =
b.local_nodes_for_primitive(primitive_global_id, mesh);
264 for (
long n = 0; n <
nodes.size(); ++n)
266 auto &bs =
b.bases[
nodes(n)];
267 for (
size_t g = 0;
g < bs.global().size(); ++
g)
269 const int base_index = bs.global()[
g].index;
270 pressure_boundary_nodes.push_back(base_index);
278 for (
int n_id = 0; n_id < n_bases; ++n_id)
284 dirichlet_nodes.push_back(n_id);
286 for (
int d = 0; d <
dim; ++d)
289 boundary_nodes.push_back(n_id * dim + d);
294 neumann_nodes.push_back(n_id);
299 std::sort(boundary_nodes.begin(), boundary_nodes.end());
300 auto it = std::unique(boundary_nodes.begin(), boundary_nodes.end());
301 boundary_nodes.resize(std::distance(boundary_nodes.begin(), it));
303 std::sort(pressure_boundary_nodes.begin(), pressure_boundary_nodes.end());
304 auto it_ = std::unique(pressure_boundary_nodes.begin(), pressure_boundary_nodes.end());
305 pressure_boundary_nodes.resize(std::distance(pressure_boundary_nodes.begin(), it_));
bool has_boundary(const BoundaryKind kind, const int tag)
virtual bool has_nodal_neumann()
void setup_bc(const mesh::Mesh &mesh, const BoundaryKind kind, const int fe_space_id, const std::vector< basis::ElementBases > &bases, const std::vector< mesh::LocalBoundary > &local_boundary, std::vector< mesh::LocalBoundary > &selected_local_boundary, std::vector< int > &boundary_nodes)
std::vector< int > normal_aligned_neumann_boundary_ids_
virtual bool is_dimension_dirichet(const int tag, const int dim) const
void setup_pressure_cavity_bc(const mesh::Mesh &mesh, const int fe_space_id, const std::vector< mesh::LocalBoundary > &local_boundary, std::unordered_map< int, std::vector< mesh::LocalBoundary > > &local_pressure_cavity)
virtual bool is_scalar() const =0
std::vector< int > pressure_boundary_ids_
virtual bool is_nodal_neumann_boundary(const int n_id, const int tag)
virtual bool might_have_no_dirichlet()
Problem(const std::string &name)
std::vector< int > splitting_pressure_boundary_ids_
std::vector< int > boundary_ids_
virtual bool is_nodal_dirichlet_boundary(const int n_id, const int tag)
virtual bool is_nodal_dimension_dirichlet(const int n_id, const int tag, const int dim) const
void setup_nodal_bc(const mesh::Mesh &mesh, const BoundaryKind kind, const int fe_space_id, const int n_bases, std::vector< int > &nodes)
std::vector< int > neumann_boundary_ids_
std::vector< int > pressure_cavity_ids_
virtual bool has_nodal_dirichlet()
Boundary primitive IDs for a single element.
void add_boundary_primitive(const int global_index, const int local_index)
Mark a boundary primitive as a part of the global boundary.
Abstract mesh class to capture 2d/3d conforming and non-conforming meshes.
bool has_node_ids() const
checks if points selections are available
virtual int get_boundary_id(const int primitive) const
Get the boundary selection of an element (face in 3d, edge in 2d)
int dimension() const
utily for dimension
virtual int get_node_id(const int node_id) const
Get the boundary selection of a node.