cancel
Showing results for 
Search instead for 
Did you mean: 

Get CAE.Result() or CAE.ResultAccess() for specific list of elements?

Phenom
Phenom

To all,

 

I am testing accessing NX.CAE results. While I am making (slow) progress in understanding the doc I cannot find anything obvious regarding accessing result for a given list of FE Element. I have concluded that the NX process is as follows;

 

  1. Create a CAE.Result for a given solution. The result contains all the results for that solution for all the elements (and nodes)
  2. Create a CAE.ResultAccess for the result created in step 1, for a specific load case and iteration and result type e.g in the CAE.Result get the stress for iteration #2 of load case #1.

Is this correct? Am I also correct in saying that one cannot create a CAE.Result or CAE.ResultAccess for a given list of elements?

 

if this is the case then does it mean that one needs to loop through the list of element one is interested as follows

 

Dim i As integer = 0
Dim listofFElmindices() As Integer
For each myelm As CAE.FEElement In mylistofFEelm
	listofFElmindices(i)=result.AskElementIndex(myelm.Label)
	i +=1
Next myelm

Dim thefinalresult() Double=resultaccess.AskElementResult(listofFElmindices)

 

 

Ultimatly I am interested in reporting the "Top N", say N=10, of a given list of element. The function AskNMinMaxLocation() will return the "top N" for all the elements in the accessed results. I need a way of "filtering"/creating a sub set of results

 

Any suggestions/pointers?

 

Thanks

Regards

Production: NX9.0.3.4, NX10.0.2.6
Development: VB.NET (amateur level !)
12 REPLIES

Re: Get CAE.Result() or CAE.ResultAccess() for specific list of elements?

Siemens Phenom Siemens Phenom
Siemens Phenom

Attached is a workshop I prepared for PLM World 2012. For element Nodal results like stress, you need to loop through the AskElementNodalResult call for each element. For elemental or nodal results, AskNodalResult and AskElementalResult are overloaded to take either a single ID or and array of IDs.

Re: Get CAE.Result() or CAE.ResultAccess() for specific list of elements?

Phenom
Phenom

Thanks for the supplied document JimB. Much appreciated. It looks like what I have coded so far is about right

 

I noticed

 

  1. the DeleteResultAccess & DeleteResultParameters in your doc after having created the CAE.RresultAccess variable. Will have to add these lines
  2. that AskElementResult can take an array of indices. Shouldn't be a problem to loop through the array of CAE.FEEElement to get the indices

 

Will play with a couple of elements to see what is returned from AskElementResult

 as I suspect the issue will be about sorting the array of returned results while keeping track of the element ID

 

Thanks

Regards

 

 

 

Production: NX9.0.3.4, NX10.0.2.6
Development: VB.NET (amateur level !)

Re: Get CAE.Result() or CAE.ResultAccess() for specific list of elements?

Phenom
Phenom

I have spent a few minutes looking at doc supplied by JimB and corrected two potential errors. However it seems that the issue is with accessing the results (CAE.ResultAccess)

Creating the result seems to be OK but the the access always returns 'Nothing'. So I am  bit stuck.

 

Is there a expert out there willing to tell me what is wrong with the way I am accessing the results, see function below?

 

Thanks

Regards

 

 

Dim theTargetSolution As CAE.SimSolution = CType(thesimulation.FindObject("Solution[" & theInputSOL103RSName & "]"), CAE.SimSolution)
Dim theresults As CAE.Result = GetResults(theTargetSolution)

'a test to check what is in the variable: theresulta

		REM For Each loadcase As CAE.BaseLoadcase In theresults.GetLoadcases

                REM theLw.WriteLine(vbNewLine + "  Loadcase: [" + loadcase.Name + "]")

                REM ' Loop through all iterations in the loadcase
                REM For Each iteration As CAE.BaseIteration In loadcase.GetIterations
                    REM theLw.WriteLine("    Iteration: [" + iteration.Name + _
                                    REM "] Type: [" + iteration.Type.ToString + "]")
				REM next iteration
		REM next loadcase

		Dim iIterID As Integer	= 0 ' 1st iteration !
		Dim theAccessedResult As CAE.ResultAccess = GetResultAccess(theresults,0,iIterID,1.0)

		If (theAccessedResult Is Nothing) Then
			theNXMessageBox.Show(theNXMessageBoxTitle, NXMessageBox.DialogType.Error, "Could not create 'Results Access' Object for Solution results")
			Exit Sub
		End if

		Dim elementIndex As Integer = theresults.AskElementIndex(189)
			Dim elemNodeIdxs() As Integer = Nothing
			Dim iNumComponents As Integer
			Dim elementValues() As Double = Nothing
			theAccessedResult.AskElementNodalResultAllComponents(elementIndex, elemNodeIdxs, _
															iNumComponents, elementValues)

			theLw.WriteLine(vbNewLine + "  Element 189 Stresses:")
			For i = 0 To elemNodeIdxs.Length - 1

				Dim nodeLabel As Integer = theresults.AskNodeLabel(elemNodeIdxs(i))
				theLw.WriteLine("    Node: [" + nodeLabel.ToString + "]")

				For j = 0 To iNumComponents - 1

					Dim valueIndex As Integer = i * iNumComponents + j

					theLw.WriteLine(" Component j: [" + j.ToString +"]  Value: [" + elementValues(valueIndex).ToString + "]")						
				Next j

			Next i

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

  Function GetResultAccess(ByVal results As CAE.Result, _
							ByVal loadCaseIdx As Integer, _
							ByVal iterationIdx As Integer, _ 
							ByVal scale As Double) As CAE.ResultAccess

        Dim part As BasePart = theSession.Parts.BaseWork

        Dim theResultManager As CAE.ResultManager = theSession.ResultManager()

        If (theResultManager Is Nothing) Then
            theNXMessageBox.Show(theNXMessageBoxTitle, NXMessageBox.DialogType.Error, "No valid ResultManager")
            Return Nothing
        End If
		
		Dim unit_stress As Unit = Nothing
		
        If part.PartUnits() = BasePart.Units.Millimeters Then 'MilliNewtonPerSquareMilliMeter
			unit_stress = CType(part.UnitCollection.FindObject("MilliNewtonPerSquareMilliMeter"), Unit)
        Else
			unit_stress = CType(part.UnitCollection.FindObject("PoundForcePerSquareInch"), Unit)
        End If
				
        Dim resultParameter As CAE.ResultParameters = theResultManager.CreateResultParameters

        Dim resultType As CAE.Result.Type
			resultType.Quantity = CAE.Result.Quantity.VonMisesStress
			resultType.Location = CAE.Result.Location.ElementNodal
			resultType.Section = CAE.Result.Section.Maximum

        Dim averaging As CAE.Result.Averaging
			averaging.DoAveraging = False
			averaging.AverageAcrossPropertyIds = False
			averaging.AverageAcrossMaterialIds = False
			averaging.AverageAcrossElementTypes = False
			averaging.AverageAcrossFeatangle = False
			averaging.AverageAcrossAnglevalue = 45.0
			averaging.IncludeInternalElementContributions = True

        resultParameter.SetLoadcaseIteration(loadCaseIdx, iterationIdx)
        resultParameter.SetResultType(resultType)
        resultParameter.SetResultComponent(CAE.Result.Component.VonMises)
        'resultParameter.SetResultDataSection(CAE.Result.Section.All)
        resultParameter.SetSectionPlyLayer(0, 0, 0)
        resultParameter.SetAveragingCriteria(averaging)
        resultParameter.SetCoordinateSystem(CAE.Result.CoordinateSystem.AbsoluteRectangular)
        resultParameter.SetElementValueCriterion(CAE.Result.ElementValueCriterion.Average)
        resultParameter.SetComplexCriterion(CAE.Result.Complex.Amplitude)
        resultParameter.SetPhaseAngle(0.0)
        resultParameter.SetScale(scale)
        resultParameter.SetUnit(unit_stress)

		Dim solResultsAccess As CAE.ResultAccess
		Try
			solResultsAccess = theResultManager.CreateResultAccess(results, resultParameter)
			solResultsAccess.SetParameters(resultParameter)
			Return solResultsAccess
		Catch ex As Exception
				'Return Nothing
			If (solResultsAccess Is Nothing) Then
				theNXMessageBox.Show(sMacroName, NXMessageBox.DialogType.Error, "Could not create Results Access Object for Solution results")
				Return Nothing
			End If
		End Try

    End Function

 

Production: NX9.0.3.4, NX10.0.2.6
Development: VB.NET (amateur level !)

Re: Get CAE.Result() or CAE.ResultAccess() for specific list of elements?

Phenom
Phenom

Just doing some line-by-line check and I think the issue might be with the line

.SetLoadcaseIteration which is Deprecated in NX8.0 (I am currently testing with N9) according to the doc

 

I am howwver struggling to undersand how to use CAE.ResultParameters.SetGenericResultType instead.

I am trying to access the VonMises stress for Load case ID =0  and a user given iteration (iter) (in the result)

 

Any suggestions?

 

Thanks

Regards

Production: NX9.0.3.4, NX10.0.2.6
Development: VB.NET (amateur level !)

Re: Get CAE.Result() or CAE.ResultAccess() for specific list of elements?

Experimenter
Experimenter

Hello,

 

Result Types cannot be created manually, as per the remarks in the API reference:

 

The attributes of this object reflect what 
is present in the result file. This object
can not be created externally as these cases
comes from the result file it will be created
automatically during result file loading

 

 

Here's a snippet of how I create my result parameters for the "Turbulent Energy" result type (the code is in C#, but it should be easy to translate to VB), assuming you obtain an iteration:

using QTT = NXOpen.CAE.Result.Quantity;
using COMP = NXOpen.CAE.Result.Component;
using NXOpen;
using NXOpen.CAE;
...
Session session;
SimPart workSimPart;
SimSolution solution;
Result solutionResult;
ResultParameters resultParams;
BaseResultType[] resultTypes;
ResultAccess resAc;

session = Session.GetSession();
resultMgr = session.ResultManager
workSimPart = (SimPart)session.Parts.BaseWork
solution = workSimPart.Simulation.ActiveSolution;
solutionResult = resultMgr.CreateSolutionResult(solution);

// Obtain iteration ...

resultTypes = iteration.GetResultTypes();
foreach (BaseResultType resultType in resultTypes)
{
    if (resultType.Quantity == QTT.TurbulenceEnergy)
    {
        resultParams = this.resultMgr.CreateResultParameters();
resultParams.SetGenericResultType(resultType);
resultParams.SetResultComponent(COMP.Scalar);
resAc = this.resultMgr.CreateResultAccess(
solutionResult,
resultParams
);
    }
}

And then you can query the results for all node IDs in your group -- you can't just pass in an FENode unfortunately. To obtain node IDs from a group with a given name, you can do something like this:

private int[] GetNodeIDsFromGroup(string groupName)
{
CaeGroupCollection groupCollection;
    TaggedObject[] taggedObjs;
    FENode node;
    int[] nodeIDs;
    int numObjs;
CaeGroup groupe; // "group" is a reserved keyword, I think

groupCollection = workSimPart.CaeGroups; // You can do this elsewhere in the file, obviously
    string identifier = String.Format("CaeGroup[{0}]", groupName);
    groupe = groupCollection.FindObject(identifier));

    taggedObjs = groupe.GetEntities();
    numObjs = taggedObjs.Length;
    nodeIDs = new int[numObjs];
    for (int i = 0; i < numObjs; i++)
    {
        node = (FENode)taggedObjs[i];
        nodeIDs[i] = node.Label;
    }
    return nodeIDs;
}

 

 

Re: Get CAE.Result() or CAE.ResultAccess() for specific list of elements?

Phenom
Phenom

Thanks for the input/pointers Selim. Will have a look a the code provided but it looks like it's kinf of what I have been playing/experimenting with.

 

Are we saying that there is not way of getting a specific result type (VM stress) for a given load case and iteration (in this load case) if one hasknows all the inputs required?

 

I have been playing with something, see below for top level idea, but it involves a lot of loop(ing).

 

I still haven't figured out on to get "top N value" but getting there slowly

 

Thanks

Regards

For Each loadcase As CAE.BaseLoadcase In theresults.GetLoadcases
	For Each iteration As CAE.BaseIteration In loadcase.GetIterations
		If iteration.Name = myselection then
			For Each baseResultType As CAE.BaseResultType In iteration.GetResultTypes
				Dim resultType As CAE.ResultType = TryCast(baseResultType, CAE.ResultType)
				Dim components() As CAE.Result.Component = Nothing
				resultType.AskComponents(components)
				
					If resultType.Quantity = CAE.Result.Quantity.Stress And _
					resultType.Location = CAE.Result.Location.ElementNodal Then
					
						For Each theFEElm As CAE.FEElement In arrFEElmInGroupTarget
								Dim elementIndex As Integer = theresults.AskElementIndex(iFEElmLabel)
								Dim elemNodeIdxs() As Integer = Nothing
								Dim iNumComponents As Integer
								Dim elementValues() As Double = Nothing
								theAccessedResult.AskElementNodalResultAllComponents(elementIndex, elemNodeIdxs, _
																			   iNumComponents, elementValues)
								
								For i = 0 To elemNodeIdxs.Length - 1

									Dim nodeLabel As Integer = theresults.AskNodeLabel(elemNodeIdxs(i))
									theLw.WriteLine("    Node: [" + nodeLabel.ToString + "]")
									
									'j = 13,27,41,55
									For j = 13 To iNumComponents - 1 Step 14
										Dim valueIndex As Integer = i * iNumComponents + j
										theLw.WriteLine("      valueIndex: " + valueIndex.ToString)
										theLw.WriteLine("      Component: [" + components(j).ToString + _
														"]  Value: [" + elementValues(valueIndex).ToString + "]")
									
										dim sDataLine As String = iFEElmLabel.ToString & "," & nodeLabel.ToString & "," & elementValues(valueIndex).ToString)
										ListFEElmLabelResult.Add(sDataLine)
										
									Next j		
							Next i
						Next theFEElm
						
					End if
			Next baseResultType
		End if
	Next iteration
Next loadcase

  

 

 

Production: NX9.0.3.4, NX10.0.2.6
Development: VB.NET (amateur level !)

Re: Get CAE.Result() or CAE.ResultAccess() for specific list of elements?

Experimenter
Experimenter

Are we saying that there is not way of getting a specific result type (VM stress) for a given load case and iteration (in this load case) if one hasknows all the inputs required?


You might be able to use the Find() method of the Iteration class, but I was never a big fan of those. You would pass in the journal identifier of the result type you're looking for. You should be able to get the identifier if you record a journal. 


I have been playing with something, see below for top level idea, but it involves a lot of loop(ing).


 If you know what loadcase and iteration you're going to want to query -- in my case it was the 0th loadcase and 0th iteration -- you can do something like: 

 

iteration = (Iteration)this.solutionResult.GetLoadcases()[0].GetIterations()[0];

Also not too sure what's going on in in the innermost loop with the components. Presumably, you know what the result component you want and you can just set it yourself in the ResultParamaters

 


I still haven't figured out on to get "top N value" but getting there slowly


I see you're dealing with Element-Nodal results, which makes things a little trickier because nodes are repeated. You can keep a dictionary of node IDs/labels with their corresponding result value -- this allows you to easily check if you've entered a key in it already. Pseudocode: 

 

nodalResultsMap = Dictionary<int, double>

foreach element in elements
{
resultAccess.AskElementNodalResult(element.Index, out nodeLabels, out values) for (int i = 0; i < nodeLabels.Length; i++)
{
if (!nodalResultsMap.containsKey(nodeLabels[i])
{
nodalResultsMap.Add(nodeLabels[i], values[i])
}
} }

You can then sort the dictionary pairs like this: (from http://stackoverflow.com/questions/23359070/order-a-dictionary-without-using-linq-orderby)

 

List<int, double> nodalResultsList = nodalResultsMap.ToList();
nodalResultsList.Sort((a, b) => a.Value.CompareTo(b.Value));
for (int i = 0; i < 10; i++)
{
// Do some stuff
}

 

Re: Get CAE.Result() or CAE.ResultAccess() for specific list of elements?

Phenom
Phenom

Thanks a lot for the detaiul response

 

1. Will look in the Find() option. However the programme is (will be 1 day!) very specific as it will only handle 1 type of solution which will always 1 Load Case (LC=0) but multiple iterations. The iterations are displayed to the user for selection. Hence the iteration IDs (or names) are known.

 

At the moment the name of all the iterations are displayed to the user for selection and the name of the selected iterations are passed to the main Sub. One can extract the iteration ID from the name, see below for simple idea

 

For sline As String In saSelectedIterationName
    'extra iteration ID from sline
   niter = 
   iteration =solutionResult.GetLoadcases(0).GetIterations(niter)
   'access result for LC=0, iteration, VM stress for elm ID=n
Next sline

2. ResultParameters. That's what I am after ultimatly. Haven't figure out how do it yet

 

resultParameter.SetResultComponent(CAE.Result.Component.VonMises)
'after the result access is defined ???
theResultsAccess.SetParameters(resultParameter)

3. Never used Dictionary. Read a tiny bit on them but never had time to learn to use them. Will definitly give it a go if cannot have the AskNMinMaxLocation() working !! (see query: http://community.plm.automation.siemens.com/t5/NX-Programming-Customization/Create-a-new-load-case-r...

 

Thanks a lot for the pointers

Production: NX9.0.3.4, NX10.0.2.6
Development: VB.NET (amateur level !)

Re: Get CAE.Result() or CAE.ResultAccess() for specific list of elements?

Experimenter
Experimenter

2. ResultParameters. That's what I am after ultimatly. Haven't figure out how do it yet


You're creating/obtaining the ResultAccess object fromResultParameters. Thus, Anything you specified in those parameters will be "applied" to the ResultAccess. In other words, what you're doing in your "GetResultAccess" function is fine. So, if you specified in your parameters that you want the Scalar component, then the ResultAccess.AskElementNodalResult method will give you the results for that component. In other words, you shouldn't need to use AskElementNodalResultAllComponents and then filter them to get the one you want. 

 

Unless, of course, you want the results for multiple components -- but I don't think that's what you want. 

 

So, use AskElementNodalResult, not AskElementNodalResultAllComponents, and you don't have to do any more processing. 


3. Never used Dictionary. Read a tiny bit on them but never had time to learn to use them.


They're pretty common in everyday programming and are actually pretty straightforward. You would benefir from reading about them AND it is also much easier to do then what you asked for in the other thread. But I suppose it's up to you.