diff --git a/src/Mod/Fem/FemInputWriter.py b/src/Mod/Fem/FemInputWriter.py index 1c892c730..92d16122e 100644 --- a/src/Mod/Fem/FemInputWriter.py +++ b/src/Mod/Fem/FemInputWriter.py @@ -45,7 +45,7 @@ class FemInputWriter(): analysis_obj, solver_obj, mesh_obj, mat_obj, fixed_obj, displacement_obj, - contact_obj, planerotation_obj, + contact_obj, planerotation_obj, transform_obj, selfweight_obj, force_obj, pressure_obj, temperature_obj, heatflux_obj, initialtemperature_obj, beamsection_obj, shellthickness_obj, @@ -59,6 +59,7 @@ class FemInputWriter(): self.displacement_objects = displacement_obj self.contact_objects = contact_obj self.planerotation_objects = planerotation_obj + self.transform_objects = transform_obj self.selfweight_objects = selfweight_obj self.force_objects = force_obj self.pressure_objects = pressure_obj @@ -103,6 +104,11 @@ class FemInputWriter(): for femobj in self.planerotation_objects: # femobj --> dict, FreeCAD document object is femobj['Object'] femobj['Nodes'] = FemMeshTools.get_femnodes_by_references(self.femmesh, femobj['Object'].References) + def get_constraints_transform_nodes(self): + # get nodes + for femobj in self.transform_objects: # femobj --> dict, FreeCAD document object is femobj['Object'] + femobj['Nodes'] = FemMeshTools.get_femnodes_by_references(self.femmesh, femobj['Object'].References) + def get_constraints_temperature_nodes(self): # get nodes for femobj in self.temperature_objects: # femobj --> dict, FreeCAD document object is femobj['Object'] diff --git a/src/Mod/Fem/FemInputWriterCcx.py b/src/Mod/Fem/FemInputWriterCcx.py index 90da6fdd4..76703d40d 100644 --- a/src/Mod/Fem/FemInputWriterCcx.py +++ b/src/Mod/Fem/FemInputWriterCcx.py @@ -40,7 +40,7 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter): analysis_obj, solver_obj, mesh_obj, mat_obj, fixed_obj, displacement_obj, - contact_obj, planerotation_obj, + contact_obj, planerotation_obj, transform_obj, selfweight_obj, force_obj, pressure_obj, temperature_obj, heatflux_obj, initialtemperature_obj, beamsection_obj, shellthickness_obj, @@ -52,7 +52,7 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter): analysis_obj, solver_obj, mesh_obj, mat_obj, fixed_obj, displacement_obj, - contact_obj, planerotation_obj, + contact_obj, planerotation_obj, transform_obj, selfweight_obj, force_obj, pressure_obj, temperature_obj, heatflux_obj, initialtemperature_obj, beamsection_obj, shellthickness_obj, @@ -78,6 +78,8 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter): self.write_node_sets_constraints_planerotation(inpfile) if self.contact_objects: self.write_surfaces_contraints_contact(inpfile) + if self.transform_objects: + self.write_node_sets_constraints_transform(inpfile) if self.analysis_type == "thermomech" and self.temperature_objects: self.write_node_sets_constraints_temperature(inpfile) @@ -92,6 +94,8 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter): self.write_constraints_planerotation(inpfile) if self.contact_objects: self.write_constraints_contact(inpfile) + if self.transform_objects: + self.write_constraints_transform(inpfile) # step begin if self.analysis_type == "frequency": @@ -262,6 +266,22 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter): for i in v: f.write("{},S{}\n".format(i[0], i[1])) + def write_node_sets_constraints_transform(self, f): + # get nodes + self.get_constraints_transform_nodes() + # write nodes to file + f.write('\n***********************************************************\n') + f.write('** Node sets for transform constraint\n') + f.write('** written by {} function\n'.format(sys._getframe().f_code.co_name)) + for femobj in self.transform_objects: # femobj --> dict, FreeCAD document object is femobj['Object'] + trans_obj = femobj['Object'] + if trans_obj.TransformType == "Rectangular": + f.write('*NSET,NSET=Rect' + trans_obj.Name + '\n') + elif trans_obj.TransformType == "Cylindrical": + f.write('*NSET,NSET=Cylin' + trans_obj.Name + '\n') + for n in femobj['Nodes']: + f.write(str(n) + ',\n') + def write_node_sets_constraints_temperature(self, f): # get nodes self.get_constraints_temperature_nodes() @@ -512,6 +532,21 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter): f.write('*MPC\n') f.write('PLANE,' + fric_obj_name + '\n') + def write_constraints_transform(self, f): + f.write('\n***********************************************************\n') + f.write('** Transform Constaints\n') + f.write('** written by {} function\n'.format(sys._getframe().f_code.co_name)) + for trans_object in self.transform_objects: + trans_obj = trans_object['Object'] + if trans_obj.TransformType == "Rectangular": + f.write('*TRANSFORM, NSET=Rect' + trans_obj.Name + ', TYPE=R\n') + coords = FemMeshTools.get_rectangular_coords(trans_obj) + f.write(coords + '\n') + elif trans_obj.TransformType == "Cylindrical": + f.write('*TRANSFORM, NSET=Cylin' + trans_obj.Name + ', TYPE=C\n') + coords = FemMeshTools.get_cylindrical_coords(trans_obj) + f.write(coords + '\n') + def write_constraints_selfweight(self, f): f.write('\n***********************************************************\n') f.write('** Self weight Constraint\n') diff --git a/src/Mod/Fem/FemInputWriterZ88.py b/src/Mod/Fem/FemInputWriterZ88.py index b5d87ac2c..9c3ec19e4 100644 --- a/src/Mod/Fem/FemInputWriterZ88.py +++ b/src/Mod/Fem/FemInputWriterZ88.py @@ -37,7 +37,7 @@ class FemInputWriterZ88(FemInputWriter.FemInputWriter): analysis_obj, solver_obj, mesh_obj, mat_obj, fixed_obj, displacement_obj, - contact_obj, planerotation_obj, + contact_obj, planerotation_obj, transform_obj, selfweight_obj, force_obj, pressure_obj, temperature_obj, heatflux_obj, initialtemperature_obj, beamsection_obj, shellthickness_obj, @@ -49,7 +49,7 @@ class FemInputWriterZ88(FemInputWriter.FemInputWriter): analysis_obj, solver_obj, mesh_obj, mat_obj, fixed_obj, displacement_obj, - contact_obj, planerotation_obj, + contact_obj, planerotation_obj, transform_obj, selfweight_obj, force_obj, pressure_obj, temperature_obj, heatflux_obj, initialtemperature_obj, beamsection_obj, shellthickness_obj, diff --git a/src/Mod/Fem/FemMeshTools.py b/src/Mod/Fem/FemMeshTools.py index 035cf7f3c..dc5cb47c3 100644 --- a/src/Mod/Fem/FemMeshTools.py +++ b/src/Mod/Fem/FemMeshTools.py @@ -868,6 +868,70 @@ def get_three_non_colinear_nodes(nodes_coords): return [node_1, node_2, node_3] +def get_rectangular_coords(obj): + from math import cos, sin, radians + A = [1, 0, 0] + B = [0, 1, 0] + a_x = A[0] + a_y = A[1] + a_z = A[2] + b_x = A[0] + b_y = A[1] + b_z = A[2] + x_rot = radians(obj.X_rot) + y_rot = radians(obj.Y_rot) + z_rot = radians(obj.Z_rot) + if obj.X_rot != 0: + a_x = A[0] + a_y = A[1] * cos(x_rot) + A[2] * sin(x_rot) + a_z = A[2] * cos(x_rot) - A[1] * sin(x_rot) + b_x = B[0] + b_y = B[1] * cos(x_rot) + B[2] * sin(x_rot) + b_z = B[2] * cos(x_rot) - B[1] * sin(x_rot) + A = [a_x, a_y, a_z] + B = [b_x, b_y, b_z] + if obj.Y_rot != 0: + a_x = A[0] * cos(y_rot) - A[2] * sin(y_rot) + a_y = A[1] + a_z = A[2] * cos(y_rot) + A[0] * sin(y_rot) + b_x = B[0] * cos(y_rot) - B[2] * sin(y_rot) + b_y = B[1] + b_z = B[2] * cos(y_rot) + B[0] * sin(z_rot) + A = [a_x, a_y, a_z] + B = [b_x, b_y, b_z] + if obj.Z_rot != 0: + a_x = A[0] * cos(z_rot) + A[1] * sin(z_rot) + a_y = A[1] * cos(z_rot) - A[0] * sin(z_rot) + a_z = A[2] + b_x = B[0] * cos(z_rot) + B[1] * sin(z_rot) + b_y = B[1] * cos(z_rot) - B[0] * sin(z_rot) + b_z = B[2] + A = [a_x, a_y, a_z] + B = [b_x, b_y, b_z] + + A_coords = str(round(A[0], 4)) + ',' + str(round(A[1], 4)) + ',' + str(round(A[2], 4)) + B_coords = str(round(B[0], 4)) + ',' + str(round(B[1], 4)) + ',' + str(round(B[2], 4)) + coords = A_coords + ',' + B_coords + return coords + + +def get_cylindrical_coords(obj): + vec = obj.Axis + base = obj.BasePoint + Ax = base[0] + 10 * vec[0] + Ay = base[1] + 10 * vec[1] + Az = base[2] + 10 * vec[2] + Bx = base[0] - 10 * vec[0] + By = base[1] - 10 * vec[1] + Bz = base[2] - 10 * vec[2] + A = [Ax, Ay, Az] + B = [Bx, By, Bz] + A_coords = str(A[0]) + ',' + str(A[1]) + ',' + str(A[2]) + B_coords = str(B[0]) + ',' + str(B[1]) + ',' + str(B[2]) + coords = A_coords + ',' + B_coords + return coords + + def make_femmesh(mesh_data): ''' makes an FreeCAD FEM Mesh object from FEM Mesh data ''' diff --git a/src/Mod/Fem/FemTools.py b/src/Mod/Fem/FemTools.py index cca6516cb..aaa9f86e0 100644 --- a/src/Mod/Fem/FemTools.py +++ b/src/Mod/Fem/FemTools.py @@ -213,6 +213,10 @@ class FemTools(QtCore.QRunnable, QtCore.QObject): # set of contact constraints from the analysis. Updated with update_objects # Individual constraints are "Fem::ConstraintContact" type self.contact_constraints = [] + ## @var transform_constraints + # set of transform constraints from the analysis. Updated with update_objects + # Individual constraints are "Fem::ConstraintTransform" type + self.transform_constraints = [] found_solver_for_use = False for m in self.analysis.Member: @@ -279,6 +283,10 @@ class FemTools(QtCore.QRunnable, QtCore.QObject): contact_constraint_dict = {} contact_constraint_dict['Object'] = m self.contact_constraints.append(contact_constraint_dict) + elif m.isDerivedFrom("Fem::ConstraintTransform"): + transform_constraint_dict = {} + transform_constraint_dict['Object'] = m + self.transform_constraints.append(transform_constraint_dict) elif hasattr(m, "Proxy") and m.Proxy.Type == "FemBeamSection": beam_section_dict = {} beam_section_dict['Object'] = m diff --git a/src/Mod/Fem/FemToolsCcx.py b/src/Mod/Fem/FemToolsCcx.py index d19c15a4f..d69ec95d1 100644 --- a/src/Mod/Fem/FemToolsCcx.py +++ b/src/Mod/Fem/FemToolsCcx.py @@ -90,7 +90,7 @@ class FemToolsCcx(FemTools.FemTools): self.analysis, self.solver, self.mesh, self.materials, self.fixed_constraints, self.displacement_constraints, - self.contact_constraints, self.planerotation_constraints, + self.contact_constraints, self.planerotation_constraints, self.transform_constraints, self.selfweight_constraints, self.force_constraints, self.pressure_constraints, self.temperature_constraints, self.heatflux_constraints, self.initialtemperature_constraints, self.beam_sections, self.shell_thicknesses, diff --git a/src/Mod/Fem/FemToolsZ88.py b/src/Mod/Fem/FemToolsZ88.py index 513b492ab..5830f261e 100644 --- a/src/Mod/Fem/FemToolsZ88.py +++ b/src/Mod/Fem/FemToolsZ88.py @@ -84,7 +84,7 @@ class FemToolsZ88(FemTools.FemTools): self.analysis, self.solver, self.mesh, self.materials, self.fixed_constraints, self.displacement_constraints, - self.contact_constraints, self.planerotation_constraints, + self.contact_constraints, self.planerotation_constraints, self.transform_constraints, self.selfweight_constraints, self.force_constraints, self.pressure_constraints, self.temperature_constraints, self.heatflux_constraints, self.initialtemperature_constraints, self.beam_sections, self.shell_thicknesses,