Entity Selection via Collections#

Most of the operations in HyperMesh performed by the user require an input entity selection provided via the interactive entity selector widget. The entity selection is internally translated into a so-called mark which is then subsequently passed to the HyperMesh function. In Tcl API, the marks can be created using the *createmark command (and its derived functions). User can create two marks per entity type simultaneously (a mark with ID 1 and ID 2). A mark is not persistent in the session, hence it needs to be defined just before calling the command that requires it as an input.

In Python API, the entity selection is provided through the Collection class. An entity selection is represented by a collection object which is persistent throughout the session and user can create an arbitrary number of collections per entity type. The requirement is that only one entity type can be present in a single collection and all entities must belong to the same model. Collections are iterable, meaning you can loop over them to perform operations on individual entity objects inside (see snippet below).

import hm
import hm.entities as ent

model = hm.Model()
elems = hm.Collection(model,ent.Element)

# Quering element IDs from a collection
for e in elems:
    print(e.id)

Collections are subscriptable and you can directly extract items from them by provding the index:

e1 = elems[0]

Collection objects can be printed, which will display the entity class contained in the collection and the number of entities in it:

print(elems)
>>> hm.mdi.entities.elements.Element, size: 436 items

Basic Operations#

The Collection constructor offers multiple ways of defining the collection content. The two basic options are: defining a collection of all entities and defining an empty collection.

# Collection of all elements in the model
elems = hm.Collection(model,ent.Element)

# Empty collection of elements
empty_elem_col = hm.Collection(model,ent.Element,populate=False)

The empty collection is typically used as an input argument for functions that populate the collection with entities.

Advanced Methods#

HyperMesh Python API allows user to create collections using more advanced methods, either via specialized functions or via filters.

In the hm Package, you will find four specialized functions that return a collection object:

  • CollectionByAdjacent - creates a collection of entities adjacent to the entities in the source collection.

  • CollectionByAttached - creates a collection of entities attached to the entities in the source collection.

  • CollectionByDisplayed - creates a collection of displayed entities.

  • CollectionByFace - creates a collection of entities that represent the same face as the entities in the source collection.

Filter classes provide an additional mechanism to define more complex rules of creating an entity collection.

The three standard filters are:

  • FilterByAttribute - entity selection based on their properties/attributes. The search string follows the same syntax as the Browser search in the GUI (see Find and Search for Entities and the examples below as well for more information ).

  • FilterByCollection - entity selection by reference (e.g. elements by properties, nodes by elements etc.).

  • FilterByEnumeration - entity selection by providing a list UIDs, either entity IDs or names.

Once the filters are defined, they can be passed to the Collection constructor as an argument. Below some examples are following for each filter.

FilterByAttribute
Create a collection of properties with PSHELL cardimage in OptiStruct profile, with thickness (PSHELL_T) between 1.5 and 2.5 units#
 # Verbose version
 rule = hm.FilterByAttribute(ent.Property,"PSHELL_T<2.5 AND PSHELL_T>1.5")
 props = hm.Collection(model,rule)

 # Implicit version
 props = hm.Collection(model,ent.Property,"PSHELL_T<2.5 AND PSHELL_T>1.5")
Create a collection of 2D QUAD (config=104) and TRIA (config=103) elements#
 # Verbose version 1
 rule = hm.FilterByAttribute(ent.Element,"config=103,104")
 elems = hm.Collection(model,rule)

 # Implicit version 1
 elems = hm.Collection(model,ent.Element,"config=103,104")

 # Implicit version 2
 elems = hm.Collection(model,ent.Element,"config IN(103,104)")

 # Implicit version 3 - Using OR (Union) operator
 elems = hm.Collection(model,ent.Element,"config=103 OR config=104")
Create a collection of MAT1 materials with Young modulus equal to 2800.0#
 # Verbose version
 rule = hm.FilterByAttribute(ent.Material,"cardimage=MAT1 AND E=2800.0")
 mats = hm.Collection(model,rule)

 # Implicit version
 mats = hm.Collection(model,ent.Material,"cardimage=MAT1 AND E=2800.0")
Create two collection. The first on will contain the parts that contain the word “SHELL”. The second will contain only components with names “ConNodRB” and “SpotWelds”.#
 # Below following the snippets for part collection

 # Verbose version 1
 rule = hm.FilterByAttribute(ent.Part,"Name~SHELL")
 parts = hm.Collection(model,rule)

 # Implicit version 1
 parts = hm.Collection(model,ent.Part,"Name~SHELL")

 # Implicit version 2
 parts = hm.Collection(model,ent.Part,"name~SHELL")

 # Below following the snippets for component collection

 # Implicit version 1
 comps = hm.Collection(model,ent.Component,"Name=ConNodRB OR Name=SpotWelds")

 # Implicit version 2
 comps = hm.Collection(model,ent.Component,"name=ConNodRB OR name=SpotWelds")

 # Implicit version 3
 comps = hm.Collection(model,ent.Component,"name=ConNodRB,SpotWelds")

Note

The attribute Name can be written as name too.

Create collections using advanced ID selections#
 # Below two snippets create material collections in which their ID starts with 8 and ends with 3
 # Verbose version 1
 rule = hm.FilterByAttribute(ent.Material,"ID=8*3")
 mats = hm.Collection(model,rule)

 # Implicit version 1
 mats = hm.Collection(model,ent.Material,"ID=8*3")

 # Below two snippets create element collections in which their ID ends with 6 in 6-digit numbers
 # Verbose version 1
 rule = hm.FilterByAttribute(ent.Element,"ID=[0-9][0-9][0-9][0-9][0-9]6")
 elems = hm.Collection(model,rule)

 # Implicit version 1
 elems = hm.Collection(model,ent.Element,"ID=[0-9][0-9][0-9][0-9][0-9]6")

 # Below two snippets create property collections in which their ID with 2 at the 5th position in 8-digit numbers
 # Verbose version 1
 rule = hm.FilterByAttribute(ent.Property,"ID=[0-9][0-9][0-9][0-9]2[0-9][0-9][0-9]")
 props = hm.Collection(model,rule)

 # Implicit version 1
 props = hm.Collection(model,ent.Property,"ID=[0-9][0-9][0-9][0-9]2[0-9][0-9][0-9]")
FilterByCollection
Get the MAT1 materials from PSHELL properties with IDs 1,2 and query the Young’s modulus#
props = hm.Collection(model,ent.Property,[1,2])

# Verbose version
rule = hm.FilterByCollection(ent.Material,ent.Property)
mats = hm.Collection(model,rule,props)

# Implicite version 1
mats = hm.Collection(model,ent.Material,props)

# Implicite version 2 - Without defining property collection initially
mats = hm.Collection(model,ent.Material,hm.Collection(model,ent.Property,[1,2]))

for mat in mats:
    print(f"Material ID {mat.id} and E {mat.E}")
Get the collection of nodes belonging to elements of all parts of model#
 # Verbose version
 parts = hm.Collection(model,ent.Part)
 rule1 = hm.FilterByCollection(ent.Element,ent.Part)
 elems = hm.Collection(model,rule1,parts)
 rule2 = hm.FilterByCollection(ent.Node,ent.Element)
 nodes = hm.Collection(model,rule2,elems)

 # Implicit version
 nodes = hm.Collection(model,ent.Node,hm.Collection(model,ent.Element,hm.Collection(model,ent.Part)))
Get collection of surfaces belonging solid with ID 1#
# Verbose version
 solids = hm.Collection(model,ent.Solid,[1])
 rule = hm.FilterByCollection(ent.Surface,ent.Solid)
 surfs = hm.Collection(model,rule,solids)

# Implicit version
surfs = hm.Collection(model,ent.Surface,hm.Collection(model,ent.Solid,[1]))
FilterByEnumeration
Get properties with IDs 103, 104, 201 and 202#
 # Verbose version
 rule = hm.FilterByEnumeration(ent.Property,[103,104,201,202])
 props = hm.Collection(model,rule)

 # Implicit version
 props = hm.Collection(model,ent.Property,[103,104,201,202])
Hide all components with IDs 3-6 and load collectors with IDs 5-8 and 10-15, do not consider elements and geometry#
 import hm
 import hm.entities as ent

 model = hm.Model()
 # Creating the collection set

 # Verbose version
 rule1 = hm.FilterByEnumeration(ent.Component, list(range(1,1001)))
 comps_collection = hm.Collection(model, rule1)
 rule2 = hm.FilterByEnumeration(ent.Loadcol, list(range(5,9))+list(range(10,16)))
 loadcols_collection = hm.Collection(model,ent.Loadcol,list(range(5,9))+list(range(10,16)))

 # Implicit version
 comps_collection = hm.Collection(model, ent.Component,list(range(3,7)))
 loadcols_collection = hm.Collection(model,ent.Loadcol,list(range(5,9))+list(range(10,16)))


 ent_collectionset = hm.CollectionSet(model)
 ent_collectionset.set(comps_collection)
 ent_collectionset.set(loadcols_collection)

 model.hideentitybymark(collection_set=ent_collectionset,geometry_off=True,elements_off=True)
Get parts with names ConNodRB, SpotWelds, Hood#
 # Verbose version
 rule = hm.FilterByEnumeration(ent.Part, ["ConNodRB", "SpotWelds", "Hood"])
 parts = hm.Collection(model, rule)

 # Implicit version
 parts = hm.Collection(model, ent.Part, ["ConNodRB", "SpotWelds", "Hood"])

The Collection constructor provides several ways of embedding the rules in the constructor, bypassing the creation of a filter object.

Below figures show how to use a FilterByAttribute search string directly inside the constructor.


A screenshot of a computer Description automatically generated A computer code with black text Description automatically generated

Figure 1. Collection of properties containing “Outer” in the name.


image1 A computer screen shot of a computer code Description automatically generated

Figure 2. Collection of properties with thickness greater than 1.5 and less than 2.5.


FilterByEnumeration can be substituted by directly passing a list of identifiers to the constructor:

hm.Collection(model, ent.Component, [1, 2])
hm.Collection(model, ent.Part, ['abc', 'xyz'])

FilterByCollection can be substituted by passing the source collection to the constructor:

elems = hm.Collection(model, ent.Element, hm.Collection(m, ent.Component, [1,2]))

Alternatively, a list of entity objects can be passed as a single argument:

elems = hm.Collection([entity_object1, entity_object2, ..., entity_objectN])

The following filters allow selecting entities based on their position in space by prescribing a geometrical primitive:

  • FilterByBox - select entities inside a box.

  • FilterByCone - select entities inside a cone.

  • FilterByCylinder - select entities inside a cylinder.

  • FilterByInfiniteCylinder - select entities inside an infinite cylinder (i.e. within a distance from an axis).

  • FilterByPlane - select entities withing a distance from a plane.

  • FilterBySphere - select entities inside a sphere.

Interactive Selection#

A collection object can be also created by selecting entities interactively in the graphics area using CollectionByInteractiveSelection function. Upon calling this function, an entity selector widget will be posted in the graphics area and after finalizing the selection, the function will return a collection object.

elems = hm.CollectionByInteractiveSelection(model,ent.Element)

A wireframe of a metal object Description automatically generated

Figure 3. Interactive entity selection using the selector widget.

Arithmetic Operations#

Collections and entity objects also support arithmetic operators. Collections can be combined or subtracted from each other using the + or - operators. Alternatively, they can be modified by adding or subtracting specific entity objects or a list of entity objects. The collections and entity objects used in these operations must be of the same entity type.

collection_object3 = collection_object1 + collection_object2

new_collection_object = collection_object + entity_object

new_collection_object = collection_object - entity_object

new_collection_object = collection_object + [entity_object1, entity_object2]

new_collection_object = collection_object - [entity_object1, entity_object2]

Collection Set#

A CollectionSet is a collection of collections. It can contain only one collection per entity type. Collection sets are typically used in functions to supply multiple collections of different entity types as a single argument. Another common use case is user supplying an empty collection set to a function that populates it with multiple entity collections. Below is an example of creating a collection set of two different entity types: LoadForce and LoadMoment.

# Collection of all forces in the model
loadF_col = hm.Collection(model,ent.LoadForce)

# Collection of all moments in the model
loadM_col = hm.Collection(model,ent.LoadMoment)

# Creating the collection set
colset = hm.CollectionSet(model)

# Adding forces collection in collection set
colset.set(loadF_col)

# Adding moments collection in collection set
colset.set(loadM_col)