FEM: Ensure finite frame values only. Fixes #20933

This commit is contained in:
Stefan Tröger
2025-04-25 19:41:00 +02:00
parent ea6c95a870
commit 642eff1663
3 changed files with 49 additions and 15 deletions

View File

@@ -23,6 +23,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <cmath>
#include <Python.h>
#include <vtkAppendFilter.h>
#include <vtkDataSetReader.h>
@@ -313,10 +314,23 @@ void FemPostPipeline::read(std::vector<Base::FileInfo>& files,
std::string& frame_type)
{
if (files.size() != values.size()) {
Base::Console().Error("Result files and frame values have different length.\n");
return;
throw Base::ValueError("Result files and frame values have different length");
}
// make sure we do not have invalid values
for (auto& value : values) {
if (!std::isfinite(value)) {
throw Base::ValueError("Values need to be finite");
}
}
// ensure no double values for frames
std::set<double> value_set(values.begin(), values.end());
if (value_set.size() != values.size()) {
throw Base::ValueError("Values need to be unique");
}
// setup the time information for the multiblock
vtkStringArray* TimeInfo = vtkStringArray::New();
TimeInfo->SetName("TimeInfo");
@@ -650,8 +664,20 @@ void FemPostPipeline::load(std::vector<FemResultObject*>& res,
{
if (res.size() != values.size()) {
Base::Console().Error("Result values and frame values have different length.\n");
return;
throw Base::ValueError("Result values and frame values have different length");
}
// make sure we do not have invalid values
for (auto& value : values) {
if (!std::isfinite(value)) {
throw Base::ValueError("Values need to be finite");
}
}
// ensure no double values for frames
std::set<double> value_set(values.begin(), values.end());
if (value_set.size() != values.size()) {
throw Base::ValueError("Values need to be unique");
}
// setup the time information for the multiblock
@@ -664,8 +690,7 @@ void FemPostPipeline::load(std::vector<FemResultObject*>& res,
for (ulong i = 0; i < res.size(); i++) {
if (!res[i]->Mesh.getValue()->isDerivedFrom<FemMeshObject>()) {
Base::Console().Error("Result mesh object is not derived from Fem::FemMeshObject.\n");
return;
throw Base::ValueError("Result mesh object is not derived from Fem::FemMeshObject");
}
// first copy the mesh over

View File

@@ -172,7 +172,8 @@ PyObject* FemPostPipelinePy::load(PyObject* args)
std::string error = std::string(
"Result and value must be list of ResultObject and number respectively.");
throw Base::TypeError(error);
PyErr_SetString(PyExc_TypeError, error.c_str());
return nullptr;
}
// extract the result objects
@@ -186,11 +187,15 @@ PyObject* FemPostPipelinePy::load(PyObject* args)
if (!PyObject_TypeCheck(*item, &(DocumentObjectPy::Type))) {
std::string error =
std::string("type in result list must be 'ResultObject', not ");
throw Base::TypeError(error);
PyErr_SetString(PyExc_TypeError, error.c_str());
return nullptr;
}
auto obj = static_cast<DocumentObjectPy*>(*item)->getDocumentObjectPtr();
if (!obj->isDerivedFrom<FemResultObject>()) {
throw Base::TypeError("object is not a result object");
std::string error =
std::string("type in result list must be 'ResultObject', not ");
PyErr_SetString(PyExc_TypeError, error.c_str());
return nullptr;
}
results[i] = static_cast<FemResultObject*>(obj);
}
@@ -202,12 +207,12 @@ PyObject* FemPostPipelinePy::load(PyObject* args)
values.resize(size);
for (Py::Sequence::size_type i = 0; i < size; i++) {
Py::Object item = values_list[i];
if (!PyFloat_Check(*item)) {
std::string error = std::string("Values must be float");
throw Base::TypeError(error);
Py::Object value = values_list[i];
if (!value.isNumeric()) {
PyErr_SetString(PyExc_TypeError, "Values must be numbers");
return nullptr;
}
values[i] = PyFloat_AsDouble(*item);
values[i] = Py::Float(value).as_double();
}
// extract the unit
@@ -223,7 +228,8 @@ PyObject* FemPostPipelinePy::load(PyObject* args)
else {
std::string error = std::string(
"Multistep load requires 4 arguments: ResultList, ValueList, unit, type");
throw Base::TypeError(error);
PyErr_SetString(PyExc_ValueError, error.c_str());
return nullptr;
}
}
return nullptr;

View File

@@ -32,6 +32,7 @@ __url__ = "https://www.freecad.org"
# \brief FreeCAD Calculix FRD Reader for FEM workbench
import os
import math
import FreeCAD
from FreeCAD import Console
@@ -133,6 +134,8 @@ def importFrd(filename, analysis=None, result_name_prefix="", result_analysis_ty
else:
eigenmode_number = 0
step_time = result_set["time"]
if not math.isfinite(step_time):
step_time = 0
step_time = round(step_time, 2)
if eigenmode_number > 0:
results_name = "{}EigenMode_{}_Results".format(