45 const int fe_space_id,
46 const std::vector<LocalBoundary> &local_boundary,
47 std::vector<LocalBoundary> &selected_local_boundary)
49 selected_local_boundary.clear();
55 for (
int i = 0; i < lb.size(); ++i)
57 const int primitive_g_id = lb.global_primitive_id(i);
61 selected_lb.add_boundary_primitive(primitive_g_id, lb[i]);
64 if (!selected_lb.empty())
65 selected_local_boundary.emplace_back(selected_lb);
72 const int fe_space_id,
73 const std::vector<ElementBases> &bases,
74 const std::vector<LocalBoundary> &local_boundary,
75 std::vector<LocalBoundary> &selected_local_boundary,
76 std::vector<int> &boundary_nodes,
79 setup_bc(mesh, kind, fe_space_id, local_boundary, selected_local_boundary);
80 boundary_nodes.clear();
85 const int dim = value_dim > 0 ? value_dim : (
is_scalar() ? 1 : mesh.dimension());
87 for (
const LocalBoundary &lb : selected_local_boundary)
89 const auto &
b = bases[lb.element_id()];
90 for (
int i = 0; i < lb.size(); ++i)
92 const int primitive_global_id = lb.global_primitive_id(i);
93 const auto nodes =
b.local_nodes_for_primitive(primitive_global_id, mesh);
95 for (
long n = 0; n <
nodes.size(); ++n)
97 auto &bs =
b.bases[
nodes(n)];
98 for (
size_t g = 0;
g < bs.global().size(); ++
g)
100 const int base_index = bs.global()[
g].index *
dim;
101 for (
int d = 0; d <
dim; ++d)
104 boundary_nodes.push_back(base_index + d);
111 std::sort(boundary_nodes.begin(), boundary_nodes.end());
112 const auto end = std::unique(boundary_nodes.begin(), boundary_nodes.end());
113 boundary_nodes.resize(std::distance(boundary_nodes.begin(), end));
119 const int fe_space_id,
120 const std::vector<LocalBoundary> &local_boundary,
121 std::unordered_map<
int, std::vector<LocalBoundary>> &selected_by_tag)
123 std::vector<LocalBoundary> selected;
124 setup_bc(mesh, kind, fe_space_id, local_boundary, selected);
125 selected_by_tag.clear();
126 for (
const LocalBoundary &lb : selected)
128 for (
int i = 0; i < lb.size(); ++i)
130 const int primitive_id = lb.global_primitive_id(i);
131 const int tag = mesh.get_boundary_id(primitive_id);
132 LocalBoundary tagged_boundary(lb.element_id(), lb.type());
133 tagged_boundary.add_boundary_primitive(primitive_id, lb[i]);
134 selected_by_tag[tag].emplace_back(tagged_boundary);
142 const int fe_space_id,
144 std::vector<int> &nodes)
152 for (
int n_id = 0; n_id < n_bases; ++n_id)
157 nodes.push_back(n_id);
161 nodes.push_back(n_id);
virtual bool is_dimension_dirichet(const int tag, const int dim, const int fe_space_id=-1) const
std::vector< int > normal_aligned_neumann_boundary_ids_
virtual bool has_boundary(const BoundaryKind kind, const int tag, const int fe_space_id)
virtual bool is_scalar() const =0
virtual bool has_nodal_dirichlet(const int fe_space_id=-1)
virtual bool might_have_no_dirichlet()
Problem(const std::string &name)
virtual bool has_nodal_neumann(const int fe_space_id=-1)
std::vector< int > boundary_ids_
virtual bool is_boundary_pressure(const int boundary_id) 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)
void setup_bc(const mesh::Mesh &mesh, const BoundaryKind kind, const int fe_space_id, const std::vector< mesh::LocalBoundary > &local_boundary, std::vector< mesh::LocalBoundary > &selected_local_boundary)
virtual bool is_nodal_neumann_boundary(const int n_id, const int tag, const int fe_space_id=-1)
std::vector< int > neumann_boundary_ids_
std::vector< int > pressure_cavity_ids_
virtual bool is_nodal_dirichlet_boundary(const int n_id, const int tag, const int fe_space_id=-1)
Boundary primitive IDs for a single element.
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)
virtual int get_node_id(const int node_id) const
Get the boundary selection of a node.