Showing results for 
Search instead for 
Do you mean 
Reply
Solved! Go to solution

Writing solution results to a file - memory allocation problem

I’ve written a program, vb .net, which get the nodal results for a group of beam elements via the NXOpen.CAE Result and ResultAccess classes and write them to Microsoft Excel in the same way as one can do via the “Identify Results” function when post processing the results.

 

When the program is running the memory allocation of the virtual memory increases rapidly and the process soon becomes slow. When I preform the same operation manually via the “Identify Results”, NX does not allocate the same amount of memory and the “export” process to Excel is much quicker than for my code, all results for the selected elements are written at once instead of writing one result at a time.

 

The memory allocation problem did I solve by deleting the result and then load them before the program continued, for example the next load case. This process will be time consuming if there are many load cases.

 

Question: How does the function “Identify Results” in the Post Processing work? It is both quicker writing to Excel and less memory is allocated than for my code which use the ResultAccess class.

 

Thanks’ in advance

 

Regards

Mikael

2 REPLIES
Solution
Solution
Accepted by topic author Tau_Beräkning
‎08-26-2015 04:32 AM

Re: Writing solution results to a file - memory allocation problem

Make sure you are only instantiating Result and ResultAccess objects once, then loop over the elements using the same object.

 

Each time you instantiate a Result object, it's like attaching an additional result file when running interactively.

 

 

Re: Writing solution results to a file - memory allocation problem

Hello Michael,

 

I'm trying to do something similar as you. I'm obtaining the element nodal result from shell elements from NX (using the NX functionality to access the results in the .op2)  and I'm writing them to a text file (in fact a SDRC universal file format). This works fine for 2D shell elements (I can share the code if you are interested).

Now I want to obtain the beam resultants for 1D beam elements. The results I obtain through the code are not what I expect them to be. I use the following code to define the result using ResultAccess class. It makes a call to the function Get1DResultFromDatabase(). I think my problem lies in the resultParameters_Beam (which is a CAE.ResultParameters).

    Sub ExportSingle1DResultFromDatabase(ByVal SolutionNumber As Integer, ByVal LoadcaseNumber As Integer, ByVal ResultNumber As Integer, ByVal FileName As String)
        'So that the user can start counting at 1
        SolutionNumber = SolutionNumber - 1
        LoadcaseNumber = LoadcaseNumber - 1
        ResultNumber = ResultNumber - 1

        Dim theSession As Session = Session.GetSession()
        Dim workSimPart As CAE.SimPart = CType(theSession.Parts.BaseWork, CAE.SimPart)
        Dim displaySimPart As CAE.SimPart = CType(theSession.Parts.BaseDisplay, CAE.SimPart)
        Dim BaseFemPart As CAE.FemPart = Nothing
        BaseFemPart = CType(workSimPart.FemPart, CAE.FemPart)
        Dim theLW As NXOpen.ListingWindow = theSession.ListingWindow()
        theLW.Open()

        If (DEBUG) Then theLW.WriteLine("Number of elements is: " + BaseFemPart.BaseFEModel.FeelementLabelMap.NumElements.ToString())


        Dim simSimulation1 As CAE.SimSimulation = CType(workSimPart.FindObject("Simulation"), CAE.SimSimulation)

        ' The SimSolutionCollection contains all solutions.
        Dim SimSolution As CAE.SimSolutionCollection = simSimulation1.Solutions
        'The following function creates an array, so they can all be individually called.
        Dim SimSolutions() As CAE.SimSolution = SimSolution.ToArray

        Dim solutionResult1 As CAE.SolutionResult
        solutionResult1 = theSession.ResultManager.CreateSolutionResult(SimSolutions(SolutionNumber))

        'Get the number of loadcases from the result just loaded
        Dim NumLoadCases As Integer = solutionResult1.AskNumLoadcases()
        theLW.WriteLine("The number of LoadCases in this result is: " & NumLoadCases.ToString())

        'The following code runs through the LoadCases of the solution and prints their name and converts them to a string
        Dim BaseLoadCases() As CAE.BaseLoadcase = solutionResult1.GetLoadcases()

        If (DEBUG) Then
            For Each BaseLC As CAE.BaseLoadcase In BaseLoadCases
                theLW.WriteLine(BaseLC.Name)
            Next
        End If

        Dim loadcase1 As CAE.Loadcase = CType(BaseLoadCases(LoadcaseNumber), CAE.Loadcase)

        Dim Iterations() As CAE.BaseIteration = loadcase1.GetIterations()
        Dim iteration1 As CAE.Iteration = CType(Iterations(0), CAE.Iteration)

        Dim ResultTypes() As CAE.BaseResultType = Iterations(0).GetResultTypes()
        Dim resultType1 As CAE.ResultType = CType(ResultTypes(ResultNumber), CAE.ResultType)

        Dim MyResult As CAE.Result
        MyResult = CType(solutionResult1, CAE.Result)

        '------------------------------------------------------------------------------------------------------------------
        '------------------------------------------------------------------------------------------------------------------
        '------------------------------------------------------------------------------------------------------------------
        '------------------------------------------------------------------------------------------------------------------
        '------------------------------------------------------------------------------------------------------------------


        Dim StressComponentId As NXOpen.CAE.Result.Component
        StressComponentId = CAE.Result.Component.Axial

        If (DEBUG) Then theLW.WriteLine(resultType1.Name)
        If (DEBUG) Then theLW.WriteLine(resultType1.UserName)

        Dim resultParameters_Beam As CAE.ResultParameters
        resultParameters_Beam = theSession.ResultManager.CreateResultParameters()
        'The following line sets the loadcase implicitly
        resultParameters_Beam.SetGenericResultType(resultType1)
        resultParameters_Beam.SetResultComponent(StressComponentId)
        resultParameters_Beam.SetBeamResultsInLocalCoordinateSystem(True)
        resultParameters_Beam.SetCoordinateSystem(CAE.Result.CoordinateSystem.Local)
        'resultParameters_Beam.MakeElementResult(False)

        Dim test As CAE.Result.CoordinateSystem = resultParameters_Beam.GetCoordinateSystem
        theLW.WriteFullline(test.ToString)

        resultParameters_Beam.SetResultBeamSection(CAE.Result.Section.All)



        'Ideally I can obtain the unit from the database...
        Dim unit1 As NXOpen.Unit = CType(workSimPart.UnitCollection.FindObject("Newton"), NXOpen.Unit)
        'Dim unit1 As NXOpen.Unit = CType(workSimPart.UnitCollection.FindObject("StressNewtonPerSquareMilliMeter"), NXOpen.Unit)
        'theLW.WriteLine("WARNING: Results written as MPa")

        resultParameters_Beam.SetUnit(unit1)

        Dim MyResultsAccess As CAE.ResultAccess
        MyResultsAccess = theSession.ResultManager.CreateResultAccess(MyResult, resultParameters_Beam)

        theLW.WriteLine("Exporting subcase: " + loadcase1.Name + " result " + resultType1.Name)

        Dim result() As String = Nothing
        result = Get1DResultFromDatabase(solutionResult1, loadcase1, LoadcaseNumber, MyResultsAccess)

        'write data
        Dim objStreamWriter As StreamWriter
        objStreamWriter = New StreamWriter(FileName)

        theLW.WriteFullline("Writing results to file " + FileName)

        For jj As Integer = 0 To result.Length - 1
            objStreamWriter.WriteLine(result(jj))
        Next
        objStreamWriter.Close()

        theSession.ResultManager.DeleteResultAccess(MyResultsAccess)
        theSession.ResultManager.DeleteResultParameters(resultParameters_Beam)

    End Sub

This is the code for Get1DResultFromDatabase(solutionResult1, loadcase1, LoadcaseNumber, MyResultsAccess):

Function Get1DResultFromDatabase(ByVal SolutionResult As CAE.SolutionResult, ByVal Loadcase As CAE.Loadcase, ByVal LoadcaseNumber As Integer, ByVal MyResultsAccess As CAE.ResultAccess) As String()
        Dim theSession As Session = Session.GetSession()
        Dim theLW As NXOpen.ListingWindow = theSession.ListingWindow()
        If (DEBUG) Then
            theLW.Open()
        End If

        'This could be done more elegant. now assume all elements are linear beams, and thus 3 lines are taken up in the universal file. At the end, the empty lines are truncated
        'Dim Result_Unv(BaseFemPart.BaseFEModel.FeelementLabelMap.NumElements * 3) As String
        Dim Result_Unv(SolutionResult.AskNumElements * 3 + 15) As String

        'Heading of the universal file
        Result_Unv(0) = "    -1"
        Result_Unv(1) = String.Format("{0,6}", "2414")
        Result_Unv(2) = String.Format("{0,10}", Str(LoadcaseNumber))
        'NX looks for the LOADCASE_NAME_KEY and uses this as the subcase name when it imports
        Result_Unv(3) = String.Format("{0,10}", "LOADCASE_NAME_KEY " + SolutionResult.Name)
        Result_Unv(4) = String.Format("{0,10}", "3")
        'NX looks for the RESULT_NAME_KEY and uses this as the result name when it imports
        Result_Unv(5) = "RESULT_NAME_KEY " + Loadcase.Name
        Result_Unv(6) = MyResultsAccess.GetParameters.GetGenericResultType.Name
        Result_Unv(7) = "Creation time " & Date.Now.ToShortDateString & "    " & TimeOfDay.ToString.Substring(12, 8)
        Result_Unv(8) = "-- ID line4" 'Extra info can be added here
        Result_Unv(9) = "-- ID line5" 'Extra info can be added here
        Result_Unv(10) = String.Format("{0,10}", "1") & String.Format("{0,10}", "1") & String.Format("{0,10}", "3") & String.Format("{0,10}", "4") & String.Format("{0,10}", "2") & String.Format("{0,10}", "6")
        Result_Unv(11) = String.Format("{0,10}", "-10") & String.Format("{0,10}", "0") & String.Format("{0,10}", "1") & String.Format("{0,10}", "1") & String.Format("{0,10}", "17") & String.Format("{0,10}", "0") & String.Format("{0,10}", "0") & String.Format("{0,10}", "0")
        Result_Unv(12) = String.Format("{0,10}", "2") & String.Format("{0,10}", "0")
        Result_Unv(13) = String.Format("{0,13}", 0.ToString("0.000000E+00")) & String.Format("{0,13}", 0.ToString("0.000000E+00")) & String.Format("{0,13}", 0.ToString("0.000000E+00")) & String.Format("{0,13}", 0.ToString("0.000000E+00")) & String.Format("{0,13}", 0.ToString("0.000000E+00")) & String.Format("{0,13}", 0.ToString("0.000000E+00"))
        Result_Unv(14) = String.Format("{0,13}", 0.ToString("0.000000E+00")) & String.Format("{0,13}", 0.ToString("0.000000E+00")) & String.Format("{0,13}", 0.ToString("0.000000E+00")) & String.Format("{0,13}", 0.ToString("0.000000E+00")) & String.Format("{0,13}", 0.ToString("0.000000E+00")) & String.Format("{0,13}", 0.ToString("0.000000E+00"))

        Dim LineNum As Integer = 15
        Dim LastEntry As String = Nothing
        Dim Shape As CAE.ElementTypes.Shape = Nothing
        Dim LastShape As CAE.ElementTypes.Shape = Nothing

        For ii As Integer = 1 To SolutionResult.AskNumElements
            Dim NodeIndex() As Integer = Nothing
            Dim NumComponents As Integer = Nothing
            Dim NodalData() As Double = Nothing
            'If (DEBUG) Then theLW.WriteLine("Running element with index: " & Str(ii))

            Shape = SolutionResult.AskElementShape(ii)

            'without this case, the code is slightly faster , but programming wise, this looks better and easier to extend to other element types and quadratic elements
            Select Case True
                Case Shape.Equals(CAE.ElementTypes.Shape.Line)

                    If Str(SolutionResult.AskElementLabel(ii)).Trim = "165" Then

                        MyResultsAccess.AskElementNodalResultAllComponents(ii, NodeIndex, NumComponents, NodalData)
                        'MyResultsAccess.AskElementResultAllComponents(ii, NodalData)

                        theLW.WriteFullline("Results for element with label: " + Str(SolutionResult.AskElementLabel(ii)))
                        theLW.WriteFullline("NodeLabels for element:")
                        For i As Integer = 0 To NodeIndex.Length - 1
                            theLW.WriteFullline(Str(SolutionResult.AskNodeLabel(NodeIndex(i))))
                        Next
                        theLW.WriteFullline("NumComponents: " + Str(NumComponents))

                        For i As Integer = 0 To NodalData.Length - 1
                            theLW.WriteFullline(Str(NodalData(i)))
                        Next

                        Dim Mycomponent() As CAE.Result.Component = Nothing
                        Dim teststr() As String
                        teststr = MyResultsAccess.AskResultComponents(Mycomponent)

                        For i As Integer = 0 To Mycomponent.Length - 1
                            theLW.WriteFullline(Mycomponent(i).ToString)
                        Next

                        For i As Integer = 0 To teststr.Length - 1
                            theLW.WriteFullline(teststr(i))
                        Next

                        theLW.WriteFullline("-------------------------------------------------------------------------------------------")

                    End If

                    'Result_Unv(LineNum) = String.Format("{0,10}", Str(SolutionResult.AskElementLabel(ii))) & String.Format("{0,10}", "1") & String.Format("{0,10}", "2") & String.Format("{0,10}", "6")
                    ''Ideas format is: 6E13.5
                    'Result_Unv(LineNum + 1) = String.Format("{0,13}", (NodalData(0)).ToString("0.00000E+00")) & String.Format("{0,13}", (NodalData(3)).ToString("0.00000E+00")) & String.Format("{0,13}", (NodalData(1)).ToString("0.00000E+00")) & String.Format("{0,13}", (NodalDataBot(5)).ToString("0.00000E+00")) & String.Format("{0,13}", (NodalDataBot(4)).ToString("0.00000E+00")) & String.Format("{0,13}", (NodalDataBot(2)).ToString("0.00000E+00"))
                    'Result_Unv(LineNum + 2) = String.Format("{0,13}", (NodalData(0)).ToString("0.00000E+00")) & String.Format("{0,13}", (NodalData(3)).ToString("0.00000E+00")) & String.Format("{0,13}", (NodalData(1)).ToString("0.00000E+00")) & String.Format("{0,13}", (NodalDataTop(5)).ToString("0.00000E+00")) & String.Format("{0,13}", (NodalDataTop(4)).ToString("0.00000E+00")) & String.Format("{0,13}", (NodalDataTop(2)).ToString("0.00000E+00"))
                    'LineNum = LineNum + 3
                    'LastShape = Shape

                Case Shape.Equals(CAE.ElementTypes.Shape.Tri)

                Case Shape.Equals(CAE.ElementTypes.Shape.Quad)

                Case Shape.Equals(CAE.ElementTypes.Shape.Point)

                Case Else
                    theLW.Open()
                    theLW.WriteLine("Element type " + Shape.ToString + " is not defined in ExportResultsFromDatabase")
            End Select

        Next

        Select Case True
            Case LastShape.Equals(CAE.ElementTypes.Shape.Tri)
                ReDim Preserve Result_Unv(LineNum - 7)
                Result_Unv(Result_Unv.Length - 1) = "    -1"
            Case LastShape.Equals(CAE.ElementTypes.Shape.Quad)
                ReDim Preserve Result_Unv(LineNum - 9)
                Result_Unv(Result_Unv.Length - 1) = "    -1"
            Case Shape.Equals(CAE.ElementTypes.Shape.Line)

            Case Shape.Equals(CAE.ElementTypes.Shape.Point)

            Case Else
                theLW.Open()
                theLW.WriteLine("Element type " + Shape.ToString + " is not defined in ExportResultsFromDatabase")
        End Select

        Result_Unv(Result_Unv.Length - 1) = "    -1"

        Return Result_Unv
    End Function

Have you perhaps experienced something similar?

 

Thanks in advance

Frederik