From 45743d4fbdf4f04b0d8f6909db29db137b3ffda7 Mon Sep 17 00:00:00 2001 From: Uwe Date: Wed, 22 Mar 2023 18:02:35 +0100 Subject: [PATCH] [FEM] improve displacement constraint - use a Distance and Angle property to get the unit handling right --- src/Mod/Fem/App/FemConstraint.h | 1 + src/Mod/Fem/App/FemConstraintDisplacement.cpp | 39 ++++++++ src/Mod/Fem/App/FemConstraintDisplacement.h | 16 +-- .../Fem/Gui/TaskFemConstraintDisplacement.cpp | 76 +++++++++------ .../Fem/Gui/TaskFemConstraintDisplacement.h | 37 +++---- .../Fem/Gui/TaskFemConstraintDisplacement.ui | 97 ++++++++++++------- .../calculix/write_constraint_displacement.py | 38 ++++++-- .../elmer/equations/deformation_writer.py | 6 +- .../elmer/equations/elasticity_writer.py | 6 +- .../ccx_cantilever_prescribeddisplacement.inp | 2 +- 10 files changed, 215 insertions(+), 103 deletions(-) diff --git a/src/Mod/Fem/App/FemConstraint.h b/src/Mod/Fem/App/FemConstraint.h index ea98a77f39..f9696a2439 100644 --- a/src/Mod/Fem/App/FemConstraint.h +++ b/src/Mod/Fem/App/FemConstraint.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/src/Mod/Fem/App/FemConstraintDisplacement.cpp b/src/Mod/Fem/App/FemConstraintDisplacement.cpp index d7ba4b5535..6af0ceee9a 100644 --- a/src/Mod/Fem/App/FemConstraintDisplacement.cpp +++ b/src/Mod/Fem/App/FemConstraintDisplacement.cpp @@ -104,6 +104,45 @@ const char* ConstraintDisplacement::getViewProviderName() const return "FemGui::ViewProviderFemConstraintDisplacement"; } +void ConstraintDisplacement::handleChangedPropertyType(Base::XMLReader& reader, + const char* TypeName, + App::Property* prop) +{ + // properties _Displacement had App::PropertyFloat and were changed to App::PropertyDistance + if (prop == &xDisplacement && strcmp(TypeName, "App::PropertyFloat") == 0) { + App::PropertyDistance xDisplacementProperty; + // restore the PropertyFloat to be able to set its value + xDisplacementProperty.Restore(reader); + xDisplacement.setValue(xDisplacementProperty.getValue()); + } + else if (prop == &yDisplacement && strcmp(TypeName, "App::PropertyFloat") == 0) { + App::PropertyDistance yDisplacementProperty; + yDisplacementProperty.Restore(reader); + yDisplacement.setValue(yDisplacementProperty.getValue()); + } + else if (prop == &zDisplacement && strcmp(TypeName, "App::PropertyFloat") == 0) { + App::PropertyDistance zDisplacementProperty; + zDisplacementProperty.Restore(reader); + zDisplacement.setValue(zDisplacementProperty.getValue()); + } + // properties _Displacement had App::PropertyFloat and were changed to App::PropertyAngle + else if (prop == &xRotation && strcmp(TypeName, "App::PropertyFloat") == 0) { + App::PropertyDistance xRotationProperty; + xRotationProperty.Restore(reader); + xRotation.setValue(xRotationProperty.getValue()); + } + else if (prop == &yRotation && strcmp(TypeName, "App::PropertyFloat") == 0) { + App::PropertyDistance yRotationProperty; + yRotationProperty.Restore(reader); + yRotation.setValue(yRotationProperty.getValue()); + } + else if (prop == &zRotation && strcmp(TypeName, "App::PropertyFloat") == 0) { + App::PropertyDistance zRotationProperty; + zRotationProperty.Restore(reader); + zRotation.setValue(zRotationProperty.getValue()); + } +} + void ConstraintDisplacement::onChanged(const App::Property* prop) { // Note: If we call this at the end, then the arrows are not oriented correctly initially diff --git a/src/Mod/Fem/App/FemConstraintDisplacement.h b/src/Mod/Fem/App/FemConstraintDisplacement.h index 6bdf853f6a..4ce17ce7ab 100644 --- a/src/Mod/Fem/App/FemConstraintDisplacement.h +++ b/src/Mod/Fem/App/FemConstraintDisplacement.h @@ -23,12 +23,12 @@ * * ***************************************************************************/ - #ifndef FEM_CONSTRAINTDISPLACEMENT_H #define FEM_CONSTRAINTDISPLACEMENT_H #include "FemConstraint.h" + namespace Fem { @@ -45,12 +45,12 @@ public: App::PropertyVectorList Normals; //Displacement parameters - App::PropertyFloat xDisplacement; - App::PropertyFloat yDisplacement; - App::PropertyFloat zDisplacement; - App::PropertyFloat xRotation; - App::PropertyFloat yRotation; - App::PropertyFloat zRotation; + App::PropertyDistance xDisplacement; + App::PropertyDistance yDisplacement; + App::PropertyDistance zDisplacement; + App::PropertyAngle xRotation; + App::PropertyAngle yRotation; + App::PropertyAngle zRotation; App::PropertyString xDisplacementFormula; App::PropertyString yDisplacementFormula; App::PropertyString zDisplacementFormula; @@ -78,6 +78,8 @@ public: const char* getViewProviderName() const override; protected: + void handleChangedPropertyType(Base::XMLReader& reader, const char* TypeName, + App::Property* prop) override; void onChanged(const App::Property* prop) override; }; diff --git a/src/Mod/Fem/Gui/TaskFemConstraintDisplacement.cpp b/src/Mod/Fem/Gui/TaskFemConstraintDisplacement.cpp index f641efc618..e206c141f6 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintDisplacement.cpp +++ b/src/Mod/Fem/Gui/TaskFemConstraintDisplacement.cpp @@ -82,15 +82,15 @@ TaskFemConstraintDisplacement::TaskFemConstraintDisplacement( // Get the feature data Fem::ConstraintDisplacement* pcConstraint = static_cast(ConstraintView->getObject()); - double fStates[6] {}; + Base::Quantity fStates[6] {}; const char* sStates[3] {}; bool bStates[16] {}; - fStates[0] = pcConstraint->xDisplacement.getValue(); - fStates[1] = pcConstraint->yDisplacement.getValue(); - fStates[2] = pcConstraint->zDisplacement.getValue(); - fStates[3] = pcConstraint->xRotation.getValue(); - fStates[4] = pcConstraint->yRotation.getValue(); - fStates[5] = pcConstraint->zRotation.getValue(); + fStates[0] = pcConstraint->xDisplacement.getQuantityValue(); + fStates[1] = pcConstraint->yDisplacement.getQuantityValue(); + fStates[2] = pcConstraint->zDisplacement.getQuantityValue(); + fStates[3] = pcConstraint->xRotation.getQuantityValue(); + fStates[4] = pcConstraint->yRotation.getQuantityValue(); + fStates[5] = pcConstraint->zRotation.getQuantityValue(); sStates[0] = pcConstraint->xDisplacementFormula.getValue(); sStates[1] = pcConstraint->yDisplacementFormula.getValue(); sStates[2] = pcConstraint->zDisplacementFormula.getValue(); @@ -170,6 +170,14 @@ TaskFemConstraintDisplacement::TaskFemConstraintDisplacement( buttonGroup->addButton(ui->btnAdd, (int)SelectionChangeModes::refAdd); buttonGroup->addButton(ui->btnRemove, (int)SelectionChangeModes::refRemove); + // Bind input fields to properties + ui->spinxDisplacement->bind(pcConstraint->xDisplacement); + ui->spinyDisplacement->bind(pcConstraint->yDisplacement); + ui->spinzDisplacement->bind(pcConstraint->zDisplacement); + ui->spinxRotation->bind(pcConstraint->xRotation); + ui->spinyRotation->bind(pcConstraint->yRotation); + ui->spinzRotation->bind(pcConstraint->zRotation); + updateUI(); } @@ -432,34 +440,34 @@ const std::string TaskFemConstraintDisplacement::getReferences() const return TaskFemConstraint::getReferences(items); } -double TaskFemConstraintDisplacement::get_spinxDisplacement() const +std::string TaskFemConstraintDisplacement::get_spinxDisplacement() const { - return ui->spinxDisplacement->value(); + return ui->spinxDisplacement->value().getSafeUserString().toStdString(); } -double TaskFemConstraintDisplacement::get_spinyDisplacement() const +std::string TaskFemConstraintDisplacement::get_spinyDisplacement() const { - return ui->spinyDisplacement->value(); + return ui->spinyDisplacement->value().getSafeUserString().toStdString(); } -double TaskFemConstraintDisplacement::get_spinzDisplacement() const +std::string TaskFemConstraintDisplacement::get_spinzDisplacement() const { - return ui->spinzDisplacement->value(); + return ui->spinzDisplacement->value().getSafeUserString().toStdString(); } -double TaskFemConstraintDisplacement::get_spinxRotation() const +std::string TaskFemConstraintDisplacement::get_spinxRotation() const { - return ui->spinxRotation->value(); + return ui->spinxRotation->value().getSafeUserString().toStdString(); } -double TaskFemConstraintDisplacement::get_spinyRotation() const +std::string TaskFemConstraintDisplacement::get_spinyRotation() const { - return ui->spinyRotation->value(); + return ui->spinyRotation->value().getSafeUserString().toStdString(); } -double TaskFemConstraintDisplacement::get_spinzRotation() const +std::string TaskFemConstraintDisplacement::get_spinzRotation() const { - return ui->spinzRotation->value(); + return ui->spinzRotation->value().getSafeUserString().toStdString(); } std::string TaskFemConstraintDisplacement::get_xFormula() const @@ -625,27 +633,31 @@ bool TaskDlgFemConstraintDisplacement::accept() static_cast(parameter); try { - Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.xDisplacement = %f", - name.c_str(), parameterDisplacement->get_spinxDisplacement()); + Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.xDisplacement = \"%s\"", + name.c_str(), + parameterDisplacement->get_spinxDisplacement().c_str()); Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.xDisplacementFormula = \"%s\"", name.c_str(), parameterDisplacement->get_xFormula().c_str()); - Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.yDisplacement = %f", - name.c_str(), parameterDisplacement->get_spinyDisplacement()); + Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.yDisplacement = \"%s\"", + name.c_str(), + parameterDisplacement->get_spinyDisplacement().c_str()); Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.yDisplacementFormula = \"%s\"", name.c_str(), parameterDisplacement->get_yFormula().c_str()); - Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.zDisplacement = %f", - name.c_str(), parameterDisplacement->get_spinzDisplacement()); + Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.zDisplacement = \"%s\"", + name.c_str(), + parameterDisplacement->get_spinzDisplacement().c_str()); Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.zDisplacementFormula = \"%s\"", name.c_str(), parameterDisplacement->get_zFormula().c_str()); - Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.xRotation = %f", - name.c_str(), parameterDisplacement->get_spinxRotation()); - Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.yRotation = %f", - name.c_str(), parameterDisplacement->get_spinyRotation()); - Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.zRotation = %f", - name.c_str(), parameterDisplacement->get_spinzRotation()); + Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.xRotation = \"%s\"", + name.c_str(), parameterDisplacement->get_spinxRotation().c_str()); + Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.yRotation = \"%s\"", + name.c_str(), parameterDisplacement->get_spinyRotation().c_str()); + Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.zRotation = \"%s\"", + name.c_str(), + parameterDisplacement->get_spinzRotation().c_str()); Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.xFree = %s", name.c_str(), parameterDisplacement->get_dispxfree() ? "True" : "False"); @@ -696,7 +708,7 @@ bool TaskDlgFemConstraintDisplacement::accept() name.c_str(), parameterDisplacement->get_useFlowSurfaceForce() ? "True" : "False"); - + std::string scale = parameterDisplacement->getScale();// OvG: determine modified scale Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.Scale = %s", diff --git a/src/Mod/Fem/Gui/TaskFemConstraintDisplacement.h b/src/Mod/Fem/Gui/TaskFemConstraintDisplacement.h index 991a73b198..e62b123c2e 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintDisplacement.h +++ b/src/Mod/Fem/Gui/TaskFemConstraintDisplacement.h @@ -48,31 +48,32 @@ public: explicit TaskFemConstraintDisplacement(ViewProviderFemConstraintDisplacement* ConstraintView, QWidget* parent = nullptr); ~TaskFemConstraintDisplacement() override; + const std::string getReferences() const override; - double get_spinxDisplacement()const; - double get_spinyDisplacement()const; - double get_spinzDisplacement()const; - double get_spinxRotation()const; - double get_spinyRotation()const; - double get_spinzRotation()const; + std::string get_spinxDisplacement() const; + std::string get_spinyDisplacement() const; + std::string get_spinzDisplacement() const; + std::string get_spinxRotation() const; + std::string get_spinyRotation() const; + std::string get_spinzRotation() const; std::string get_xFormula() const; std::string get_yFormula() const; std::string get_zFormula() const; - bool get_dispxfix()const; - bool get_dispxfree()const; + bool get_dispxfix() const; + bool get_dispxfree() const; bool get_hasDispXFormula() const; - bool get_dispyfix()const; - bool get_dispyfree()const; + bool get_dispyfix() const; + bool get_dispyfree() const; bool get_hasDispYFormula() const; - bool get_dispzfix()const; - bool get_dispzfree()const; + bool get_dispzfix() const; + bool get_dispzfree() const; bool get_hasDispZFormula() const; - bool get_rotxfix()const; - bool get_rotxfree()const; - bool get_rotyfix()const; - bool get_rotyfree()const; - bool get_rotzfix()const; - bool get_rotzfree()const; + bool get_rotxfix() const; + bool get_rotxfree() const; + bool get_rotyfix() const; + bool get_rotyfree() const; + bool get_rotzfix() const; + bool get_rotzfree() const; bool get_useFlowSurfaceForce() const; private Q_SLOTS: diff --git a/src/Mod/Fem/Gui/TaskFemConstraintDisplacement.ui b/src/Mod/Fem/Gui/TaskFemConstraintDisplacement.ui index 6446200353..72134293ac 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintDisplacement.ui +++ b/src/Mod/Fem/Gui/TaskFemConstraintDisplacement.ui @@ -10,7 +10,7 @@ 0 0 300 - 617 + 649 @@ -110,8 +110,8 @@ true - - + + @@ -120,10 +120,7 @@ - - - - + Formulas are only valid @@ -134,6 +131,13 @@ for the Emer solver + + + + mm + + + @@ -146,8 +150,19 @@ for the Emer solver true - - + + + + + + + Formulas are only valid +for the Emer solver + + + Formula + + @@ -156,17 +171,10 @@ for the Emer solver - - - - - - - Formulas are only valid -for the Emer solver - - - Formula + + + + mm @@ -182,8 +190,8 @@ for the Emer solver true - - + + @@ -192,10 +200,7 @@ for the Emer solver - - - - + Formulas are only valid @@ -206,6 +211,13 @@ for the Emer solver + + + + mm + + + @@ -265,7 +277,11 @@ generated by the flow - + + + deg + + @@ -279,9 +295,6 @@ generated by the flow true - - - @@ -289,6 +302,13 @@ generated by the flow + + + + deg + + + @@ -301,9 +321,6 @@ generated by the flow true - - - @@ -311,11 +328,25 @@ generated by the flow + + + + deg + + + + + + Gui::QuantitySpinBox + QWidget +
Gui/QuantitySpinBox.h
+
+
diff --git a/src/Mod/Fem/femsolver/calculix/write_constraint_displacement.py b/src/Mod/Fem/femsolver/calculix/write_constraint_displacement.py index e9f932ca20..6c30323691 100644 --- a/src/Mod/Fem/femsolver/calculix/write_constraint_displacement.py +++ b/src/Mod/Fem/femsolver/calculix/write_constraint_displacement.py @@ -25,6 +25,8 @@ __title__ = "FreeCAD FEM calculix constraint displacement" __author__ = "Bernd Hahnebach" __url__ = "https://www.freecadweb.org" +import FreeCAD + def get_analysis_types(): return "all" # write for all analysis types @@ -68,26 +70,50 @@ def write_constraint(f, femobj, disp_obj, ccxwriter): if disp_obj.xFix: f.write("{},1\n".format(disp_obj.Name)) elif not disp_obj.xFree: - f.write("{},1,1,{:.13G}\n".format(disp_obj.Name, disp_obj.xDisplacement)) + f.write( + "{},1,1,{}\n".format( + disp_obj.Name, FreeCAD.Units.Quantity(disp_obj.xDisplacement.getValueAs("mm")) + ) + ) if disp_obj.yFix: f.write("{},2\n".format(disp_obj.Name)) elif not disp_obj.yFree: - f.write("{},2,2,{:.13G}\n".format(disp_obj.Name, disp_obj.yDisplacement)) + f.write( + "{},2,2,{}\n".format( + disp_obj.Name, FreeCAD.Units.Quantity(disp_obj.yDisplacement.getValueAs("mm")) + ) + ) if disp_obj.zFix: f.write("{},3\n".format(disp_obj.Name)) elif not disp_obj.zFree: - f.write("{},3,3,{:.13G}\n".format(disp_obj.Name, disp_obj.zDisplacement)) + f.write( + "{},3,3,{}\n".format( + disp_obj.Name, FreeCAD.Units.Quantity(disp_obj.zDisplacement.getValueAs("mm")) + ) + ) if ccxwriter.member.geos_beamsection or ccxwriter.member.geos_shellthickness: if disp_obj.rotxFix: f.write("{},4\n".format(disp_obj.Name)) elif not disp_obj.rotxFree: - f.write("{},4,4,{:.13G}\n".format(disp_obj.Name, disp_obj.xRotation)) + f.write( + "{},4,4,{}\n".format( + disp_obj.Name, FreeCAD.Units.Quantity(disp_obj.xRotation.getValueAs("deg")) + ) + ) if disp_obj.rotyFix: f.write("{},5\n".format(disp_obj.Name)) elif not disp_obj.rotyFree: - f.write("{},5,5,{:.13G}\n".format(disp_obj.Name, disp_obj.yRotation)) + f.write( + "{},5,5,{}\n".format( + disp_obj.Name, FreeCAD.Units.Quantity(disp_obj.yRotation.getValueAs("deg")) + ) + ) if disp_obj.rotzFix: f.write("{},6\n".format(disp_obj.Name)) elif not disp_obj.rotzFree: - f.write("{},6,6,{:.13G}\n".format(disp_obj.Name, disp_obj.zRotation)) + f.write( + "{},6,6,{}\n".format( + disp_obj.Name, FreeCAD.Units.Quantity(disp_obj.zRotation.getValueAs("deg")) + ) + ) diff --git a/src/Mod/Fem/femsolver/elmer/equations/deformation_writer.py b/src/Mod/Fem/femsolver/elmer/equations/deformation_writer.py index a0bdb56ec0..10717cad56 100644 --- a/src/Mod/Fem/femsolver/elmer/equations/deformation_writer.py +++ b/src/Mod/Fem/femsolver/elmer/equations/deformation_writer.py @@ -113,19 +113,19 @@ class DeformationWriter: continue if not obj.xFree: if not obj.hasXFormula: - displacement = obj.xDisplacement * 0.001 + displacement = float(obj.xDisplacement.getValueAs("m")) else: displacement = obj.xDisplacementFormula self.write.boundary(name, "Displacement 1", displacement) if not obj.yFree: if not obj.hasYFormula: - displacement = obj.yDisplacement * 0.001 + displacement = float(obj.yDisplacement.getValueAs("m")) else: displacement = obj.yDisplacementFormula self.write.boundary(name, "Displacement 2", displacement) if not obj.zFree: if not obj.hasZFormula: - displacement = obj.zDisplacement * 0.001 + displacement = float(obj.zDisplacement.getValueAs("m")) else: displacement = obj.zDisplacementFormula self.write.boundary(name, "Displacement 3", displacement) diff --git a/src/Mod/Fem/femsolver/elmer/equations/elasticity_writer.py b/src/Mod/Fem/femsolver/elmer/equations/elasticity_writer.py index 7f09be1df1..1e931fe3c6 100644 --- a/src/Mod/Fem/femsolver/elmer/equations/elasticity_writer.py +++ b/src/Mod/Fem/femsolver/elmer/equations/elasticity_writer.py @@ -329,19 +329,19 @@ class ElasticityWriter: continue if not obj.xFree: if not obj.hasXFormula: - displacement = obj.xDisplacement * 0.001 + displacement = float(obj.xDisplacement.getValueAs("m")) else: displacement = obj.xDisplacementFormula self.write.boundary(name, "Displacement 1", displacement) if not obj.yFree: if not obj.hasYFormula: - displacement = obj.yDisplacement * 0.001 + displacement = float(obj.yDisplacement.getValueAs("m")) else: displacement = obj.yDisplacementFormula self.write.boundary(name, "Displacement 2", displacement) if not obj.zFree: if not obj.hasZFormula: - displacement = obj.zDisplacement * 0.001 + displacement = float(obj.zDisplacement.getValueAs("m")) else: displacement = obj.zDisplacementFormula self.write.boundary(name, "Displacement 3", displacement) diff --git a/src/Mod/Fem/femtest/data/calculix/ccx_cantilever_prescribeddisplacement.inp b/src/Mod/Fem/femtest/data/calculix/ccx_cantilever_prescribeddisplacement.inp index 9d9d464b72..f803012856 100644 --- a/src/Mod/Fem/femtest/data/calculix/ccx_cantilever_prescribeddisplacement.inp +++ b/src/Mod/Fem/femtest/data/calculix/ccx_cantilever_prescribeddisplacement.inp @@ -394,7 +394,7 @@ ConstraintFixed,3 ** Displacement constraint applied ** ConstraintDisplacmentPrescribed *BOUNDARY -ConstraintDisplacmentPrescribed,3,3,-250 +ConstraintDisplacmentPrescribed,3,3,-250.0 ***********************************************************