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 - Creating new entities#

The code imports the HyperMesh bumper.hm model, creates and defines a collection containing all the nodes, and then prints out the number of nodes inside the collection.

In the second part, it creates a new property, defining its name as “Steel” with a cardimage “MAT1”, and then prints out the name of the material.

 1import hm
 2import hm.entities as ent
 3import os
 4
 5# Reading a HyperMesh database file and grabbing the model object
 6modelfile = os.path.join(hm.altair_home,"demos/hm/bumper.hm")
 7model = hm.Model()
 8model.readfile(modelfile,0)
 9
10# Exposing the initial number of nodes
11node_col = hm.Collection(model,ent.Node)
12print(f'Number of Nodes: {len(node_col)}')
13
14# Create a node
15node = ent.Node(model)
16print(f'Created Node id {node.id}')
17
18# Create a material and name it 'Steel'
19mat1 = ent.Material(model)
20mat1.name = 'Steel'
21mat1.cardimage = 'MAT1'
22print(f'Material Name: {mat1.name}')

Example_02 - Modifying existing entities#

The code imports the HyperMesh bumper.hm model, and retrieves the material object with ID 1. Then it prints out its name and defines its Young’s Modulus and Poisson’s ratio.

In the second part, the code creates an object representing element ID 18 and isolates it.

 1import hm
 2import hm.entities as ent
 3
 4# Reading a HyperMesh database file and retrieving the model object
 5modelfile = os.path.join(hm.altair_home,"demos/hm/bumper.hm")
 6model = hm.Model()
 7model.readfile(modelfile,0)
 8
 9# Retrieve the entity object for material ID 1 and update its properties
10mat1 = ent.Material(model,1)
11print(f'Material Name: {mat1.name}')
12mat1.cardimage = 'MAT1'
13mat1.E = 2.1e+05  # Elasticity Modulus
14mat1.Nu = 0.3 # Poisson's ratio
15
16# Retrieve the entity object for element ID 18 and isolate it
17elem = ent.Element(model,18)
18model.isolateonlyentity(elem)

Example 03 - 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    ind_node = ent.Node(model, 1462)
115    # Dependent Nodes for rigidlink
116    nodelist = (
117        list(range(1420, ind_node.id))
118        + list(range(ind_node.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    filter1 = hm.FilterByEnumeration(ent.Node, nodelist)
125    dep_nodes = hm.Collection(model, filter1)
126
127    # rigid link creation
128    model.rigidlink(
129        independent=ind_node, collection=dep_nodes, dofs=123456
130    )
131
132    # Applying constraint to independent node of rigid link.
133    ind_node_col = hm.Collection([ind_node])
134    model.loadcreateonentity_curve(
135        collection=ind_node_col,
136        config=3,
137        type=1,
138        comp1=0,
139        comp2=0,
140        comp3=0,
141        comp4=0,
142        comp5=0,
143        comp6=0,
144        x_loc=0,
145        y_loc=0,
146        z_loc=0,
147        curve_id=0,
148        x_scale=0,
149    )
150
151    # Creating a Load collection with the name "Pressure" and we apply it on selected elements
152    loadcol2 = ent.Loadcol(model)
153    loadcol2.name = "Pressure"
154
155    elems = hm.CollectionByInteractiveSelection(model, ent.Element)
156    filt = hm.FilterByCollection(ent.Node, ent.Element)
157    nele = hm.Collection(model, filt, elems)
158
159    model.pressuresonentity_curve(
160        collection=elems,
161        facenodes=nele,
162        x_comp=0,
163        y_comp=0,
164        z_comp=-1,
165        magnitude=1,
166        breakangle=30,
167        onface=1,
168        xlocation=0,
169        ylocation=0,
170        zlocation=0,
171        curve_id=0,
172        x_scale=0,
173    )
174
175    # Setting up the loadstep
176    loadstep1 = ent.Loadstep(model)
177    loadstep1.OS_TYPE = 1  # Linear Static
178    loadstep1.OS_SPCID = model.get(hm.Entity(ent.Loadcol, 1))
179    loadstep1.OS_LOADID = loadcol2
180
181    # Two options for our geometry. Translation or rotation of elements. Selected and run via GUI
182    OptionsGui(model)
183
184def option_runner(model:hm.Model, opt:int):
185    if opt == 1:
186        # Translate elements
187        selected_elems = hm.CollectionByInteractiveSelection(model, ent.Element)
188        model.translatemark(collection=selected_elems, vector=[0.0, 1.0, 0.0], distance=0.5)
189    elif opt == 2:
190        # Rotate component
191        comp1 = hm.Collection(model, ent.Component, [1])
192        rot_axis = [0.0, 0.0, 1.0]
193        plane_orig = [0.0, 0.0, 0.0]
194        model.rotatemark(
195            collection=comp1, plane_normal=rot_axis, plane_base=plane_orig, angle=30
196        )
197
198if __name__ == "__main__":
199    main()

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

Figure 2. Creating nodes at components COGs

Example 06 - 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()