fix: tighten thermal input diagnostics

This commit is contained in:
KOKO\Mimi
2026-09-29 20:18:00 +09:00
parent 71b85379cd
commit ba57a469c7
2 changed files with 45 additions and 5 deletions
+28 -5
View File
@@ -1639,6 +1639,11 @@ class DomainMappingContext::Impl {
}
void ParseElastic(const KeywordBlock& block) {
if (model_element_family_ == ElementFamily::kThermalShell) {
InputFailure("unsupported-keyword", block.location, block.canonical_name,
"", "ELASTIC is outside the thermal material subset.");
return;
}
if (!material_eligible_) {
InputFailure("invalid-keyword-location", block.location,
block.canonical_name, "",
@@ -2564,6 +2569,13 @@ class DomainMappingContext::Impl {
"HEAT TRANSFER accepts only END=PERIOD.");
return;
}
if (block.data[0].fields.size() > 5U) {
InputFailure(
"invalid-thermal-time-grid", block.data[0].location,
block.canonical_name, "",
"HEAT TRANSFER permits at most three trailing empty fields.");
return;
}
const auto fields = WithoutTrailingEmpty(block.data[0].fields);
if (fields.size() != 2U) {
InputFailure("invalid-thermal-time-grid", block.data[0].location,
@@ -2631,8 +2643,9 @@ class DomainMappingContext::Impl {
"PERTURBATION is supported only with FREQUENCY.");
return;
}
if (step_.has_static || !ValidateParameters(block, {}) ||
block.data.size() != 1U || block.data[0].fields.size() != 4U) {
if (step_.has_heat_transfer || step_.has_static ||
!ValidateParameters(block, {}) || block.data.size() != 1U ||
block.data[0].fields.size() != 4U) {
if (!failure_) {
InputFailure(step_.nlgeom ? "invalid-nonlinear-static-data"
: "invalid-static-data",
@@ -2740,6 +2753,12 @@ class DomainMappingContext::Impl {
}
void ParseOutputChild(const KeywordBlock& block) {
if (step_.has_heat_transfer) {
InputFailure("unsupported-keyword", block.location, block.canonical_name,
"",
"Thermal output children are outside the approved subset.");
return;
}
if (!active_output_) {
InputFailure(
"invalid-keyword-location", block.location, block.canonical_name, "",
@@ -2918,10 +2937,14 @@ class DomainMappingContext::Impl {
if (model_element_family_ == ElementFamily::kThermalShell) {
for (const auto& block : input_.blocks) {
if (block.canonical_name != "PREPRINT") continue;
if (!ValidateParameters(block,
{"ECHO", "MODEL", "HISTORY", "CONTACT"}) ||
block.parameters.size() != 4U)
if (!ValidateParameters(block, {"ECHO", "MODEL", "HISTORY", "CONTACT"}))
return;
if (block.parameters.size() != 4U) {
InputFailure("unsupported-keyword", block.location,
block.canonical_name, "",
"Thermal PREPRINT requires four NO parameters.");
return;
}
for (const auto& parameter : block.parameters) {
if (!parameter.value ||
!AsciiCaseInsensitiveEquals(*parameter.value, "NO")) {
@@ -147,6 +147,7 @@ TEST(ThermalDomainMapping, RejectsThermalMaterialAndControlForms) {
{"7850.,\n", "-1.,\n"},
{"*Conductivity\n", "*Conductivity, dependencies=1\n"},
{"*Specific Heat\n460.,\n", ""},
{"*Specific Heat\n460.,\n", "*Specific Heat\n460.,\n*Elastic\n1., .3\n"},
{"*Heat Transfer\n1., 100.\n",
"*Heat Transfer, steady state\n1., 100.\n"},
{"*Heat Transfer\n1., 100.\n", "*Heat Transfer\n0., 100.\n"},
@@ -163,6 +164,22 @@ TEST(ThermalDomainMapping, RejectsThermalMaterialAndControlForms) {
}
}
TEST(ThermalDomainMapping, RejectsThermalNoOpAndProcedureViolations) {
const std::vector<std::pair<std::string, std::string>> cases{
{"*Part, name=P",
"*Preprint, echo=NO, model=NO, history=NO\n*Part, name=P"},
{"1., 100.\n", "1., 100., , , ,\n"},
{"*Cflux", "*Static\n.1, 1., .1, 1.\n*Cflux"},
{"*End Step", "*Output, field\n*Node Output\nNT\n*End Step"}};
for (const auto& test_case : cases) {
auto deck = ThermalDeck();
const auto position = deck.find(test_case.first);
ASSERT_NE(position, std::string::npos);
deck.replace(position, test_case.first.size(), test_case.second);
EXPECT_FALSE(MapText(deck).HasValue());
}
}
TEST(ThermalDomainMapping, AppliesSameDofStepOverrideAndDefaultValues) {
auto deck = ThermalDeck();
const auto first = deck.find("Bottom, 15, 15, 30.");