From 0a6a7155e59d307ddfe85935b9d0d25e67571d70 Mon Sep 17 00:00:00 2001 From: Ajinkya Dahale Date: Wed, 2 Nov 2022 17:20:07 +0530 Subject: [PATCH] FEM: Add rigid body constraint to ccx writer --- src/Mod/Fem/CMakeLists.txt | 1 + src/Mod/Fem/ObjectsFem.py | 10 ++ src/Mod/Fem/femmesh/meshsetsgetter.py | 16 +++ .../calculix/write_constraint_rigidbody.py | 105 ++++++++++++++++++ src/Mod/Fem/femsolver/calculix/writer.py | 3 + src/Mod/Fem/femtools/membertools.py | 7 ++ 6 files changed, 142 insertions(+) create mode 100644 src/Mod/Fem/femsolver/calculix/write_constraint_rigidbody.py diff --git a/src/Mod/Fem/CMakeLists.txt b/src/Mod/Fem/CMakeLists.txt index 91ed22746b..365e208dc7 100755 --- a/src/Mod/Fem/CMakeLists.txt +++ b/src/Mod/Fem/CMakeLists.txt @@ -231,6 +231,7 @@ SET(FemSolverCalculix_SRCS femsolver/calculix/write_constraint_initialtemperature.py femsolver/calculix/write_constraint_planerotation.py femsolver/calculix/write_constraint_pressure.py + femsolver/calculix/write_constraint_rigidbody.py femsolver/calculix/write_constraint_sectionprint.py femsolver/calculix/write_constraint_selfweight.py femsolver/calculix/write_constraint_temperature.py diff --git a/src/Mod/Fem/ObjectsFem.py b/src/Mod/Fem/ObjectsFem.py index c1e6deb951..40f73d3945 100644 --- a/src/Mod/Fem/ObjectsFem.py +++ b/src/Mod/Fem/ObjectsFem.py @@ -173,6 +173,16 @@ def makeConstraintFixed( return obj +def makeConstraintRigidBody( + doc, + name="ConstraintRigidBody" +): + """makeConstraintRigidBody(document, [name]): + makes a Fem ConstraintRigidBody object""" + obj = doc.addObject("Fem::ConstraintRigidBody", name) + return obj + + def makeConstraintFlowVelocity( doc, name="ConstraintFlowVelocity" diff --git a/src/Mod/Fem/femmesh/meshsetsgetter.py b/src/Mod/Fem/femmesh/meshsetsgetter.py index 4ef2b31702..c84b2b31b0 100644 --- a/src/Mod/Fem/femmesh/meshsetsgetter.py +++ b/src/Mod/Fem/femmesh/meshsetsgetter.py @@ -139,6 +139,7 @@ class MeshSetsGetter(): # constraints node sets getter self.get_constraints_fixed_nodes() self.get_constraints_displacement_nodes() + self.get_constraints_rigidbody_nodes() self.get_constraints_planerotation_nodes() # constraints surface sets getter @@ -205,6 +206,21 @@ class MeshSetsGetter(): femobj["NodesSolid"] = set(nds_solid) femobj["NodesFaceEdge"] = set(nds_faceedge) + def get_constraints_rigidbody_nodes(self): + if not self.member.cons_rigidbody: + return + # get nodes + for femobj in self.member.cons_rigidbody: + # femobj --> dict, FreeCAD document object is femobj["Object"] + print_obj_info(femobj["Object"]) + femobj["Nodes"] = meshtools.get_femnodes_by_femobj_with_references( + self.femmesh, + femobj + ) + # add nodes to constraint_conflict_nodes, needed by constraint plane rotation + for node in femobj["Nodes"]: + self.constraint_conflict_nodes.append(node) + def get_constraints_displacement_nodes(self): if not self.member.cons_displacement: return diff --git a/src/Mod/Fem/femsolver/calculix/write_constraint_rigidbody.py b/src/Mod/Fem/femsolver/calculix/write_constraint_rigidbody.py new file mode 100644 index 0000000000..26169e4098 --- /dev/null +++ b/src/Mod/Fem/femsolver/calculix/write_constraint_rigidbody.py @@ -0,0 +1,105 @@ +# *************************************************************************** +# * Copyright (c) 2022 Ajinkya Dahale * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +__title__ = "FreeCAD FEM calculix constraint rigid body" +__author__ = "Ajinkya Dahale" +__url__ = "https://www.freecadweb.org" + + +def get_analysis_types(): + return "all" # write for all analysis types + + +def get_sets_name(): + return "constraints_rigidbody_node_sets" + + +def get_constraint_title(): + return "Rigid Body Constraints" + + +def get_before_write_meshdata_constraint(): + return "" + + +def get_after_write_meshdata_constraint(): + return "" + + +def get_before_write_constraint(): + return "" + + +def get_after_write_constraint(): + return "" + + +def write_meshdata_constraint(f, femobj, rb_obj, ccxwriter): + f.write("*NSET,NSET=" + rb_obj.Name + "\n") + for n in femobj["Nodes"]: + f.write("{},\n".format(n)) + + +def write_constraint(f, femobj, rb_obj, ccxwriter): + + # floats read from ccx should use {:.13G}, see comment in writer module + is_ref_bc_defined = any((rb_obj.xDisplacement, + rb_obj.yDisplacement, + rb_obj.zDisplacement, + rb_obj.xLoad, + rb_obj.yLoad, + rb_obj.zLoad)) + + is_rot_bc_defined = any((rb_obj.xRotation, + rb_obj.yRotation, + rb_obj.zRotation, + rb_obj.xMoment, + rb_obj.yMoment, + rb_obj.zMoment)) + + # FIXME: This needs to be implemented + ref_node_idx = -1 + rot_node_idx = -1 + + kw_line = "*RIGID BODY,NSET={}".format(rb_obj.Name) + + if is_ref_bc_defined: + kw_line = kw_line + ",REF NODE={}".format(ref_node_idx) + + if is_rot_bc_defined: + kw_line = kw_line + ",ROT NODE={}".format(rot_node_idx) + + f.write(kw_line + "\n") + + # TODO: Displacement definitions need fixing + if is_ref_bc_defined: + f.write("*CLOAD\n") + f.write("{},1,{}\n".format(ref_node_idx, rb_obj.xLoad)) + f.write("{},2,{}\n".format(ref_node_idx, rb_obj.yLoad)) + f.write("{},3,{}\n".format(ref_node_idx, rb_obj.zLoad)) + + if is_rot_bc_defined: + f.write("*CLOAD\n") + f.write("{},1,{}\n".format(rot_node_idx, rb_obj.xMoment)) + f.write("{},2,{}\n".format(rot_node_idx, rb_obj.yMoment)) + f.write("{},3,{}\n".format(rot_node_idx, rb_obj.zMoment)) diff --git a/src/Mod/Fem/femsolver/calculix/writer.py b/src/Mod/Fem/femsolver/calculix/writer.py index bf61f35baa..25225bc9c5 100644 --- a/src/Mod/Fem/femsolver/calculix/writer.py +++ b/src/Mod/Fem/femsolver/calculix/writer.py @@ -45,6 +45,7 @@ from . import write_constraint_heatflux as con_heatflux from . import write_constraint_initialtemperature as con_itemp from . import write_constraint_planerotation as con_planerotation from . import write_constraint_pressure as con_pressure +from . import write_constraint_rigidbody as con_rigidbody from . import write_constraint_sectionprint as con_sectionprint from . import write_constraint_selfweight as con_selfweight from . import write_constraint_temperature as con_temperature @@ -161,6 +162,7 @@ class FemInputWriterCcx(writerbase.FemInputWriter): # node sets self.write_constraints_meshsets(inpfile, self.member.cons_fixed, con_fixed) + self.write_constraints_meshsets(inpfile, self.member.cons_rigidbody, con_rigidbody) self.write_constraints_meshsets(inpfile, self.member.cons_displacement, con_displacement) self.write_constraints_meshsets(inpfile, self.member.cons_planerotation, con_planerotation) self.write_constraints_meshsets(inpfile, self.member.cons_transform, con_transform) @@ -181,6 +183,7 @@ class FemInputWriterCcx(writerbase.FemInputWriter): self.write_constraints_propdata(inpfile, self.member.cons_contact, con_contact) self.write_constraints_propdata(inpfile, self.member.cons_tie, con_tie) self.write_constraints_propdata(inpfile, self.member.cons_transform, con_transform) + self.write_constraints_propdata(inpfile, self.member.cons_rigidbody, con_rigidbody) # step equation write_step_equation.write_step_equation(inpfile, self) diff --git a/src/Mod/Fem/femtools/membertools.py b/src/Mod/Fem/femtools/membertools.py index e75ce7d593..705885b0a6 100644 --- a/src/Mod/Fem/femtools/membertools.py +++ b/src/Mod/Fem/femtools/membertools.py @@ -207,6 +207,10 @@ class AnalysisMember(): list of fixed constraints from the analysis. [{"Object":fixed_obj, "NodeSupports":bool}, {}, ...] + constraints_rigidbody : list of dictionaries + list of displacements for the analysis. + [{"Object":rigidbody_obj, "xxxxxxxx":value}, {}, ...] + constraints_force : list of dictionaries list of force constraints from the analysis. [{"Object":force_obj, "NodeLoad":value}, {}, ... @@ -294,6 +298,9 @@ class AnalysisMember(): self.cons_fixed = self.get_several_member( "Fem::ConstraintFixed" ) + self.cons_rigidbody = self.get_several_member( + "Fem::ConstraintRigidBody" + ) self.cons_force = self.get_several_member( "Fem::ConstraintForce" )