11#include <unordered_set>
13#include <spdlog/fmt/fmt.h>
21 const std::vector<std::shared_ptr<legacy::State>> &states,
24 assert(!states.empty());
27 int num = states[0]->mesh->n_vertices();
28 for (
auto &s : states)
30 if (s->mesh->n_vertices() != num)
32 reason =
"Mesh vertex num mismatch between states";
37 if (active_geom_nodes.size() == 0)
43 int min_id = active_geom_nodes.minCoeff();
44 int max_id = active_geom_nodes.maxCoeff();
45 if (min_id < 0 || max_id >= num)
47 reason = fmt::format(
"Invalid active node range [{}, {}]", min_id, max_id);
52 std::unordered_set<int> id_set(active_geom_nodes.begin(), active_geom_nodes.end());
53 if (id_set.size() != active_geom_nodes.size())
55 reason =
"Duplicate active node id";
63 const std::vector<std::shared_ptr<legacy::State>> &states,
66 assert(!states.empty());
69 int dim = states[0]->mesh->dimension();
70 for (
auto &s : states)
72 if (s->mesh->dimension() != dim)
74 reason =
"Mesh dimension mismatch between states";
79 if (active_dimensions.size() == 0)
85 int min_dim = active_dimensions.minCoeff();
86 int max_dim = active_dimensions.maxCoeff();
87 if (min_dim < 0 || max_dim >= dim)
89 reason = fmt::format(
"Invalid active dimension range [{}, {}]", min_dim, max_dim);
94 std::unordered_set<int> dim_set(active_dimensions.begin(), active_dimensions.end());
95 if (dim_set.size() != active_dimensions.size())
97 reason =
"Duplicate dimensions";
105 const std::vector<std::shared_ptr<legacy::State>> &states,
108 assert(!states.empty());
111 int ndof = states[0]->ndof();
112 for (
auto &s : states)
114 if (s->ndof() != ndof)
116 reason =
"legacy::State ndof mismatch between states";
121 if (active_dofs.size() == 0)
127 const int min_id = active_dofs.minCoeff();
128 const int max_id = active_dofs.maxCoeff();
129 if (min_id < 0 || max_id >= ndof)
131 reason = fmt::format(
"Invalid active dof range [{}, {}]", min_id, max_id);
136 std::unordered_set<int> id_set(active_dofs.begin(), active_dofs.end());
137 if (id_set.size() != active_dofs.size())
139 reason =
"Duplicate active dof id";
147 const std::vector<std::shared_ptr<legacy::State>> &states,
150 assert(!states.empty());
153 int time_steps = states[0]->args[
"time"][
"time_steps"];
154 for (
auto &s : states)
156 if (
int(s->args[
"time"][
"time_steps"]) != time_steps)
158 reason =
"time_steps mismatch between states";
163 if (active_time_slices.size() == 0)
169 const int min_id = active_time_slices.minCoeff();
170 const int max_id = active_time_slices.maxCoeff();
171 if (min_id < 0 || max_id >= time_steps)
173 reason = fmt::format(
"Invalid active time slice range [{}, {}]", min_id, max_id);
178 std::unordered_set<int> id_set(active_time_slices.begin(), active_time_slices.end());
179 if (id_set.size() != active_time_slices.size())
181 reason =
"Duplicate active time slices";
189 const std::vector<std::shared_ptr<legacy::State>> &states,
192 assert(!states.empty());
194 if (active_boundary_ids.size() == 0)
200 std::unordered_set<int> id_set(active_boundary_ids.begin(), active_boundary_ids.end());
201 if (id_set.size() != active_boundary_ids.size())
203 reason =
"Duplicate active boundary id";
208 int dim = states[0]->mesh->dimension();
209 for (
auto &s : states)
214 auto boundry_dims = s->boundary_conditions_ids(
"dirichlet_boundary");
215 for (
int i = 0; i < active_boundary_ids.size(); ++i)
218 int id = active_boundary_ids(i);
219 auto iter = boundry_dims.find(
id);
220 if (iter == boundry_dims.end())
222 reason = fmt::format(
"Invalid dirichlet boundary id {}",
id);
226 if (s->mesh->dimension() != dim)
228 reason =
"Inconsistent boundary node dimension";
233 for (
int d = 0; d < dim; ++d)
235 if (!iter->second[d])
237 reason = fmt::format(
"Dirichlet boundary id {} has inactive dimensions (not supported)",
id);
248 const std::vector<std::shared_ptr<legacy::State>> &states,
251 assert(!states.empty());
259 int vertex_num = states[0]->mesh->n_vertices();
260 int dim = states[0]->mesh->dimension();
262 for (
auto &s : states)
264 if (s->mesh->n_vertices() != vertex_num)
266 reason =
"Mesh vertex num mismatch between states";
270 if (s->mesh->dimension() != dim)
272 reason =
"Mesh dimension mismatch between states";
276 if (!s->problem->has_nodal_dirichlet())
278 reason =
"Nodal Dirichlet matrix is missing (cannot update nodal Dirichlet values)";
282 for (
int i = 0; i < active_dirichlet_nodes.size(); ++i)
284 int v_in = active_dirichlet_nodes(i);
285 int v = s->in_node_to_node(v_in);
286 if (v < 0 || v >= vertex_num)
288 reason = fmt::format(
"Invalid in_node_to_node mapping: input vertex {} -> {}", v_in, v);
292 int tag = s->mesh->get_node_id(v);
293 if (!s->problem->is_nodal_dirichlet_boundary(v, tag))
295 reason = fmt::format(
"Input vertex {} is not a nodal Dirichlet node", v_in);
299 for (
int d = 0; d < dim; ++d)
301 if (!s->problem->is_nodal_dimension_dirichlet(v, tag, d))
303 reason = fmt::format(
"Nodal Dirichlet at input vertex {} has inactive dimensions (not supported)", v_in);
314 const std::vector<std::shared_ptr<legacy::State>> &states,
317 assert(!states.empty());
319 if (active_boundary_ids.size() == 0)
325 std::unordered_set<int> id_set(active_boundary_ids.begin(), active_boundary_ids.end());
326 if (id_set.size() != active_boundary_ids.size())
328 reason =
"Duplicate pressure boundary id";
332 for (
auto &s : states)
334 for (
auto id : active_boundary_ids)
336 if (!s->problem->is_boundary_pressure(
id))
338 reason = fmt::format(
"Invalid pressure boundary id {}",
id);
bool is_active_dirichlet_node_valid(const Eigen::VectorXi &active_dirichlet_nodes, const std::vector< std::shared_ptr< legacy::State > > &states, std::string &reason)
Validate active Dirichlet node ids selection given states.
bool is_active_time_slices_valid(const Eigen::VectorXi &active_time_slices, const std::vector< std::shared_ptr< legacy::State > > &states, std::string &reason)
Validate active time slices selection given states.
bool is_active_dirichlet_boundary_ids_valid(const Eigen::VectorXi &active_boundary_ids, const std::vector< std::shared_ptr< legacy::State > > &states, std::string &reason)
Validate active Dirichlet boundary ids selection given states.
bool is_active_geom_nodes_valid(const Eigen::VectorXi &active_geom_nodes, const std::vector< std::shared_ptr< legacy::State > > &states, std::string &reason)
Validate active geometry nodes selection given states.
bool is_active_pressure_boundary_ids_valid(const Eigen::VectorXi &active_boundary_ids, const std::vector< std::shared_ptr< legacy::State > > &states, std::string &reason)
Validate active pressure boundary ids selection given states.
bool is_active_dofs_valid(const Eigen::VectorXi &active_dofs, const std::vector< std::shared_ptr< legacy::State > > &states, std::string &reason)
Validate active solution space dofs selection given states.
bool is_active_dims_valid(const Eigen::VectorXi &active_dimensions, const std::vector< std::shared_ptr< legacy::State > > &states, std::string &reason)
Validate active dimensions selection given states.