Using .tcl to automate assigning nodes/elements to sets without directly specifying IDs
Hello,
I am looking to create a .tcl script that simplifies importing geometry, meshing the geometry, and creating node/element sets. I already have a basic model template, but I will be creating quite a number of HM files with different geometries, so hopefully running the .tcl script can cut down on time spent manually importing, meshing, and creating node/element sets for BCs using that HM template.
I have made use of the command1.tcl file located in the Documents folder which records all of the commands in HM to help build my own .tcl script. However, I have run into the following issues:
1. The command for assigning elements to an output block:
*setvalue outputblocks id=4 ids={elems 9313-30840}
*startnotehistorystate {Updated "ids" of Outputblocks}
*endnotehistorystate {Updated "ids" of Outputblocks}
uses the IDs of elements directly. Since I will have different geometries with different meshes (leading to a different number of elements), I don't want the .tcl script to refer to anything fixed like this, which would require me to modify it for every new geometry (defeating the purpose of having my .tcl script).
Is there a way to avoid directly calling out the element IDs, say by using the command "displayed" or something else (I have already tried "...ids={elems "displayed"}..." with no luck)?
2. I want to assign nodes to certain sets based on where they fall on the geometry. This is quite easy to do manually for the geometry I have by selecting nodes "on plane" (e.g. y-axis and base point (0,0,0)), but the resulting line of code in command1.tcl:
*setvalue sets id=6 ids={nodes 14003 14122 14195 14283 14509-14511 14526-14527 14697 14712-14714 15017-15044 15750-15752 15782-15783 15987-16209}
does not show any of those specifications on how to select the nodes instead, listing them directly (which will not be transferable from one geometry to another for me, since the meshes will all differ slightly, with different node numbers for those nodes that I want in that specific set).
As with #1, is there a way to avoid directly calling out the node IDs instead, passing a command to assign the node IDs on a defined plane to the set?
Thus, is there a way to write the commands in the .tcl script which does not directly list element/node IDs so as to automate the importing, meshing, and set creation for many different geometries?
I have attached my .tcl script if required.
Thank you in advance for your suggestions and help.
Best Answer
-
The command you are looking for is hm_createmark. There are all kinds of options for selecting entities with this option including by displayed.
The help file for hm_createmark is below but to short circuit what you are looking for here is an example.
hm_createmark elements 1 "advanced" "displayed"
set lst_elem_id [hm_getmark elements 1]
In HW the mark is a "container" for selecting entities and there are 2 for each entity type 1 and 2. So the first command is adding all the displayed elements to mark 1 and the second command retrieves the element ids in mark 1 and sets them to a variable named lst_elem_id.
1
Answers
-
The command you are looking for is hm_createmark. There are all kinds of options for selecting entities with this option including by displayed.
The help file for hm_createmark is below but to short circuit what you are looking for here is an example.
hm_createmark elements 1 "advanced" "displayed"
set lst_elem_id [hm_getmark elements 1]
In HW the mark is a "container" for selecting entities and there are 2 for each entity type 1 and 2. So the first command is adding all the displayed elements to mark 1 and the second command retrieves the element ids in mark 1 and sets them to a variable named lst_elem_id.
1 -
usually what i do is to use the commands mentioned by Ben, above and also
*setvalue outputblocks id=4 ids={elems 9313-30840}
Would be something like:
hm_createmark elements 1 "by comp name" "my_comp"; #select elements by component name
set lst_elem_id [hm_getmark elements 1]; #store the IDs of the elements selected in mark #1 into a list
set outputblock_name "my_output_block"; #define the name of the output block to be edited (using name it's easier than using Ids)
eval "*setvalue outputblocks name=$outputblock_name ids=\{elems $lst_elem_id\}" ; #add the elements inside the list into your output block
The eval command will first take this string and substitute the variables into it, and then run the *setvalue command.
1 -
Thank you for all your help!
I made use of some options within hm_createmark (the link to the reference page provided above was especially useful) and decided to go the route of being more specific than "advanced" "displayed" so as to avoid needing to ensure the correct visibility of components.
I also found 'set', 'eval', and 'hm_markremove' to be useful and my solution to my two issues in the original question is as follows for anyone coming across this question in the future:
1. For output blocks, where I want all the solid elements in a specific component "LatticeMesh" to be assigned to "Solid Elems":
hm_createmark elements 1 "by comp name" "LatticeMesh"
*setvalue outputblocks name="Solid Elems" ids={elems [hm_getmark elements 1]}2. For node sets, where I wanted to select by plane:
hm_createmark nodes 1 "on plane" "0 0 0 0 1 0 0.00001 1 1"
*setvalue sets name="BOTTOM" ids={nodes [hm_getmark nodes 1]}
set nodes_rem1 [hm_getmark nodes 1]
hm_createmark nodes 1 "on plane" "0 0.01 0 0 1 0 0.00001 1 1"
*setvalue sets name="TOP" ids={nodes [hm_getmark nodes 1]}
set nodes_rem2 [hm_getmark nodes 1]I then wanted an additional node set called SIDES to contain nodes on the sides of my cube, but to not contain nodes already contained within the TOP and BOTTOM node sets (if they were, an error with BCs would result). My solution was to follow up with:
hm_createmark nodes 2 "on plane" "0.005 0.005 0 1 0 0 0.00001 1 1"
eval hm_markremove nodes 2 $nodes_rem1, $nodes_rem2
set side_list_1 [hm_getmark nodes 2]
hm_createmark nodes 2 "on plane" "-0.005 0.005 0 1 0 0 0.00001 1 1"
eval hm_markremove nodes 2 $nodes_rem1, $nodes_rem2
set side_list_2 [hm_getmark nodes 2]
hm_createmark nodes 2 "on plane" "0 0.005 0.005 0 0 1 0.00001 1 1"
eval hm_markremove nodes 2 $nodes_rem1, $nodes_rem2
set side_list_3 [hm_getmark nodes 2]
hm_createmark nodes 2 "on plane" "0 0.005 -0.005 0 0 1 0.00001 1 1"
eval hm_markremove nodes 2 $nodes_rem1, $nodes_rem2
set side_list_4 [hm_getmark nodes 2]
set sets_name "SIDES"
eval "*setvalue sets name=$sets_name ids=\{nodes $side_list_1, $side_list_2, $side_list_3, $side_list_4\}"which was a (perhaps tedious) method of selecting some nodes on the side of the cube based on a plane, then removing any nodes that were also contained within TOP and BOTTOM (which I assigned to nodes_rem1 and nodes_rem2) and finally adding everything to one set called SIDES.
0