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()
Example #2
0
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
Example #3
0
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.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')
Example #4
0
def importAvs(filename, analysis=None, result_name_prefix=""):
    import ObjectsFem
    from feminout import importToolsFem

    TUNE = False
    if TUNE:
        import time
        cur = time.time()

    if analysis:
        doc = analysis.Document
    else:
        doc = FreeCAD.ActiveDocument

    m = read_avs_result(filename)

    result_mesh_object = None
    res_obj = None

    if TUNE:
        new = time.time()
        Console.PrintMessage("dtime 1:" + '%8.3f' % (new - cur) + "\n")
        cur = new

    if len(m["Nodes"]) > 0:
        mesh = importToolsFem.make_femmesh(m)
        if TUNE:
            new = time.time()
            Console.PrintMessage("dtime 2:" + '%8.3f' % (new - cur) + "\n")
            cur = new

        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 TUNE:
            new = time.time()
            Console.PrintMessage("dtime 3:" + '%8.3f' % (new - cur) + "\n")
            cur = new
        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))

                if TUNE:
                    new = time.time()
                    Console.PrintMessage("dtime 4:" + '%8.3f' % (new - cur) +
                                         "\n")
                    cur = new
                res_obj = ObjectsFem.makeResultMechanical(doc, results_name)
                res_obj.Mesh = result_mesh_object

                if TUNE:
                    new = time.time()
                    Console.PrintMessage("dtime 5:" + '%8.3f' % (new - cur) +
                                         "\n")
                    cur = new

                res_obj = importToolsFem.fill_femresult_mechanical(
                    res_obj, result_set)
                if analysis:
                    # need to be here, becasause later on, the analysis objs are needed
                    # see fill of principal stresses
                    analysis.addObject(res_obj)
                if TUNE:
                    new = time.time()
                    Console.PrintMessage("dtime 6:" + '%8.3f' % (new - cur) +
                                         "\n")
                    cur = new

                # more result object calculations
                from femresult import resulttools
                from femtools import femutils
                if not res_obj.MassFlowRate:
                    if res_mesh_is_compacted is False:
                        # first result set, compact FemMesh and NodeNumbers
                        res_obj = resulttools.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

                if TUNE:
                    new = time.time()
                    Console.PrintMessage("dtime 7:" + '%8.3f' % (new - cur) +
                                         "\n")
                    cur = new
                # fill DisplacementLengths
                res_obj = resulttools.add_disp_apps(res_obj)

                if TUNE:
                    new = time.time()
                    Console.PrintMessage("dtime 8:" + '%8.3f' % (new - cur) +
                                         "\n")
                    cur = new

                # fill vonMises
                mstress = []
                for nid in res_obj.NodeNumbers:
                    mstress.append(result_set["mises"][nid])
                res_obj.vonMises = mstress

                if TUNE:
                    new = time.time()
                    Console.PrintMessage("dtime 9:" + '%8.3f' % (new - cur) +
                                         "\n")
                    cur = new

                # fill principal stress
                prinstress1 = []
                prinstress2 = []
                prinstress3 = []
                for nid in res_obj.NodeNumbers:
                    pstr = result_set["pstress"][nid]
                    prinstress1.append(pstr[0])
                    prinstress2.append(pstr[1])
                    prinstress3.append(pstr[2])
                res_obj.PrincipalMax = prinstress1
                res_obj.PrincipalMed = prinstress2
                res_obj.PrincipalMin = prinstress3

                # fill Stats
                res_obj = resulttools.fill_femresult_stats(res_obj)

                if TUNE:
                    new = time.time()
                    Console.PrintMessage("dtime10:" + '%8.3f' % (new - cur) +
                                         "\n")
                    cur = new
        else:
            error_message = (
                "Nodes, but no results found in avs file. "
                "It means there only is a mesh but no results in avs file. "
                "Usually this happens for: \n"
                "- analysis type 'NOANALYSIS'\n"
                "- if FrontISTR returned no results "
                "(happens on nonpositive jacobian determinant in at least one element)\n"
                "- just no avs results where requestet in input file "
                "(neither 'node file' nor 'el file' in output section')\n")
            Console.PrintWarning(error_message)

        # create a result obj, even if we have no results but a result mesh in avs 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()

        if TUNE:
            new = time.time()
            Console.PrintMessage("dtime11:" + '%8.3f' % (new - cur) + "\n")
            cur = new

    else:
        Console.PrintError(
            "Problem on avs file import. No nodes found in avs file.\n")
        # None will be returned
        # or would it be better to raise an exception if there are not even nodes in avs file?

    return res_obj
	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 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