Examples#

Some examples require external input files. Before you start, please follow the link in the Example Scripts section to download the zip file with model and result files.

Example 01 - Using hm and hm.entities module#

This is an example of automating a complete preprocessing task. The code consists of the following actions:

  1. Loading the pedal.hm model.

  2. Creating a material and assigning some properties (data names). Afterwards, a new property is created where some data names and the new material are assigned. This property is assigned to the component ID 1.

  3. Meshing using tetramesh with element size of 0.8.

  4. Creating a rigid link element.

  5. Applying constraints on the independent node of newly created rigid link.

  6. Applying pressure load on interactively selected elements.

  7. Performing an action (rotation or translation) selected by the user via a custom GUI defined via OptionsGui class.

  1# ---Imports-----------
  2import hm
  3import hm.entities as ent
  4import os
  5import hwx.gui as gui
  6
  7class OptionsGui():
  8    '''
  9
 10    Class for the custom GUI for selecting options for example.
 11
 12    '''
 13    def __init__(self, model:hm.Model):
 14
 15        # Initialization of some attributes
 16        self.option = 1 # Option
 17        self.model = model #Passing Model instance to class
 18        # Constructing the GUI adding option combo box and run/close buttons
 19        optionLabel=gui.Label(text="Options:")
 20        self.optionCombo=gui.ComboBox(((1, "Translate Elements"), (2, "Rotate Elements"),),command=self.option_selection)
 21
 22        closeButton = gui.Button("Close", command=self.on_close)
 23        runButton = gui.Button("Run", command=self.on_run)
 24
 25        self.mainFrame = gui.GridFrame(
 26            (optionLabel, self.optionCombo),
 27            (closeButton, runButton),
 28        )
 29        self.dialog = gui.Dialog(caption="Export Dialog", width=230, height=150)
 30        self.dialog.addChildren(self.mainFrame)
 31        self.dialog.show()
 32
 33    def option_selection(self, event):
 34        '''
 35        Helping function
 36        Passing to option attribute the combo box value, by changing events (i.e., options)
 37        '''
 38        self.option = event.value
 39
 40    def on_close(self):
 41        '''
 42        Helping function
 43        Closing GUI
 44        '''
 45        self.dialog.Hide()
 46
 47    def on_run(self):
 48        '''
 49        Helping function
 50        Running GUI functionality.
 51        '''
 52        print(f"Option {self.option} will run...")
 53        option_runner(model=self.model, opt=self.option)
 54        print(f"Option {self.option} finished!")
 55        self.dialog.Hide()
 56
 57def main():
 58
 59    '''
 60
 61    Function for the main procedure of the example
 62
 63    '''
 64
 65    # Grabbing a model instance by name
 66    session = hm.Session()
 67    model = hm.Model(session.get_all_models()[0])
 68
 69    # Reading HyperMesh model
 70    script_dir = os.path.dirname(os.path.abspath(__file__))
 71    model.hm_answernext("yes")
 72    model.readfile(os.path.join(script_dir,"pedal.hm"),0)
 73
 74    # Material Creation
 75    mat1 = ent.Material(model)
 76    mat1.name = "Steel"
 77    mat1.cardimage = "MAT1"
 78    mat1.E = 21e04
 79    mat1.Nu = 0.3
 80    mat1.Rho = 7850
 81
 82    # Property Creation and Material Assignment to Property
 83    prop1 = ent.Property(model)
 84    prop1.name = "Prop"
 85    prop1.cardimage = "PSOLID"
 86    prop1.materialid = mat1
 87
 88    # Assign Properties to Component with id=1
 89    compID = 1
 90    comp1 = ent.Component(model, compID)
 91    comp1.propertyid = prop1
 92
 93    # Create Tetramesh
 94    node_col = hm.Collection(model, ent.Node, populate=False)
 95    str_array1 = hm.hwStringList(
 96        [
 97            "pars: upd_shell fix_comp_bdr post_cln elem_order = 2 delaunay el2comp=3 fill_void=1 tet_clps='0.100000,0.300000, 0.500000, 1.000000, 0.380000, 0.100000'",
 98            "tet: 35 1.3 -1 0.014 0.8 0 0 1",
 99            "2d: 1 0 4 0.01 0.001 30 1",
100        ]
101    )
102    solids_col = hm.Collection(model, ent.Solid)
103    model.tetmesh(
104        collection1=solids_col,
105        mode1=1,
106        collection2=node_col,
107        mode2=5,
108        string_array=str_array1,
109    )
110
111    # Create a rigid link element
112
113    # Independent Node for rigidlink
114    indNode = ent.Node(model, 1462)
115    # Dependent Nodes for rigidlink
116    nodelist = (
117        list(range(1420, indNode.id))
118        + list(range(indNode.id + 1, 1642))
119        + list(range(74051, 74064))
120        + list(range(74214, 74300))
121        + list(range(74356, 74369))
122        + list(range(74980, 75066))
123    )
124    filtNode = hm.FilterByEnumeration(ent.Node, nodelist)
125    depnodes = hm.Collection(model, filtNode)
126    model.rigidlink(
127        independent=indNode, collection=depnodes, dofs=123456
128    )  # rigid link creation
129
130    # Applying constraint to independent node of rigid link.
131    indNode_col = hm.Collection([indNode])
132    model.loadcreateonentity_curve(
133        collection=indNode_col,
134        config=3,
135        type=1,
136        comp1=0,
137        comp2=0,
138        comp3=0,
139        comp4=0,
140        comp5=0,
141        comp6=0,
142        x_loc=0,
143        y_loc=0,
144        z_loc=0,
145        curve_id=0,
146        x_scale=0,
147    )
148
149    # Creating a Load collection with the name "Pressure" and we apply it on selected elements
150    loadcol2 = ent.Loadcol(model)
151    loadcol2.name = "Pressure"
152
153    elemes = hm.CollectionByInteractiveSelection(model, ent.Element)
154    filt = hm.FilterByCollection(ent.Node, ent.Element)
155    nele = hm.Collection(model, filt, elemes)
156
157    model.pressuresonentity_curve(
158        collection=elemes,
159        facenodes=nele,
160        x_comp=0,
161        y_comp=0,
162        z_comp=-1,
163        magnitude=1,
164        breakangle=30,
165        onface=1,
166        xlocation=0,
167        ylocation=0,
168        zlocation=0,
169        curve_id=0,
170        x_scale=0,
171    )
172
173    # Setting up the loadstep
174    loadStep1 = ent.Loadstep(model)
175    loadStep1.OS_TYPE = 1  # Linear Static
176    loadStep1.OS_SPCID = model.get(hm.Entity(ent.Loadcol, 1))
177    loadStep1.OS_LOADID = loadcol2
178
179    # Two options for our geometry. Translation or rotation of elements. Selected and run via GUI
180    OptionsGui(model)
181
182def option_runner(model:hm.Model, opt:int):
183    if opt == 1:
184        # Translate elements
185        tranElem = hm.CollectionByInteractiveSelection(model, ent.Element)
186        model.translatemark(collection=tranElem, vector=[0.0, 1.0, 0.0], distance=0.5)
187    elif opt == 2:
188        # Rotate component
189        comp1 = hm.Collection(model, ent.Component, [1])
190        RotAx = [0.0, 0.0, 1.0]
191        PlaneOr = [0.0, 0.0, 0.0]
192        model.rotatemark(
193            collection=comp1, plane_normal=RotAx, plane_base=PlaneOr, angle=30
194        )
195
196if __name__ == "__main__":
197    main()

Example 02 - Querying entity attributes#

The first part of the code creates a collection of all properties and queries their attributes, including the attributes of the assigned material. The data is stored in prop_data list and printed in the console using the prettytable library.

In the second part, the code prompts the user to interactively select some elements. It then loops through the returned collection and extracts various elements attributes. It stores the data in the elem_data list and prints it in the console using the prettytable library.

  1import hm
  2import hm.entities as ent
  3import prettytable as pt
  4
  5model = hm.Model()
  6
  7# Create a collection of all properties in the model
  8prop_data = list()
  9props = hm.Collection(model, ent.Property)
 10
 11# Printing a table of properties and their respective material if exist
 12for p in props:
 13    prop_name = p.name
 14    prop_id = p.id
 15    prop_cardimage = p.cardimage
 16    if prop_cardimage == "PSHELL":
 17        prop_thickness = p.PSHELL_T
 18    else:
 19        prop_thickness = "-"
 20    if p.materialid:
 21        mat = p.materialid
 22        mat_name = mat.name
 23        mat_id = mat.id
 24        mat_cardimage = mat.cardimage
 25    else:
 26        mat_name = "-"
 27        mat_id = "-"
 28        mat_cardimage = "-"
 29    prop_data.append(
 30        [
 31            prop_name,
 32            prop_id,
 33            prop_cardimage,
 34            prop_thickness,
 35            mat_name,
 36            mat_id,
 37            mat_cardimage,
 38        ]
 39    )
 40
 41tab = pt.PrettyTable(
 42    [
 43        "Prop Name",
 44        "Prop ID",
 45        "Prop Cardimage",
 46        "Prop Thickness",
 47        "Mat Name",
 48        "Mat ID",
 49        "Mat Cardimage",
 50    ]
 51)
 52
 53tab.add_rows(prop_data)
 54print(tab)
 55
 56# Create a collection of elements by interactive selection
 57elems = hm.CollectionByInteractiveSelection(model, ent.Element)
 58
 59# Create a table of elements along with following attributes: id, configuration number, property name, material name, number of nodes, and jacobian.
 60elem_data = list()
 61
 62for e in elems:
 63    el_id = e.id
 64    el_conf = e.config
 65    el_ncount = e.nodecount
 66    if e.propertyid:
 67        el_prop_name = e.propertyid.name
 68    else:
 69        el_prop_name = "-"
 70    if e.materialid:
 71        el_mat_name = e.materialid.name
 72    else:
 73        el_mat_name = "-"
 74    if e.jacobian:
 75        el_jac = e.jacobian
 76    else:
 77        el_jac = "-"
 78    elem_data.append(
 79    [
 80        el_id,
 81        el_conf,
 82        el_ncount,
 83        el_prop_name,
 84        el_mat_name,
 85        el_jac
 86    ]
 87)
 88
 89tab2 = pt.PrettyTable(
 90    [
 91        "Elem ID",
 92        "Elem Config",
 93        "Elem NodeCount",
 94        "Elem Prop",
 95        "Elem Mat",
 96        "Jacobian",
 97    ]
 98)
 99tab2.add_rows(elem_data)
100print(tab2)
../../_images/image_prop.png

Figure 1. Querying elements’ and properties’ data

Example 03 - Creating a node at CoG of every component#

The code imports the HyperMesh bumper.hm model, creates and defines a new material entity, and then assigns it to a newly created property entity. A collection of all components is then created and the code loops over the components in the collection to perform the following actions on each component:

  • assigning the property to the component

  • calculating the CoG (Center of Gravity) of the component

  • creating a new node and positioning it at the CoG location

 1import hm
 2import hm.entities as ent
 3
 4model = hm.Model()
 5
 6# Importing the model in HyperMesh
 7datadir = rf"{hm.altair_home}\demos\hm"
 8model.hm_answernext("yes")
 9model.readfile(
10    filename=os.path.join(datadir, "bumper.hm"),
11    load_cad_geometry_as_graphics=0,
12)
13
14# Create a material with name 'Al' and properties of Aluminum
15mat1 = ent.Material(model)
16mat1.name = "Al"
17mat1.cardimage = "MAT1"
18mat1.E = 7e04
19mat1.Nu = 0.3
20mat1.Rho = 2700
21
22# Create a property with the name 'central_prop' and assign 'Al' material to it
23prop1 = ent.Property(model)
24prop1.name = "central_prop"
25prop1.cardimage = "PSHELL"
26prop1.materialid = mat1
27prop1.PSHELL_T = 1.0
28
29# Create a collection of all components
30comp_col = hm.Collection(
31    model, ent.Component
32)
33
34# Assign the property to all components, compute for each component the center of gravity (CoG) and a create a node to cog
35for comp in comp_col:
36    comp.propertyid = prop1
37    ccol = hm.Collection(model, ent.Component, [comp.id])
38    status, result = model.hm_getcog(ccol)
39    nodeNew = ent.Node(model)  # Create a new node
40    nodeNew.localcoordinates = result.coord  # Place the node at CoG
../../_images/image_cog.png

Figure 2. Creating nodes at components COGs

Example 04 - Creating a new component per solid (includes “performance” API)#

The example shows how to organize each solid entity in the model into individual component using the HyperMesh movemark() function. The code also includes a custom performance() function which is used before and after the loop to turn on/off certain functionalities to speed up the process. Before entering the for loop, the function disables the graphics refreshing, writing into the command file, entity highlighting, and browser update. After the loop, the functionalities are reenabled.

 1import hm
 2import hm.entities as ent
 3
 4
 5def main():
 6
 7    model = hm.Model()
 8
 9    solidcol = hm.Collection(model, ent.Solid)
10
11    # Enable performance boost
12    performance(model, True)
13
14    # Create a component for each solid
15    for solid in solidcol:
16        comp = ent.Component(model)
17        comp.name = f"solid_{solid.id}"
18        # Organize (move) the solid to the new component
19        solid_in_col = hm.Collection([solid])
20        model.movemark(collection=solid_in_col, name=f"solid_{solid.id}")
21
22    # Disable performance boost
23    performance(model, False)
24
25
26def performance(model, switch):
27    if switch == True:
28        hm.setoption(
29            block_redraw=1,
30            command_file_state=0,
31            entity_highlighting=0,
32        )
33        model.hm_blockbrowserupdate(mode=1)
34    else:
35        hm.setoption(
36            block_redraw=0,
37            command_file_state=1,
38            entity_highlighting=1,
39        )
40        model.hm_blockbrowserupdate(mode=0)
41
42
43if __name__ == "__main__":
44    main()