fix: strengthen validation diagnostics
This commit is contained in:
@@ -124,6 +124,21 @@ std::size_t diagnosticCount(const std::vector<fesa::Diagnostic>& diagnostics, co
|
||||
return count;
|
||||
}
|
||||
|
||||
fesa::Domain singleElementValidationDomain() {
|
||||
fesa::Domain domain;
|
||||
domain.nodes[1] = {1, {0, 0, 0}};
|
||||
domain.nodes[2] = {2, {1, 0, 0}};
|
||||
domain.nodes[3] = {3, {1, 1, 0}};
|
||||
domain.nodes[4] = {4, {0, 1, 0}};
|
||||
domain.elements[1] = {1, fesa::ElementType::MITC4, {1, 2, 3, 4}, "EALL"};
|
||||
domain.element_sets["eall"] = {"EALL", {1}};
|
||||
domain.node_sets["all_nodes"] = {"ALL_NODES", {1, 2, 3, 4}};
|
||||
domain.materials["mat"] = {"MAT", 1000.0, 0.3};
|
||||
domain.shell_sections.push_back({"EALL", "MAT", 0.1});
|
||||
domain.loads.push_back({"2", 3, -1.0});
|
||||
return domain;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
FESA_TEST(core_types_and_dof_mapping_are_stable) {
|
||||
@@ -377,6 +392,102 @@ FESA_TEST(domain_validation_reports_missing_property_and_targets) {
|
||||
}
|
||||
}
|
||||
|
||||
FESA_TEST(domain_validation_reports_missing_sets_and_set_members) {
|
||||
auto domain = singleElementValidationDomain();
|
||||
domain.shell_sections.clear();
|
||||
domain.shell_sections.push_back({"MISSING_ELSET", "MISSING_MAT", 0.1});
|
||||
domain.node_sets["bad_nodes"] = {"BAD_NODES", {1, 99}};
|
||||
domain.element_sets["bad_elements"] = {"BAD_ELEMENTS", {1, 77}};
|
||||
domain.boundary_conditions.push_back({"MISSING_BOUNDARY_SET", 1, 6, 0.0});
|
||||
domain.boundary_conditions.push_back({"BAD_NODES", 1, 1, 0.0});
|
||||
domain.loads.push_back({"MISSING_LOAD_SET", 3, 1.0});
|
||||
domain.loads.push_back({"BAD_NODES", 3, 1.0});
|
||||
|
||||
auto diagnostics = fesa::validateDomain(domain);
|
||||
FESA_CHECK(fesa::containsDiagnostic(diagnostics, "FESA-VALIDATION-MISSING-ELSET"));
|
||||
FESA_CHECK(fesa::containsDiagnostic(diagnostics, "FESA-VALIDATION-MISSING-MATERIAL"));
|
||||
FESA_CHECK(fesa::containsDiagnostic(diagnostics, "FESA-VALIDATION-MISSING-NSET"));
|
||||
FESA_CHECK(fesa::containsDiagnostic(diagnostics, "FESA-VALIDATION-NSET-MISSING-NODE"));
|
||||
FESA_CHECK(fesa::containsDiagnostic(diagnostics, "FESA-VALIDATION-ELSET-MISSING-ELEMENT"));
|
||||
|
||||
const auto* missing_set = findDiagnostic(diagnostics, "FESA-VALIDATION-MISSING-NSET");
|
||||
FESA_CHECK(missing_set != nullptr);
|
||||
FESA_CHECK(missing_set->message.find("MISSING_BOUNDARY_SET") != std::string::npos ||
|
||||
missing_set->message.find("MISSING_LOAD_SET") != std::string::npos);
|
||||
|
||||
const auto* missing_node = findDiagnostic(diagnostics, "FESA-VALIDATION-NSET-MISSING-NODE");
|
||||
FESA_CHECK(missing_node != nullptr);
|
||||
FESA_CHECK(missing_node->message.find("BAD_NODES") != std::string::npos);
|
||||
FESA_CHECK(missing_node->message.find("99") != std::string::npos);
|
||||
}
|
||||
|
||||
FESA_TEST(domain_validation_reports_nonpositive_thickness_and_invalid_dofs) {
|
||||
auto domain = singleElementValidationDomain();
|
||||
domain.shell_sections.front().thickness = 0.0;
|
||||
domain.boundary_conditions.push_back({"ALL_NODES", 0, 1, 0.0});
|
||||
domain.loads.push_back({"2", 7, 1.0});
|
||||
|
||||
auto diagnostics = fesa::validateDomain(domain);
|
||||
FESA_CHECK(fesa::containsDiagnostic(diagnostics, "FESA-VALIDATION-NONPOSITIVE-THICKNESS"));
|
||||
FESA_CHECK(fesa::containsDiagnostic(diagnostics, "FESA-VALIDATION-BOUNDARY-DOF"));
|
||||
FESA_CHECK(fesa::containsDiagnostic(diagnostics, "FESA-VALIDATION-CLOAD-DOF"));
|
||||
|
||||
const auto* thickness = findDiagnostic(diagnostics, "FESA-VALIDATION-NONPOSITIVE-THICKNESS");
|
||||
FESA_CHECK(thickness != nullptr);
|
||||
FESA_CHECK(thickness->message.find("EALL") != std::string::npos);
|
||||
|
||||
const auto* load_dof = findDiagnostic(diagnostics, "FESA-VALIDATION-CLOAD-DOF");
|
||||
FESA_CHECK(load_dof != nullptr);
|
||||
FESA_CHECK(load_dof->message.find("DOF 7") != std::string::npos);
|
||||
}
|
||||
|
||||
FESA_TEST(domain_validation_reports_no_active_elements_and_missing_load) {
|
||||
fesa::Domain domain;
|
||||
domain.nodes[1] = {1, {0, 0, 0}};
|
||||
auto diagnostics = fesa::validateDomain(domain);
|
||||
FESA_CHECK(fesa::containsDiagnostic(diagnostics, "FESA-SINGULAR-NO-ACTIVE-ELEMENTS"));
|
||||
FESA_CHECK(fesa::containsDiagnostic(diagnostics, "FESA-SINGULAR-NO-NONZERO-LOAD"));
|
||||
for (const auto& diagnostic : diagnostics) {
|
||||
FESA_CHECK(diagnostic.code.find("MESH") == std::string::npos);
|
||||
}
|
||||
}
|
||||
|
||||
FESA_TEST(domain_validation_reports_no_free_dofs) {
|
||||
auto domain = singleElementValidationDomain();
|
||||
domain.boundary_conditions.push_back({"ALL_NODES", 1, 6, 0.0});
|
||||
|
||||
auto diagnostics = fesa::validateDomain(domain);
|
||||
const auto* no_free = findDiagnostic(diagnostics, "FESA-SINGULAR-NO-FREE-DOFS");
|
||||
FESA_CHECK(no_free != nullptr);
|
||||
FESA_CHECK(no_free->source.keyword == "dof");
|
||||
FESA_CHECK(no_free->message.find("No free DOFs") != std::string::npos);
|
||||
}
|
||||
|
||||
FESA_TEST(domain_validation_reports_free_untouched_dofs_for_isolated_nodes) {
|
||||
auto domain = singleElementValidationDomain();
|
||||
domain.nodes[99] = {99, {10, 0, 0}};
|
||||
domain.boundary_conditions.push_back({"ALL_NODES", 1, 6, 0.0});
|
||||
|
||||
auto diagnostics = fesa::validateDomain(domain);
|
||||
const auto* untouched = findDiagnostic(diagnostics, "FESA-SINGULAR-DOF-UNTOUCHED");
|
||||
FESA_CHECK(untouched != nullptr);
|
||||
FESA_CHECK(untouched->source.keyword == "dof");
|
||||
FESA_CHECK(untouched->message.find("Node 99") != std::string::npos);
|
||||
FESA_CHECK(untouched->message.find("UX") != std::string::npos);
|
||||
}
|
||||
|
||||
FESA_TEST(domain_validation_reports_weak_drilling_dof_smoke) {
|
||||
auto domain = singleElementValidationDomain();
|
||||
domain.boundary_conditions.push_back({"ALL_NODES", 1, 5, 0.0});
|
||||
|
||||
auto diagnostics = fesa::validateDomain(domain);
|
||||
const auto* weak_drilling = findDiagnostic(diagnostics, "FESA-SINGULAR-WEAK-DRILLING-DOF");
|
||||
FESA_CHECK(weak_drilling != nullptr);
|
||||
FESA_CHECK(weak_drilling->severity == fesa::Severity::Warning);
|
||||
FESA_CHECK(weak_drilling->source.keyword == "dof");
|
||||
FESA_CHECK(weak_drilling->message.find("RZ") != std::string::npos);
|
||||
}
|
||||
|
||||
FESA_TEST(dof_manager_owns_equation_numbering_and_reconstruction) {
|
||||
auto domain = parsedPhase1Domain();
|
||||
fesa::DofManager dofs(domain);
|
||||
|
||||
Reference in New Issue
Block a user