diff --git a/src/Mod/Fem/femsolver/calculix/writer.py b/src/Mod/Fem/femsolver/calculix/writer.py index abe4172f31..ef03f0bb7f 100644 --- a/src/Mod/Fem/femsolver/calculix/writer.py +++ b/src/Mod/Fem/femsolver/calculix/writer.py @@ -126,6 +126,7 @@ class FemInputWriterCcx(writerbase.FemInputWriter): self.write_node_sets_constraints_planerotation(inpfileMain, self.split_inpfile) self.write_surfaces_constraints_contact(inpfileMain, self.split_inpfile) self.write_surfaces_constraints_tie(inpfileMain, self.split_inpfile) + self.write_surfaces_constraints_sectionprint(inpfileMain, self.split_inpfile) self.write_node_sets_constraints_transform(inpfileMain, self.split_inpfile) self.write_node_sets_constraints_temperature(inpfileMain, self.split_inpfile) @@ -170,6 +171,7 @@ class FemInputWriterCcx(writerbase.FemInputWriter): # constraints dependent from steps self.write_constraints_fixed(inpfileMain) self.write_constraints_displacement(inpfileMain) + self.write_constraints_sectionprint(inpfileMain) self.write_constraints_selfweight(inpfileMain) self.write_constraints_force(inpfileMain, self.split_inpfile) self.write_constraints_pressure(inpfileMain, self.split_inpfile) @@ -611,6 +613,83 @@ class FemInputWriterCcx(writerbase.FemInputWriter): dep_surf = "TIE_DEP" + tie_obj.Name f.write("{},{}\n".format(dep_surf, ind_surf)) + # ******************************************************************************************** + # constraints sectionprint + def write_surfaces_constraints_sectionprint(self, f, inpfile_split=None): + if not self.sectionprint_objects: + return + # write for all analysis types + + write_name = "constraints_sectionprint_surface_sets" + f.write("\n***********************************************************\n") + f.write("** {}\n".format(write_name.replace("_", " "))) + f.write("** written by {} function\n".format(sys._getframe().f_code.co_name)) + + if inpfile_split is True: + file_name_splitt = self.mesh_name + "_" + write_name + ".inp" + f.write("** {}\n".format(write_name.replace("_", " "))) + f.write("*INCLUDE,INPUT={}\n".format(file_name_splitt)) + inpfile_splitt = open(join(self.dir_name, file_name_splitt), "w") + self.write_surfacefaces_constraints_sectionprint(inpfile_splitt) + inpfile_splitt.close() + else: + self.write_surfacefaces_constraints_sectionprint(f) + + # TODO move code parts from this method to base writer module + def write_surfacefaces_constraints_sectionprint(self, f): + # get surface nodes and write them to file + obj = 0 + for femobj in self.sectionprint_objects: + # femobj --> dict, FreeCAD document object is femobj["Object"] + sectionprint_obj = femobj["Object"] + f.write("** " + sectionprint_obj.Label + "\n") + obj = obj + 1 + for o, elem_tup in sectionprint_obj.References: + for elem in elem_tup: + ref_shape = o.Shape.getElement(elem) + if ref_shape.ShapeType == "Face": + name = "SECTIONFACE" + str(obj) + f.write("*SURFACE, NAME=" + name + "\n") + + v = self.mesh_object.FemMesh.getccxVolumesByFace(ref_shape) + if len(v) > 0: + # volume elements found + FreeCAD.Console.PrintLog( + "{}, surface {}, {} touching volume elements found\n" + .format(sectionprint_obj.Label, name, len(v)) + ) + for i in v: + f.write("{},S{}\n".format(i[0], i[1])) + else: + # no volume elements found, shell elements not allowed + FreeCAD.Console.PrintError( + "{}, surface {}, Error: " + "No volume elements found!\n" + .format(sectionprint_obj.Label, name) + ) + f.write("** Error: empty list\n") + + def write_constraints_sectionprint(self, f): + if not self.sectionprint_objects: + return + # write for all analysis types + + # write constraint to file + f.write("\n***********************************************************\n") + f.write("** SectionPrint Constraints\n") + f.write("** written by {} function\n".format(sys._getframe().f_code.co_name)) + obj = 0 + for femobj in self.sectionprint_objects: + # femobj --> dict, FreeCAD document object is femobj["Object"] + obj = obj + 1 + sectionprint_obj = femobj["Object"] + f.write("** {}\n".format(sectionprint_obj.Label)) + f.write( + "*SECTION PRINT, SURFACE=SECTIONFACE{}, NAME=SECTIONPRINT{}\n" + .format(obj, obj) + ) + f.write("SOF, SOM, SOAREA\n") + # ******************************************************************************************** # constraints transform def write_node_sets_constraints_transform(self, f, inpfile_split=None): diff --git a/src/Mod/Fem/femsolver/writerbase.py b/src/Mod/Fem/femsolver/writerbase.py index ab2893c166..6c18762733 100644 --- a/src/Mod/Fem/femsolver/writerbase.py +++ b/src/Mod/Fem/femsolver/writerbase.py @@ -68,6 +68,7 @@ class FemInputWriter(): self.initialtemperature_objects = member.cons_initialtemperature self.planerotation_objects = member.cons_planerotation self.pressure_objects = member.cons_pressure + self.sectionprint_objects = member.cons_sectionprint self.selfweight_objects = member.cons_selfweight self.temperature_objects = member.cons_temperature self.tie_objects = member.cons_tie diff --git a/src/Mod/Fem/femtools/ccxtools.py b/src/Mod/Fem/femtools/ccxtools.py index 92ecce1d9b..7f6cebc17d 100644 --- a/src/Mod/Fem/femtools/ccxtools.py +++ b/src/Mod/Fem/femtools/ccxtools.py @@ -655,6 +655,7 @@ class FemToolsCcx(QtCore.QRunnable, QtCore.QObject): ) return False else: + FreeCAD.Console.PrintMessage("**** try to read result files\n") self.load_results() # TODO: output an error message if there where problems reading the results return True @@ -805,10 +806,20 @@ class FemToolsCcx(QtCore.QRunnable, QtCore.QObject): """ import feminout.importCcxDatResults as importCcxDatResults dat_result_file = os.path.splitext(self.inp_file_name)[0] + ".dat" + if os.path.isfile(dat_result_file): mode_frequencies = importCcxDatResults.import_dat(dat_result_file, self.analysis) + + obj = FreeCAD.ActiveDocument.addObject("App::TextDocument", "ccx dat file") + # TODO this object should be inside analysis or under result object + # self.result_object.addObject(obj) + file = open(dat_result_file, "r") + obj.Text = file.read() + file.close() + # TODO make the Text of obj read only, or the obj itself else: raise Exception("FEM: No .dat results found at {}!".format(dat_result_file)) + if mode_frequencies: # print(mode_frequencies) for m in self.analysis.Group: diff --git a/src/Mod/Fem/femtools/checksanalysis.py b/src/Mod/Fem/femtools/checksanalysis.py index 911b0c0e07..73fcd867b2 100644 --- a/src/Mod/Fem/femtools/checksanalysis.py +++ b/src/Mod/Fem/femtools/checksanalysis.py @@ -267,6 +267,17 @@ def check_analysismember(analysis, solver, mesh, member): "{} doesn't references exactly two needed faces.\n" .format(c["Object"].Name) ) + # sectionprint + if member.cons_sectionprint: + for c in member.cons_sectionprint: + items = 0 + for reference in c["Object"].References: + items += len(reference[1]) + if items != 1: + message += ( + "{} doesn't reference exactly one needed face.\n" + .format(c["Object"].Name) + ) # transform if member.cons_transform: for c in member.cons_transform: diff --git a/src/Mod/Fem/femtools/membertools.py b/src/Mod/Fem/femtools/membertools.py index a777c4ad27..b3f540b0bb 100644 --- a/src/Mod/Fem/femtools/membertools.py +++ b/src/Mod/Fem/femtools/membertools.py @@ -290,6 +290,9 @@ class AnalysisMember(): self.cons_pressure = self.get_several_member( "Fem::ConstraintPressure" ) + self.cons_sectionprint = self.get_several_member( + "Fem::ConstraintSectionPrint" + ) self.cons_selfweight = self.get_several_member( "Fem::ConstraintSelfWeight" )