def importFrame3DD( filename, analysis=None, result_name_prefix="" ): from . import importToolsFem #from . import Fem.feminout.importToolsFem import ObjectsFem #import result mesh only Console.PrintMessage( "Read Frame3DD results from Frame3DD file: {}\n" .format(filename) ) Frame3DD_file = pyopen(filename, "r") nodes = {} elem = -1 elemType = 0 nDisp=0 numNode = 0 numFixedNode = 0 numMember = 0 numLC = 0 isDebug=0 NodeList = {} MemberList = {} tline=[] for line in Frame3DD_file: tline.append(line.strip()) for i in range(len(tline)): #Console.PrintError(tline[i]) tStrNode="In 2D problems the Y-axis is vertical. In 3D problems the Z-axis is vertical." if tline[i].strip() == tStrNode: #Console.PrintError("FEM: nodes found.\n") i=i+1 i=i+1 data = tline[i].split() #12 NODES 12 FIXED NODES 21 FRAME ELEMENTS 2 LOAD CASES numNode = int(data[0]) numFixedNode = int(data[2]) numMember = int(data[5]) numLC = int(data[8]) i=i+1 # = fp.readline().strip() i=i+1 # = fp.readline().strip() i=i+1 # = fp.readline().strip() #print ("") #print ("numNode: "+str(numNode)) for id in range(numNode): # node #1 0.000000 0.000000 0.000000 0.000 1 1 1 1 1 0 i=i+1 #print (tline[i]) dataNode = tline[i].split() elem = int(dataNode[0]) nodes_x = float(dataNode[1]) nodes_y = float(dataNode[2]) nodes_z = float(dataNode[3]) nodes[elem] = FreeCAD.Vector(nodes_x, nodes_y, nodes_z) NodeList[id] = Node(str(id+1), nodes_x, nodes_y, nodes_z ) i=i+1 i=i+1 #print ("") #print ("numMember: "+str(numMember)) for id in range(numMember): # Member i=i+1 #print (tline[i]) dataNode = tline[i].split() elem = int(dataNode[0]) nd1 = int(dataNode[1]) nd2 = int(dataNode[2]) MemberList[id] = Member(str(id+1) ,nd1, nd2) #print ("") #print ("numFixedNode: "+str(numFixedNode)) #print ("numLC: "+str(numLC)) femmesh = Fem.FemMesh() # nodes #print ("Add nodes") for id in NodeList: # node #femmesh.addNode(NodeList[id].x,NodeList[id].y,NodeList[id].z, int(id)+1 ) femmesh.addNode(NodeList[id].x,NodeList[id].y,NodeList[id].z, int(id)+1 ) # elements for id in MemberList: n1 = MemberList[id].n1 n2 = MemberList[id].n2 femmesh.addEdge([int(n1), int(n2)], int(id)+1) # close Frame3DD file if loop over all lines is finished Frame3DD_file.close() if not nodes: Console.PrintError("FEM: No nodes found in Frame3DD file.\n") else: #Console.PrintError(tline[i]) result_mesh_object = None #mesh = importToolsFem.make_femmesh(m) result_mesh_object = ObjectsFem.makeMeshResult( FreeCAD.ActiveDocument, "ResultMesh" ) result_mesh_object.FemMesh = femmesh res_mesh_is_compacted = False nodenumbers_for_compacted_mesh = [] #import result mm = read_Frame3DD_result(filename) number_of_increments = len(mm["Results"]) Console.PrintLog( "Increments: " + str(number_of_increments) + "\n" ) if len(mm["Results"]) > 0: res_obj=[] iLC=0 iModal=0 results_name="Elastic" for result_set in mm["Results"]: if (iLC<numLC): results_name="Elastic" res_obj.append(ObjectsFem.makeResultMechanical(FreeCAD.ActiveDocument, results_name+str(iLC))) else: results_name="Modal" res_obj.append(ObjectsFem.makeResultMechanical(FreeCAD.ActiveDocument, results_name+str(iModal))) iModal+=1 res_obj[iLC].Mesh = result_mesh_object res_obj[iLC] = importToolsFem.fill_femresult_mechanical(res_obj[iLC], result_set) if analysis: analysis.addObject(res_obj[iLC]) # complementary result object calculations import femresult.resulttools as restools import femtools.femutils as femutils if not res_obj[iLC].MassFlowRate: if res_mesh_is_compacted is False: # first result set, compact FemMesh and NodeNumbers res_obj[iLC] = restools.compact_result(res_obj[iLC]) res_mesh_is_compacted = True nodenumbers_for_compacted_mesh = res_obj[iLC].NodeNumbers else: # all other result sets, do not compact FemMesh, only set NodeNumbers res_obj[iLC].NodeNumbers = nodenumbers_for_compacted_mesh # fill DisplacementLengths res_obj[iLC] = restools.add_disp_apps(res_obj[iLC]) # fill StressValues res_obj[iLC] = restools.add_von_mises(res_obj[iLC]) if res_obj[iLC].getParentGroup(): has_reinforced_mat = False for obj in res_obj[iLC].getParentGroup().Group: if obj.isDerivedFrom("App::MaterialObjectPython") \ and femutils.is_of_type(obj, "Fem::MaterialReinforced"): has_reinforced_mat = True restools.add_principal_stress_reinforced(res_obj[iLC]) break if has_reinforced_mat is False: # fill PrincipalMax, PrincipalMed, PrincipalMin, MaxShear res_obj[iLC] = restools.add_principal_stress_std(res_obj[iLC]) else: # if a pure Frame3DD file was opened no analysis and thus no parent group # fill PrincipalMax, PrincipalMed, PrincipalMin, MaxShear res_obj[iLC] = restools.add_principal_stress_std(res_obj[iLC]) # fill Stats res_obj[iLC] = restools.fill_femresult_stats(res_obj[iLC]) iLC+=1 return res_obj else: error_message = ( "We have nodes only.\n" ) Console.PrintMessage(error_message) if analysis: analysis.addObject(result_mesh_object) if FreeCAD.GuiUp: if analysis: import FemGui FemGui.setActiveAnalysis(analysis) FreeCAD.ActiveDocument.recompute()
def importFrd(filename, analysis=None, result_name_prefix=""): from . import importToolsFem import ObjectsFem if analysis: doc = analysis.Document else: doc = FreeCAD.ActiveDocument m = read_frd_result(filename) result_mesh_object = None res_obj = None if len(m["Nodes"]) > 0: mesh = importToolsFem.make_femmesh(m) result_mesh_object = ObjectsFem.makeMeshResult(doc, "ResultMesh") result_mesh_object.FemMesh = mesh res_mesh_is_compacted = False nodenumbers_for_compacted_mesh = [] number_of_increments = len(m["Results"]) Console.PrintLog("Increments: " + str(number_of_increments) + "\n") if len(m["Results"]) > 0: for result_set in m["Results"]: if "number" in result_set: eigenmode_number = result_set["number"] else: eigenmode_number = 0 step_time = result_set["time"] step_time = round(step_time, 2) if eigenmode_number > 0: results_name = ("{}Mode{}_Results".format( result_name_prefix, eigenmode_number)) elif number_of_increments > 1: results_name = ("{}Time{}_Results".format( result_name_prefix, step_time)) else: results_name = ("{}Results".format(result_name_prefix)) res_obj = ObjectsFem.makeResultMechanical(doc, results_name) res_obj.Mesh = result_mesh_object res_obj = importToolsFem.fill_femresult_mechanical( res_obj, result_set) if analysis: analysis.addObject(res_obj) # complementary result object calculations import femresult.resulttools as restools import femtools.femutils as femutils if not res_obj.MassFlowRate: # information 1: # only compact result if not Flow 1D results # compact result object, workaround for bug 2873 # https://www.freecadweb.org/tracker/view.php?id=2873 # information 2: # if the result data has multiple result sets there will be multiple result objs # they all will use one mesh obj # on the first res obj fill the mesh obj will be compacted, thus # it does not need to be compacted on further result sets # but NodeNumbers need to be compacted for every result set (res object fill) # example frd file: https://forum.freecadweb.org/viewtopic.php?t=32649#p274291 if res_mesh_is_compacted is False: # first result set, compact FemMesh and NodeNumbers res_obj = restools.compact_result(res_obj) res_mesh_is_compacted = True nodenumbers_for_compacted_mesh = res_obj.NodeNumbers else: # all other result sets, do not compact FemMesh, only set NodeNumbers res_obj.NodeNumbers = nodenumbers_for_compacted_mesh # fill DisplacementLengths res_obj = restools.add_disp_apps(res_obj) # fill vonMises res_obj = restools.add_von_mises(res_obj) if res_obj.getParentGroup(): has_reinforced_mat = False for obj in res_obj.getParentGroup().Group: if obj.isDerivedFrom("App::MaterialObjectPython") \ and femutils.is_of_type(obj, "Fem::MaterialReinforced"): has_reinforced_mat = True restools.add_principal_stress_reinforced(res_obj) break if has_reinforced_mat is False: # fill PrincipalMax, PrincipalMed, PrincipalMin, MaxShear res_obj = restools.add_principal_stress_std(res_obj) else: # if a pure frd file was opened no analysis and thus no parent group # fill PrincipalMax, PrincipalMed, PrincipalMin, MaxShear res_obj = restools.add_principal_stress_std(res_obj) # fill Stats res_obj = restools.fill_femresult_stats(res_obj) else: error_message = ( "Nodes, but no results found in frd file. " "It means there only is a mesh but no results in frd file. " "Usually this happens for: \n" "- analysis type 'NOANALYSIS'\n" "- if CalculiX returned no results " "(happens on nonpositive jacobian determinant in at least one element)\n" "- just no frd results where requestet in input file " "(neither 'node file' nor 'el file' in output section')\n") Console.PrintMessage(error_message) # create a result obj, even if we have no results but a result mesh in frd file # see error message above for more information if not res_obj: if result_name_prefix: results_name = ("{}_Results".format(result_name_prefix)) else: results_name = ("Results".format(result_name_prefix)) res_obj = ObjectsFem.makeResultMechanical(doc, results_name) res_obj.Mesh = result_mesh_object # TODO, node numbers in result obj could be set if analysis: analysis.addObject(res_obj) if FreeCAD.GuiUp: if analysis: import FemGui FemGui.setActiveAnalysis(analysis) doc.recompute() else: Console.PrintError( "Problem on frd file import. No nodes found in frd file.\n") # None will be returned # or would it be better to raise an exception if there are not even nodes in frd file return res_obj
def importFrd(filename, analysis=None, result_name_prefix=None): from . import importToolsFem import ObjectsFem if result_name_prefix is None: result_name_prefix = '' m = read_frd_result(filename) result_mesh_object = None if len(m['Nodes']) > 0: if analysis: analysis_object = analysis mesh = importToolsFem.make_femmesh(m) result_mesh_object = ObjectsFem.makeMeshResult(FreeCAD.ActiveDocument, 'Result_mesh') result_mesh_object.FemMesh = mesh number_of_increments = len(m['Results']) FreeCAD.Console.PrintLog('Increments: ' + str(number_of_increments) + '\n') if len(m['Results']) > 0: for result_set in m['Results']: if 'number' in result_set: eigenmode_number = result_set['number'] else: eigenmode_number = 0 step_time = result_set['time'] step_time = round(step_time, 2) if eigenmode_number > 0: results_name = result_name_prefix + 'mode_' + str( eigenmode_number) + '_results' elif number_of_increments > 1: results_name = result_name_prefix + 'time_' + str( step_time) + '_results' else: results_name = result_name_prefix + 'results' res_obj = ObjectsFem.makeResultMechanical( FreeCAD.ActiveDocument, results_name) res_obj.Mesh = result_mesh_object res_obj = importToolsFem.fill_femresult_mechanical( res_obj, result_set) if analysis: analysis_object.addObject(res_obj) # complementary result object calculations import femresult.resulttools as restools if not res_obj.MassFlowRate: # only compact result if not Flow 1D results # compact result object, workaround for bug 2873, https://www.freecadweb.org/tracker/view.php?id=2873 res_obj = restools.compact_result(res_obj) res_obj = restools.add_disp_apps( res_obj) # fill DisplacementLengths res_obj = restools.add_von_mises(res_obj) # fill StressValues res_obj = restools.add_principal_stress( res_obj ) # fill PrincipalMax, PrincipalMed, PrincipalMin, MaxShear res_obj = restools.fill_femresult_stats(res_obj) # fill Stats else: error_message = ( "We have nodes but no results in frd file, which means we only have a mesh in frd file. " "Usually this happens for analysis type 'NOANALYSIS' or if CalculiX returned no results because " "of nonpositive jacobian determinant in at least one element.\n" ) FreeCAD.Console.PrintMessage(error_message) if analysis: analysis_object.addObject(result_mesh_object) if FreeCAD.GuiUp: if analysis: import FemGui FemGui.setActiveAnalysis(analysis_object) FreeCAD.ActiveDocument.recompute() else: FreeCAD.Console.PrintError( 'Problem on frd file import. No nodes found in frd file.\n')
def Activated(self): import feminout.importToolsFem as toolsFem import ObjectsFem analysis=None path = FreeCAD.getHomePath()+"/bin/" fName = path+'hFrame3DDfc.out' NodeList = {} MemberList = {} DisplacementList = {} NodeEndList = {} MemberEndList = {} ProjectDescription = '' nodes = {} results = [] mode_results = {} mode_disp = {} iFilled=[] nDisp=0 mDisp=0 numNode = 0 isDebug=1 #factor = 25.42 factor = 1 factorZoom = 100 #000000000000000000000000000000000000000000000000000000000000000000 femmesh = Fem.FemMesh() #femResult = Fem.FemResultObject() fp = open(fName) Frame3DD_file=fp.readlines() fp.close() tline=[] for line in Frame3DD_file: tline.append(line.strip()) for i in range(len(tline)): tStrNode="In 2D problems the Y-axis is vertical. In 3D problems the Z-axis is vertical." if tline[i].strip() == tStrNode: #Console.PrintError("FEM: nodes found.\n") i=i+1 i=i+1 data = tline[i].split() #12 NODES 12 FIXED NODES 21 FRAME ELEMENTS 2 LOAD CASES numNode = int(data[0]) numFixedNode = int(data[2]) numMember = int(data[5]) numLC = int(data[8]) for id in range(numNode): # node iFilled.append(0) i=i+1 # = fp.readline().strip() i=i+1 # = fp.readline().strip() i=i+1 # = fp.readline().strip() if isDebug==1: print ("") print ("numNode: "+str(numNode)) for id in range(numNode): # node #1 0.000000 0.000000 0.000000 0.000 1 1 1 1 1 0 i=i+1 #print (tline[i]) dataNode = tline[i].split() elem = int(dataNode[0]) nodes_x = float(dataNode[1]) nodes_y = float(dataNode[2]) nodes_z = float(dataNode[3]) nodes[elem] = FreeCAD.Vector(nodes_x, nodes_y, nodes_z) NodeList[id] = Node(str(id+1), nodes_x, nodes_y, nodes_z ) i=i+1 i=i+1 if isDebug==1: print ("") print ("numMember: "+str(numMember)) for id in range(numMember): # Member i=i+1 #print (tline[i]) dataNode = tline[i].split() elem = int(dataNode[0]) nd1 = int(dataNode[1]) nd2 = int(dataNode[2]) MemberList[id] = Member(str(id+1) ,nd1, nd2) #if isDebug==1: # print ("") # print ("numFixedNode: "+str(numFixedNode)) if isDebug==1: print ("") print ("numLC: "+str(numLC)) femmesh = Fem.FemMesh() # nodes #print ("Add nodes") for id in NodeList: # node #femmesh.addNode(NodeList[id].x,NodeList[id].y,NodeList[id].z, int(id)+1 ) femmesh.addNode(NodeList[id].x,NodeList[id].y,NodeList[id].z, int(id)+1 ) # elements for id in MemberList: n1 = MemberList[id].n1 n2 = MemberList[id].n2 femmesh.addEdge([int(n1), int(n2)], int(id)+1) result_mesh_object = None result_mesh_object = ObjectsFem.makeMeshResult( FreeCAD.ActiveDocument, "ResultMesh" ) result_mesh_object.FemMesh = femmesh res_mesh_is_compacted = False nodenumbers_for_compacted_mesh = [] isElastic=0 isModal=0 for i in range(len(tline)): tStrDis="E L A S T I C S T I F F N E S S A N A L Y S I S via L D L' decomposition" if tline[i].strip() == tStrDis: #Console.PrintError("FEM: displacement found.\n") isElastic=1 if (isElastic==1 and isModal==0): tStrDis="Node X-dsp Y-dsp Z-dsp X-rot Y-rot Z-rot" if tline[i].strip() == tStrDis: #Console.PrintError("FEM: displacement found.\n") print ("") print ("Displacement"+str(nDisp)) for id in range(numNode): # node iFilled[id]=0 for id in range(numNode): # node #Node X-dsp Y-dsp Z-dsp X-rot Y-rot Z-rot #1 0.0 0.0 0.0 0.0 0.0 -0.001254 i=i+1 #print (tline[i]) dataNode = tline[i].split() #print (dataNode[0]+" "+str(numNode)) if (dataNode[0].isdigit()): elem = int(dataNode[0]) iFilled[elem-1] = 1 mode_disp_x = float(dataNode[1]) mode_disp_y = float(dataNode[2]) mode_disp_z = float(dataNode[3]) mode_disp[elem] = FreeCAD.Vector(mode_disp_x, mode_disp_y, mode_disp_z) else: break for id in range(numNode): # node if (iFilled[id] == 0): mode_disp[id+1] = FreeCAD.Vector(0., 0., 0.) #print (str(id)+" "+str(iFilled[id])) #mode_results["disp"+str(nDisp)] = mode_disp mode_results["disp"] = mode_disp mode_disp = {} nDisp+=1 # append mode_results to results and reset mode_result results.append(mode_results) mode_results = {} #mode shapes tStrDis="M O D A L A N A L Y S I S R E S U L T S" if tline[i].strip() == tStrDis: #Console.PrintError("FEM: displacement found.\n") isModal=1 if (isModal==1): tStrDis="Node X-dsp Y-dsp Z-dsp X-rot Y-rot Z-rot" if tline[i].strip() == tStrDis: #Console.PrintError("FEM: displacement found.\n") print ("") print ("Modal Displacement"+str(mDisp)) for id in range(numNode): # node iFilled[id]=0 for id in range(numNode): # node #Node X-dsp Y-dsp Z-dsp X-rot Y-rot Z-rot #1 0.0 0.0 0.0 0.0 0.0 -0.001254 #" %11.3e" #1 -1.#IOe+000 -1.#IOe+000 -1.#IOe+000 -1.#IOe+000 -1.#IOe+000 -1.#IOe+000 i=i+1 #print (tline[i]) dataNode = tline[i].split() #print (dataNode[0]+" "+str(numNode)) if (dataNode[0].isdigit()): elem = int(dataNode[0]) iFilled[elem-1] = 1 mode_disp_x = float(dataNode[1]) mode_disp_y = float(dataNode[2]) mode_disp_z = float(dataNode[3]) mode_disp[elem] = FreeCAD.Vector(mode_disp_x, mode_disp_y, mode_disp_z) else: break for id in range(numNode): # node if (iFilled[id] == 0): mode_disp[id+1] = FreeCAD.Vector(0., 0., 0.) #print (str(id)+" "+str(iFilled[id])) #mode_results["disp"+str(nDisp)] = mode_disp mode_results["disp"] = mode_disp mode_disp = {} mDisp+=1 # append mode_results to results and reset mode_result results.append(mode_results) mode_results = {} res_obj=[] iLC=0 iModal=0 results_name="Elastic" for result_set in results: if (iLC<numLC): results_name="Elastic" res_obj.append(ObjectsFem.makeResultMechanical(FreeCAD.ActiveDocument, results_name+str(iLC))) else: results_name="Modal" res_obj.append(ObjectsFem.makeResultMechanical(FreeCAD.ActiveDocument, results_name+str(iModal))) iModal+=1 res_obj[iLC].Mesh = result_mesh_object #res_obj[iLC] = importToolsFem.fill_femresult_mechanical(res_obj[iLC], result_set) res_obj[iLC] = toolsFem.fill_femresult_mechanical(res_obj[iLC], result_set) if analysis: analysis.addObject(res_obj[iLC]) # complementary result object calculations import femresult.resulttools as restools import femtools.femutils as femutils if not res_obj[iLC].MassFlowRate: if res_mesh_is_compacted is False: # first result set, compact FemMesh and NodeNumbers res_obj[iLC] = restools.compact_result(res_obj[iLC]) res_mesh_is_compacted = True nodenumbers_for_compacted_mesh = res_obj[iLC].NodeNumbers else: # all other result sets, do not compact FemMesh, only set NodeNumbers res_obj[iLC].NodeNumbers = nodenumbers_for_compacted_mesh # fill DisplacementLengths res_obj[iLC] = restools.add_disp_apps(res_obj[iLC]) # fill StressValues res_obj[iLC] = restools.add_von_mises(res_obj[iLC]) if res_obj[iLC].getParentGroup(): has_reinforced_mat = False for obj in res_obj[iLC].getParentGroup().Group: if obj.isDerivedFrom("App::MaterialObjectPython") \ and femutils.is_of_type(obj, "Fem::MaterialReinforced"): has_reinforced_mat = True restools.add_principal_stress_reinforced(res_obj[iLC]) break if has_reinforced_mat is False: # fill PrincipalMax, PrincipalMed, PrincipalMin, MaxShear res_obj[iLC] = restools.add_principal_stress_std(res_obj[iLC]) else: # if a pure Frame3DD file was opened no analysis and thus no parent group # fill PrincipalMax, PrincipalMed, PrincipalMin, MaxShear res_obj[iLC] = restools.add_principal_stress_std(res_obj[iLC]) # fill Stats res_obj[iLC] = restools.fill_femresult_stats(res_obj[iLC]) iLC+=1
def importFrd( filename, analysis=None, result_name_prefix=None ): from . import importToolsFem import ObjectsFem if result_name_prefix is None: result_name_prefix = '' m = read_frd_result(filename) result_mesh_object = None if len(m['Nodes']) > 0: if analysis: analysis_object = analysis mesh = importToolsFem.make_femmesh(m) result_mesh_object = ObjectsFem.makeMeshResult( FreeCAD.ActiveDocument, 'Result_mesh' ) result_mesh_object.FemMesh = mesh number_of_increments = len(m['Results']) FreeCAD.Console.PrintLog( 'Increments: ' + str(number_of_increments) + '\n' ) if len(m['Results']) > 0: for result_set in m['Results']: if 'number' in result_set: eigenmode_number = result_set['number'] else: eigenmode_number = 0 step_time = result_set['time'] step_time = round(step_time, 2) if eigenmode_number > 0: results_name = ( '{}mode_{}_results' .format(result_name_prefix, eigenmode_number) ) elif number_of_increments > 1: results_name = ( '{}time_{}_results' .format(result_name_prefix, step_time) ) else: results_name = ( '{}results' .format(result_name_prefix) ) res_obj = ObjectsFem.makeResultMechanical(FreeCAD.ActiveDocument, results_name) res_obj.Mesh = result_mesh_object res_obj = importToolsFem.fill_femresult_mechanical(res_obj, result_set) if analysis: analysis_object.addObject(res_obj) # complementary result object calculations import femresult.resulttools as restools if not res_obj.MassFlowRate: # only compact result if not Flow 1D results # compact result object, workaround for bug 2873 # https://www.freecadweb.org/tracker/view.php?id=2873 res_obj = restools.compact_result(res_obj) # fill DisplacementLengths res_obj = restools.add_disp_apps(res_obj) # fill StressValues res_obj = restools.add_von_mises(res_obj) # fill PrincipalMax, PrincipalMed, PrincipalMin, MaxShear res_obj = restools.add_principal_stress(res_obj) # fill Stats res_obj = restools.fill_femresult_stats(res_obj) else: error_message = ( "We have nodes but no results in frd file, " "which means we only have a mesh in frd file. " "Usually this happens for analysis type 'NOANALYSIS' " "or if CalculiX returned no results because " "of nonpositive jacobian determinant in at least one element.\n" ) FreeCAD.Console.PrintMessage(error_message) if analysis: analysis_object.addObject(result_mesh_object) if FreeCAD.GuiUp: if analysis: import FemGui FemGui.setActiveAnalysis(analysis_object) FreeCAD.ActiveDocument.recompute() else: FreeCAD.Console.PrintError( 'Problem on frd file import. No nodes found in frd file.\n' ) return res_obj
def Activated(self): import feminout.importToolsFem as toolsFem import ObjectsFem numNode = 0 numMember = 0 analysis = None iHfc = FreeCAD.ActiveDocument.getObject('hfc') if iHfc == None: ininame = "Mod/hfcMystran/hfcMystran.ini" inifile = FreeCAD.getHomePath() + ininame if os.path.exists(inifile): iniF = open(inifile, "r") path = iniF.readline() iniF.close() else: inipath = FreeCAD.getHomePath() try: filename = QFileDialog.getOpenFileName( None, QString.fromLocal8Bit("Read a Mystarn's neu file"), path, "*.neu") # PyQt4 except Exception: filename, Filter = PySide.QtGui.QFileDialog.getOpenFileName( None, "Read a Mystran's neu file", path, "*.neu") #PySide data = filename.split("/") n = len(data) path = "" for i in range(n - 1): path = path + data[i] + "/" fn = data[n - 1].split('.') filenameDat = path + fn[0] + '.dat' inifileOut = FreeCAD.getHomePath() + ininame iniFout = open(inifileOut, "w") iniFout.writelines(path) iniFout.close() else: path = iHfc.DatPath filenameDat = iHfc.DatFile filename = filenameDat[:len(filenameDat) - 3] + 'neu' print("Result: " + filename) #print (path) #fNameDat = path+'hfcMystran.dat' nodes_x = [] nodes_y = [] nodes_z = [] NodeList = {} MemberList = {} DisplacementList = {} NodeEndList = {} MemberEndList = {} ProjectDescription = '' nodes = {} results = [] mode_results = {} mode_disp = {} iFilled = [] mode_disp_id = [] mode_disp_x = [] mode_disp_y = [] mode_disp_z = [] nDisp = 0 mDisp = 0 isDebug = 1 #factor = 25.42 factor = 1 factorZoom = 100 #000000000000000000000000000000000000000000000000000000000000000000 fpDat = open(filenameDat) tline = [] for line in fpDat: aline = line.strip() if len(aline) == 0 or aline[0] == '$': continue else: tline.append(line.strip()) fpDat.close() for id in range(len(tline)): aline = tline[id].strip() data = aline.split() data1 = aline.split(",") #GRID 3004 0.750 0.500 0.000 126 if data[0] == 'GRID': #Fixed format # id cp x1 #GRID 10101 0 0.000 0.000 0.000 0 is8Byte = 1 if is8Byte == 1: tid = aline[8:16].strip() #cp=aline[17:24].strip() x = aline[24:32].strip() y = aline[32:40].strip() z = aline[40:48].strip() NodeList[tid] = Node(tid, float(x), float(y), float(z)) elif len(aline) == 48: tid = aline[6:24].strip() #print (tid) #x datax = aline[25:32].strip() #56-41=15 if len(datax) == 15: dataf = datax[1:12] datab = datax[13:15] x = dataf + 'E' + datab #56-41=15 else: x = datax #56-41=15 #print (x) #y datay = aline[33:40].strip() #56-41=15 if len(datay) == 15: dataf = datay[1:12] datab = datay[13:15] y = dataf + 'E' + datab #56-41=15 else: y = datax #56-41=15 #print (y) #z dataz = aline[40:48].strip() #56-41=15 #print (dataz) tsign = dataz[len(dataz) - 2] #print (tsign) if tsign == '-': dataf = dataz[:len(dataz) - 1 - 1] datab = dataz[len(dataz) - 1 - 1:] z = dataf + 'E' + datab #56-41=15 else: z = dataz #56-41=15 #print (str(id)+" "+str(x)+" "+str(y)+" "+str(z)) NodeList[tid] = Node(tid, float(x), float(y), float(z)) else: #NodeList[data[1].strip()] = Node(data[1].strip(), float(data[2].strip()), float(data[3].strip()), float(data[4].strip())) print('Grid') numNode = numNode + 1 #GRID* 1 0.00000E+00 0.00000E+00 if data[0] == 'GRID*': NodeList[data[1]] = Node(data[1], float(data[2]), float(data[3]), 0.0) numNode = numNode + 1 # Member 333333333333333333333333333333333333333 #CBAR 201 2 11 21 0.0 0.0 1.0 if data[0] == 'CBAR': MemberList[data[1].strip()] = MemberCBAR( data[1].strip(), data[3], data[4], data[0].strip()) numMember += 1 #CBEAM 9400 9401 9401 9402 0. 0. 1. if data[0] == 'CBEAM': MemberList[data[1].strip()] = MemberCBEAM( data[1].strip(), data[3], data[4], data[0].strip()) numMember += 1 #CROD, 418,418,8,3 if data[0] == 'CROD': MemberList[data[1].strip()] = MemberCROD( data[1].strip(), data[3], data[4], data[0].strip()) numMember += 1 #CROD, 418,418,8,3 if data1[0] == 'CROD': MemberList[data1[1].strip()] = MemberCROD( data1[1].strip(), data1[3], data1[4], data1[0].strip()) numMember += 1 #CTRIA3 24 91 1033 1032 1023 if data[0] == 'CTRIA3': MemberList[data[1].strip()] = MemberCTRIA3( data[1].strip(), data[3], data[4], data[5], data[0].strip()) numMember += 1 #CQUAD4 1001 1 1001 1002 2002 2001 if data[0] == 'CQUAD4': MemberList[data[1].strip()] = MemberCQUAD4( data[1].strip(), data[3], data[4], data[5], data[6], data[0].strip()) numMember += 1 #CQUAD8 16004 1 16007 16009 18009 18007 16008 17009 #18008 17007 if data[0] == 'CQUAD8': MemberList[data[1].strip()] = MemberCQUAD8( data[1].strip(), data[3], data[4], data[5], data[6], data[0].strip()) numMember += 1 #CTETRA 1 1 8 13 67 33 if data[0] == 'CTETRA': MemberList[data[1].strip()] = MemberCQUAD4( data[1].strip(), data[3], data[4], data[5], data[6], data[0].strip()) numMember += 1 # #CHEXA 10101 100 10101 10103 10303 10301 30101 30103+E 1 #+E 1 30303 30301 if data[0] == 'CHEXA': bline = tline[id + 1].strip() if len(aline) == 80: eid = aline[9:16].strip() pid = aline[17:24].strip() g1 = aline[25:32].strip() g2 = aline[33:40].strip() g3 = aline[41:48].strip() g4 = aline[49:56].strip() g5 = aline[57:64].strip() g6 = aline[65:72].strip() if aline[73:80] == bline[1:8]: g7 = bline[9:16].strip() g8 = bline[17:24].strip() #print (eid+" "+g1+" "+g2+" "+g3+" "+g4+" "+g5+" "+g6+" "+g7+" "+g8) MemberList[eid] = MemberCHEXA(eid, g1, g2, g3, g4, g5, g6, g7, g8, data[0].strip()) numMember += 1 #print (NodeList) #print (MemberList) femmesh = Fem.FemMesh() # nodes #print ("Add nodes") for id in NodeList: # node #femmesh.addNode(NodeList[id].x,NodeList[id].y,NodeList[id].z, int(id)+1 ) femmesh.addNode(NodeList[id].x, NodeList[id].y, NodeList[id].z, int(id)) # elements for id in MemberList: mtype = MemberList[id].mtype if mtype == 'CROD': n1 = int(MemberList[id].n1) n2 = int(MemberList[id].n2) femmesh.addEdge([n1, n2]) elif mtype == 'CBAR': n1 = int(MemberList[id].n1) n2 = int(MemberList[id].n2) femmesh.addEdge([n1, n2]) elif mtype == 'CBEAM': n1 = int(MemberList[id].n1) n2 = int(MemberList[id].n2) femmesh.addEdge([n1, n2]) elif mtype == 'CTRIA3': n1 = int(MemberList[id].n1) n2 = int(MemberList[id].n2) n3 = int(MemberList[id].n3) femmesh.addEdge([n1, n2]) femmesh.addEdge([n2, n3]) femmesh.addEdge([n3, n1]) #femmesh.addFace([n1,n2,n3]) elif mtype == 'CQUAD4': n1 = int(MemberList[id].n1) n2 = int(MemberList[id].n2) n3 = int(MemberList[id].n3) n4 = int(MemberList[id].n4) #print (str(n1)+" "+str(n2)+" "+str(n3)+" "+str(n4)) femmesh.addEdge([n1, n2]) femmesh.addEdge([n2, n3]) femmesh.addEdge([n3, n4]) femmesh.addEdge([n4, n1]) #femmesh.addFace([n1,n2,n3,n4]) elif mtype == 'CQUAD8': n1 = int(MemberList[id].n1) n2 = int(MemberList[id].n2) n3 = int(MemberList[id].n3) n4 = int(MemberList[id].n4) femmesh.addEdge([n1, n2]) femmesh.addEdge([n2, n3]) femmesh.addEdge([n3, n4]) femmesh.addEdge([n4, n1]) #femmesh.addFace([n1,n2,n3,n4]) elif mtype == 'CTETRA': n1 = int(MemberList[id].n1) n2 = int(MemberList[id].n2) n3 = int(MemberList[id].n3) n4 = int(MemberList[id].n4) femmesh.addEdge([n1, n2]) femmesh.addEdge([n2, n3]) femmesh.addEdge([n3, n4]) femmesh.addEdge([n4, n1]) #femmesh.addVolume([n1,n2,n3,n4]) elif mtype == 'CHEXA': n1 = int(MemberList[id].n1) n2 = int(MemberList[id].n2) n3 = int(MemberList[id].n3) n4 = int(MemberList[id].n4) n5 = int(MemberList[id].n5) n6 = int(MemberList[id].n6) n7 = int(MemberList[id].n7) n8 = int(MemberList[id].n8) femmesh.addEdge([n1, n2]) femmesh.addEdge([n2, n3]) femmesh.addEdge([n3, n4]) femmesh.addEdge([n4, n1]) femmesh.addEdge([n5, n6]) femmesh.addEdge([n6, n7]) femmesh.addEdge([n7, n8]) femmesh.addEdge([n8, n5]) femmesh.addEdge([n1, n5]) femmesh.addEdge([n2, n6]) femmesh.addEdge([n3, n7]) femmesh.addEdge([n4, n8]) #femmesh.addVolume([n1,n2,n3,n4,n5,n6,n7,n8]) else: print(mtype + ' Not supported yet') result_mesh_object = None result_mesh_object = ObjectsFem.makeMeshResult(FreeCAD.ActiveDocument, "ResultMesh") result_mesh_object.FemMesh = femmesh res_mesh_is_compacted = False nodenumbers_for_compacted_mesh = [] #femResult = Fem.FemResultObject() #-------------------------------------- fp = open(filename) tline = [] for line in fp: aline = line.strip() if len(aline) == 0 or aline[0] == '$': continue else: tline.append(line.strip()) fp.close() tStrDis1 = "T1 translation" tStrDis2 = "T2 translation" tStrDis3 = "T3 translation" for i in range(len(tline)): if tline[i].strip() == tStrDis1: #T1 translation # 0.000000E+00, 1.800000E-04, 1.800000E-04, # 10002, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 1, 7, 1, 7, # 1, 1, 1 i = i + 6 for id in range(numNode): # node #print (tline[i]) #1, 0.000000E+00, dataNode = tline[i].split(",") #print (dataNode[0]+" "+str(numNode)) mode_disp_id.append(int(dataNode[0])) mode_disp_x.append(float(dataNode[1])) i = i + 1 if tline[i].strip() == tStrDis2: #T1 translation # 0.000000E+00, 1.800000E-04, 1.800000E-04, # 10002, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 1, 7, 1, 7, # 1, 1, 1 i = i + 6 for id in range(numNode): # node #print (tline[i]) #1, 0.000000E+00, dataNode = tline[i].split(",") #print (dataNode[0]+" "+str(numNode)) mode_disp_y.append(float(dataNode[1])) i = i + 1 if tline[i].strip() == tStrDis3: #T1 translation # 0.000000E+00, 1.800000E-04, 1.800000E-04, # 10002, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # 1, 7, 1, 7, # 1, 1, 1 i = i + 6 for id in range(numNode): # node #print (tline[i]) #1, 0.000000E+00, dataNode = tline[i].split(",") #print (dataNode[0]+" "+str(numNode)) mode_disp_z.append(float(dataNode[1])) i = i + 1 for id in range(numNode): # node #print (str(id)+" "+str(mode_disp_x[id])+" "+ str(mode_disp_y[id])+" "+str(mode_disp_z[id])) mode_disp[mode_disp_id[id]] = FreeCAD.Vector( mode_disp_x[id], mode_disp_y[id], mode_disp_z[id]) #mode_results["disp"+str(nDisp)] = mode_disp mode_results["disp"] = mode_disp mode_disp = {} #nDisp+=1 res_obj = [] iLC = 0 results_name = "Displacement" # append mode_results to results and reset mode_result results.append(mode_results) mode_results = {} for result_set in results: res_obj.append( ObjectsFem.makeResultMechanical(FreeCAD.ActiveDocument, results_name + str(iLC))) res_obj[iLC].Mesh = result_mesh_object #res_obj[iLC] = importToolsFem.fill_femresult_mechanical(res_obj[iLC], result_set) res_obj[iLC] = toolsFem.fill_femresult_mechanical( res_obj[iLC], result_set) # complementary result object calculations import femresult.resulttools as restools import femtools.femutils as femutils # fill DisplacementLengths res_obj[iLC] = restools.add_disp_apps(res_obj[iLC]) # fill StressValues res_obj[iLC] = restools.add_von_mises(res_obj[iLC]) if res_obj[iLC].getParentGroup(): has_reinforced_mat = False for obj in res_obj[iLC].getParentGroup().Group: if obj.isDerivedFrom("App::MaterialObjectPython") \ and femutils.is_of_type(obj, "Fem::MaterialReinforced"): has_reinforced_mat = True restools.add_principal_stress_reinforced(res_obj[iLC]) break if has_reinforced_mat is False: # fill PrincipalMax, PrincipalMed, PrincipalMin, MaxShear res_obj[iLC] = restools.add_principal_stress_std( res_obj[iLC]) else: # if a pure Frame3DD file was opened no analysis and thus no parent group # fill PrincipalMax, PrincipalMed, PrincipalMin, MaxShear res_obj[iLC] = restools.add_principal_stress_std(res_obj[iLC]) # fill Stats res_obj[iLC] = restools.fill_femresult_stats(res_obj[iLC]) #res_obj[iLC].ViewObject.DisplayMode = 'Uabs' FreeCAD.ActiveDocument.recompute() FreeCADGui.activeDocument().activeView().viewAxonometric() FreeCADGui.SendMsgToActiveView("ViewFit")
def importFrd(filename, analysis=None, result_name_prefix=None): from . import importToolsFem import ObjectsFem if result_name_prefix is None: result_name_prefix = '' m = read_frd_result(filename) result_mesh_object = None if len(m['Nodes']) > 0: if analysis: analysis_object = analysis mesh = importToolsFem.make_femmesh(m) result_mesh_object = ObjectsFem.makeMeshResult(FreeCAD.ActiveDocument, 'ResultMesh') result_mesh_object.FemMesh = mesh res_mesh_is_compacted = False nodenumbers_for_compacted_mesh = [] number_of_increments = len(m['Results']) FreeCAD.Console.PrintLog('Increments: ' + str(number_of_increments) + '\n') if len(m['Results']) > 0: for result_set in m['Results']: if 'number' in result_set: eigenmode_number = result_set['number'] else: eigenmode_number = 0 step_time = result_set['time'] step_time = round(step_time, 2) if eigenmode_number > 0: results_name = ('{}Mode{}_Results'.format( result_name_prefix, eigenmode_number)) elif number_of_increments > 1: results_name = ('{}Time{}_Results'.format( result_name_prefix, step_time)) else: results_name = ('{}Results'.format(result_name_prefix)) res_obj = ObjectsFem.makeResultMechanical( FreeCAD.ActiveDocument, results_name) res_obj.Mesh = result_mesh_object res_obj = importToolsFem.fill_femresult_mechanical( res_obj, result_set) if analysis: analysis_object.addObject(res_obj) # complementary result object calculations import femresult.resulttools as restools import femtools.femutils as femutils if not res_obj.MassFlowRate: # information 1: # only compact result if not Flow 1D results # compact result object, workaround for bug 2873 # https://www.freecadweb.org/tracker/view.php?id=2873 # information 2: # if the result data has multiple result sets there will be multiple result objs # they all will use one mesh obj # on the first res obj fill the mesh obj will be compacted, thus # it does not need to be compacted on further result sets # but NodeNumbers need to be compacted for every result set (res object fill) # example frd file: https://forum.freecadweb.org/viewtopic.php?t=32649#p274291 if res_mesh_is_compacted is False: # first result set, compact FemMesh and NodeNumbers res_obj = restools.compact_result(res_obj) res_mesh_is_compacted = True nodenumbers_for_compacted_mesh = res_obj.NodeNumbers else: # all other result sets, do not compact FemMesh, only set NodeNumbers res_obj.NodeNumbers = nodenumbers_for_compacted_mesh # fill DisplacementLengths res_obj = restools.add_disp_apps(res_obj) # fill StressValues res_obj = restools.add_von_mises(res_obj) if res_obj.getParentGroup(): has_reinforced_mat = False for obj in res_obj.getParentGroup().Group: if obj.isDerivedFrom('App::MaterialObjectPython') \ and femutils.is_of_type(obj, 'Fem::MaterialReinforced'): has_reinforced_mat = True restools.add_principal_stress_reinforced(res_obj) break if has_reinforced_mat is False: # fill PrincipalMax, PrincipalMed, PrincipalMin, MaxShear res_obj = restools.add_principal_stress_std(res_obj) else: # if a pure frd file was opened no analysis and thus no parent group # fill PrincipalMax, PrincipalMed, PrincipalMin, MaxShear res_obj = restools.add_principal_stress_std(res_obj) # fill Stats res_obj = restools.fill_femresult_stats(res_obj) else: error_message = ( "We have nodes but no results in frd file, " "which means we only have a mesh in frd file. " "Usually this happens for analysis type 'NOANALYSIS' " "or if CalculiX returned no results because " "of nonpositive jacobian determinant in at least one element.\n" ) FreeCAD.Console.PrintMessage(error_message) if analysis: analysis_object.addObject(result_mesh_object) if FreeCAD.GuiUp: if analysis: import FemGui FemGui.setActiveAnalysis(analysis_object) FreeCAD.ActiveDocument.recompute() else: FreeCAD.Console.PrintError( 'Problem on frd file import. No nodes found in frd file.\n') return res_obj