cancel
Showing results for 
Search instead for 
Did you mean: 

Apply a Force on a Point in a Sim File

Creator
Creator

I am attempting to write an NX Open script (VB) after a long hiatus. I would like to apply forces/moments on a number of points in the sim using the by components option. 

 

I've recorded the action to a script file, but I've found the results to be very verbose, apparently executing the gui form for the load application. It is shown below.

 

Is there a more direct method to apply a force to a point in a simulation, which I can then extend to applying a moment to the same point, then wrap in a for loop?

 

I've tried looking through the documentation (which, granted I am not very familiar with) and searching through posts in this forum. It seemed for the action of creating a point the recorded script also generated the gui form inputs, but then I was able to find the nugget of code that actually creates the point and was able to strip out the superfluous stuff. I'm finding the generated create force script to be quite different.

 

Thanks.

 

Option Strict Off
Imports System
Imports NXOpen

Module NXJournal
Sub Main (ByVal args() As String) 

Dim theSession As NXOpen.Session = NXOpen.Session.GetSession()
Dim workSimPart As NXOpen.CAE.SimPart = CType(theSession.Parts.BaseWork, NXOpen.CAE.SimPart)

Dim displaySimPart As NXOpen.CAE.SimPart = CType(theSession.Parts.BaseDisplay, NXOpen.CAE.SimPart)

Dim markId1 As NXOpen.Session.UndoMarkId
markId1 = theSession.SetUndoMark(NXOpen.Session.MarkVisibility.Visible, "Start")

Dim simPart1 As NXOpen.CAE.SimPart = CType(workSimPart, NXOpen.CAE.SimPart)

Dim simSimulation1 As NXOpen.CAE.SimSimulation
simSimulation1 = simPart1.Simulation

Dim simBCBuilder1 As NXOpen.CAE.SimBCBuilder
simBCBuilder1 = simSimulation1.CreateBcBuilderForLoadDescriptor("ComponentForceField", "Force(1)", 1)

Dim propertyTable1 As NXOpen.CAE.PropertyTable
propertyTable1 = simBCBuilder1.PropertyTable

Dim setManager1 As NXOpen.CAE.SetManager
setManager1 = simBCBuilder1.TargetSetManager

theSession.SetUndoMarkName(markId1, "Force Dialog")

' ----------------------------------------------
'   Dialog Begin Force
' ----------------------------------------------
Dim markId2 As NXOpen.Session.UndoMarkId
markId2 = theSession.SetUndoMark(NXOpen.Session.MarkVisibility.Invisible, "Force")

theSession.DeleteUndoMark(markId2, Nothing)

Dim markId3 As NXOpen.Session.UndoMarkId
markId3 = theSession.SetUndoMark(NXOpen.Session.MarkVisibility.Invisible, "Force")

Dim objects1(0) As NXOpen.CAE.SetObject
Dim component1 As NXOpen.Assemblies.Component = CType(workSimPart.ComponentAssembly.RootComponent.FindObject("COMPONENT fem1 1"), NXOpen.Assemblies.Component)

Dim point1 As NXOpen.Point = CType(component1.FindObject("PROTO#.Points|ENTITY 2 1 1"), NXOpen.Point)

objects1(0).Obj = point1
objects1(0).SubType = NXOpen.CAE.CaeSetObjectSubType.None
objects1(0).SubId = 0
setManager1.SetTargetSetMembers(0, objects1)

Dim vectorFieldWrapper1 As NXOpen.Fields.VectorFieldWrapper
vectorFieldWrapper1 = propertyTable1.GetVectorFieldWrapperPropertyValue("CartesianMagnitude")

Dim unit1 As NXOpen.Unit = CType(workSimPart.UnitCollection.FindObject("Newton"), NXOpen.Unit)

Dim expression1 As NXOpen.Expression
expression1 = workSimPart.Expressions.CreateSystemExpressionWithUnits("10", unit1)

Dim expression2 As NXOpen.Expression
expression2 = workSimPart.Expressions.CreateSystemExpressionWithUnits("20", unit1)

Dim expression3 As NXOpen.Expression
expression3 = workSimPart.Expressions.CreateSystemExpressionWithUnits("30", unit1)

Dim fieldManager1 As NXOpen.Fields.FieldManager = CType(workSimPart.FindObject("FieldManager"), NXOpen.Fields.FieldManager)

Dim expressions1(2) As NXOpen.Expression
expressions1(0) = expression1
expressions1(1) = expression2
expressions1(2) = expression3
Dim vectorFieldWrapper2 As NXOpen.Fields.VectorFieldWrapper
vectorFieldWrapper2 = fieldManager1.CreateVectorFieldWrapperWithExpressions(expressions1)

propertyTable1.SetVectorFieldWrapperPropertyValue("CartesianMagnitude", vectorFieldWrapper2)

propertyTable1.SetTablePropertyWithoutValue("CylindricalMagnitude")

Dim nullNXOpen_Fields_VectorFieldWrapper As NXOpen.Fields.VectorFieldWrapper = Nothing

propertyTable1.SetVectorFieldWrapperPropertyValue("CylindricalMagnitude", nullNXOpen_Fields_VectorFieldWrapper)

propertyTable1.SetTablePropertyWithoutValue("SphericalMagnitude")

propertyTable1.SetVectorFieldWrapperPropertyValue("SphericalMagnitude", nullNXOpen_Fields_VectorFieldWrapper)

propertyTable1.SetTablePropertyWithoutValue("DistributionField")

Dim nullNXOpen_Fields_ScalarFieldWrapper As NXOpen.Fields.ScalarFieldWrapper = Nothing

propertyTable1.SetScalarFieldWrapperPropertyValue("DistributionField", nullNXOpen_Fields_ScalarFieldWrapper)

Dim propertyValue1(-1) As String
propertyTable1.SetTextPropertyValue("description", propertyValue1)

Dim simBC1 As NXOpen.CAE.SimBC
simBC1 = simBCBuilder1.CommitAddBc()

simBCBuilder1.Destroy()

theSession.DeleteUndoMark(markId3, Nothing)

theSession.SetUndoMarkName(markId1, "Force")

' ----------------------------------------------
'   Menu: Tools->Journal->Stop Recording
' ----------------------------------------------

End Sub
End Module
10 REPLIES

Re: Apply a Force on a Point in a Sim File

Phenom
Phenom

I cannot think of another but working your way through the recorded journal and start "hacking" it. Starting with obvious lines, see below. Having said that is it not a case of using NXOpen.CAE.SimBCBuilder?

 

Dim dForceFx, dForceFy,dForceFz,  As Double 'Could be taken from a user input
dForceFx = 10
dForceFy = 20
dForceFz = 30

Dim expressions1(2) As NXOpen.Expression
expressions1(0) = workSimPart.Expressions.CreateSystemExpressionWith​Units(dForceFx.ToString, unit1)
expressions1(1) = workSimPart.Expressions.CreateSystemExpressionWith​Units(dForceFy.ToString, unit1)
expressions1(2) = workSimPart.Expressions.CreateSystemExpressionWith​Units(dForceFzToString, unit1)
Production: NX9.0.3.4, NX10.0.2.6
Development: VB.NET (amateur level !)

Re: Apply a Force on a Point in a Sim File

Creator
Creator

Thanks for your response. I think you are right. I was hacking away at it last night and I think I understand it better.

 

The main call is to SimBCBuilder, specifically CreateBcBuilderForLoadDescriptor, which creates the force entry. Then the properties of the force are entered into a PropertyTable entry. Finally the force entry is committed to the database with a CommitAddBc() entry. I'm thinking now that I can reuse most of the PropertyTable, only modifying the point and the force components for each force to be input.

 

I still have a number of things to hack my way through/review documentation. Like do I really need all the markId entrys and what ever they do? Also, this entry is a bit confusing:

 

Dim component1 As NXOpen.Assemblies.Component = CType(workSimPart.ComponentAssembly.RootComponent.FindObject("COMPONENT fem1 1"), NXOpen.Assemblies.Component)

Dim point1 As NXOpen.Point = CType(component1.FindObject("PROTO#.Points|ENTITY 2 1 1"), NXOpen.Point)

It looks like, since I'm working in the Sim, that it needs to make a pointer to the Fem (as a component of the Sim "assembly"). It then finds the point onto which to apply the force. The portion "PROTO#.Points|ENTITY 2 1 1" seems to be refering to the point. I'm not sure how the 2 1 1 is worked out. I created 2 points in the Fem. I do know that this entry actually applies the force to the second point I created. To apply the force to the first point I would need to enter 2 2 1. So maybe the first digit is the number of points and the second digit is the point ID in the reverse order of creation? I don't know what the third digit is for. I'll have to record another session with more than 2 points to try to figure it out.

 

I wonder if there is an easier way to select the point based on the variable I will have created earlier in the full script (this one was just to figure out the force entry). But that variable was created in the context of the Fem, so I'm not sure if there is a way to use it from within the context of the Sim.

Re: Apply a Force on a Point in a Sim File

Honored Contributor
Honored Contributor

"I wonder if there is an easier way to select the point based on the variable I will have created earlier in the full script"

 

If you created a point object earlier in the journal, you can use it directly later in the journal; you don't need to "find" it again to reuse it.

Re: Apply a Force on a Point in a Sim File

Creator
Creator
Well, at your suggestion I tried it but received the error:

Selected objects are not in the same file as the Targetset.

I think it is because the point is created in the Fem (effectively a part), but must be selected from within the Sim (effectively an assembly). Points created in a Fem are a bit odd in that they don't show up in the Part Navigator. So they have no name and can only be edited by contextual menu. I'm not sure if that makes them more difficult to work with for scripting, hence the need for the FindObject("PROTO#.Points|ENTITY 2 1 1").

Re: Apply a Force on a Point in a Sim File

Honored Contributor
Honored Contributor

Is the new point object created in the fem file? If so, the sim file probably needs the reference to the occurrence object in the sim file rather than the prototype point object in the fem file. To get this occurrence object, you can use the fem component's .FindOccurrence method.

 

Some psuedocode:

myFemPoint = create point object in FEM file
myFemComponent = reference to FEM component in SIM assembly file

mySimPoint = myFemComponent.FindOccurrence(myFemPoint)

 

Re: Apply a Force on a Point in a Sim File

Creator
Creator

Thanks. That should really help in making the code more traceable. Here is the relevant snippet from the full script:

 

Dim componentFem As NXOpen.Assemblies.Component = CType(workSimPart.ComponentAssembly.RootComponent.FindObject("COMPONENT fem1 1"), NXOpen.Assemblies.Component)

Dim loadPoint1 As NXOpen.Point = componentFem.FindOccurrence(point1)

(Ignore the variable names for now. I'm in the middle of combining codes from two recorded sessions and just hacking it together for now, so some of the variable names may be a bit nonsensical.)

 

I bet I could also use the FindOccurrence method to refer to the Fem directly instead of using the FindObject method, which is a bit messy as it relies on knowledge of the Fem file name.

 

 

Re: Apply a Force on a Point in a Sim File

Honored Contributor
Honored Contributor

You can query an assembly file to get references to the components. Here is one example:

http://solutions.industrysoftware.automation.siemens.com/view.php?si=nx_api1504

Re: Apply a Force on a Point in a Sim File

Creator
Creator
Thanks for the link. It doesn't seem to work for a Sim (the reported error is: The part file is not a .prt file). I'll try it for a simple assembly and see what I can glean. Then maybe I can make a modified version that references SimParts and FemParts instead of regular Parts

Re: Apply a Force on a Point in a Sim File

Honored Contributor
Honored Contributor

For sim and fem files, you will need to change the "Part" references to "BasePart" references (or CAEPart if you know for sure that you will be handling a sim or fem file). For example:

Dim prototype As Part

becomes

Dim prototype As BasePart

The BasePart object type will handle sim and fem files, the Part object type only refers to CAD files where the extension is ".prt". Once you have a base part you can use the TypeOf operator or the .GetType property to determine if it is a part file or CAE part file (if necessary).