Hypermesh using Variables and arrays in Template

Altair Forum User
Altair Forum User
Altair Employee
edited October 2020 in Community Q&A

Hi,

I wonder if we can use variables in a custom template for FE out, beneath a small example.

How does one set the variable properly? set $Variable = 22, in the output the last column is 0.

 

second issue: I want to write the element and node amount to the file, I know that the 'elements' and 'nodes' returns a array:

elements

The list of elements contained in the component (entity array).  Valid for hm_getvalue query only.

from the

 

how to get theirs size and write it down?

 

  *components('','')  *before() *string('#components') *end() set $Variable = 22 *format() *fieldright(integer,id,8) *string(' ') *fieldright(integer,elements,8) *string(' ') *fieldright(integer,nodes,8) *string(' ') *fieldright(integer,$Variable,8) *end() *output()

 

Answers

  • Altair Forum User
    Altair Forum User
    Altair Employee
    edited May 2016

    Try this code:

     *text()   *uservariableset(#MYVARIABLE,22) *output()  *components('','') *before()   *string('#components')   *end() *format()   *fieldright(integer,id,8)   *string(' ')   *fieldright(integer,elements,8)   *string(' ')   *fieldright(integer,nodes,8)   *string(' ')   *fieldright(integer,#MYVARIABLE,8)   *end() *output()

     

  • Altair Forum User
    Altair Forum User
    Altair Employee
    edited May 2016

    Thank you,

     

    I will give it a try. Is there a method to get the size of an array ( elements and nodes)?

     

     

  • Altair Forum User
    Altair Forum User
    Altair Employee
    edited May 2016

    Maybe there's some function / variable to get this information.

    But you can count manually. The following code is used for counting number of nodes:

     *nodes() *nomenu() *before()   *treataslocal(counter19)   *counterset(counter19,0) *format()   *counterinc(counter19) *after()   *string('Total number of Nodes= ') *field(integer,counter19,0)    *end() *output()

    By the same way, you can do with elements.

  • Altair Forum User
    Altair Forum User
    Altair Employee
    edited May 2016

    Thanks a lot this is working fine.

     

    however I have to write a following line:

     

    ELEMENT, ComponentID, NumberOfElementsInTHISCOMPONENT, ElementID1, Element ID2, .... Element IDXX

    ELEMENT, 2, 28, 13, 14, 11, 15, 10, 8, 12, ... 1

     

    So the problem is I have to know the numbers of the nodes in each component BEFORE writing it down. :unsure:/emoticons/default_unsure.png' title=':unsure:' />

    I tried to construct a String while counting the elements/Nodes however no such thing is possible.

     

    Another important issue: Is it possible to know the collector a node is connected? a node can have several connectors, but I need it for the nodes in a similar matter like for elements

     

     *text()   *uservariableset(#MYVARIABLE,22) *output()   *elements(,,) *before() *string('COLLECTORS') *treataslocal(counter8) *counterset(counter8,0) *end() *format() *if([counter8==0]) *end() *string('MESH   , ') *field(int,collector.id,10) *string(', ') 	*if([collector.$Use_Quotes==1]) 	*quote() 	*endif() 	*fieldleft(string,collector.name,0) 	*if([collector.$Use_Quotes==1]) 	*quote() 	*endif() *end()       # *uservariableset(#ElementString, '')  // THis does not work, no STRINGS possible?  *endif() *counterinc(counter8)  # //*uservariableset(#ElementString,#ElementString+ ', '+id)  // THis does not work *string(',')   *uservariableset(#MYVARIABLE,counter8) *after() *end()    *string('ELEMENTS , ') *field(int,collector.id,10) *string(' , ')*field(integer,#MYVARIABLE,0)  #WAS TRYING to construct a string containing all NODEIDs #  *field(string,#ElementString,0) // THis does not work   *end() *output()

     

  • Altair Forum User
    Altair Forum User
    Altair Employee
    edited May 2016

    If you can't do some thing with 'FE Output Template', try with TCL script.

    With TCL script you can loop over components and get any information about nodes/elements of this component.

  • Altair Forum User
    Altair Forum User
    Altair Employee
    edited May 2016

    Thank you, is there any good documentation or tutorials? Where can the scripts be executed?

     

    found at http://www.tcl.tk/man/tcl8.5/tutorial/tcltutorial.html

     


     

    TCL is maybe the solution. I will post the result.

  • tinh
    tinh Altair Community Member
    edited May 2016

    Hi,

    Such your tasks, it's very easy to do by Tcl

    Template is just useful when you have to do a loop through big number of entities, in case Tcl takes long time to do

     

    a node is attached to some elements (components), you can use *findmark to get components attached to a node

  • Altair Forum User
    Altair Forum User
    Altair Employee
    edited May 2016

    Thank you both for the hints and tipps.

     

    I guess in order to count and get nodes and elements of the collector I have to use arrays and loops. Hence the tcl scripts are the way to go. The templates are straightforward in terms of nodes and elements. However the grouping mixed it up.

     

    Do you have any basic examples about querying the mesh, where I can build upon?

  • Altair Forum User
    Altair Forum User
    Altair Employee
    edited May 2016

    Thanks a lot this is working fine.

     

    however I have to write a following line:

     

    ELEMENT, ComponentID, NumberOfElementsInTHISCOMPONENT, ElementID1, Element ID2, .... Element IDXX

    ELEMENT, 2, 28, 13, 14, 11, 15, 10, 8, 12, ... 1

     

    Try this code:

     *createmarkpanel comps 1 'Select Component'; set mycomps [hm_getmark comps 1] hm_markclear comps 1;  foreach i $mycomps { 	set cname [hm_entityinfo name components $i] 	set elems [hm_elemlist id $cname] 	set num_elem [llength $elems] 	puts [format 'ELEMENT,%d,%d,%s' $i $num_elem [join $elems ',']] }

     

  • Altair Forum User
    Altair Forum User
    Altair Employee
    edited May 2016

    I sorted it out, it is working now. thank you!

     

    However it is taking ages, like tinh told me. is there a way to combine TPL (node and element list) with TCL ( for counting the lements and nodes) ?

     

    call the tpl from a tcl file and then attach the MESHSET INFO?

  • Altair Forum User
    Altair Forum User
    Altair Employee
    edited May 2016

    Yes, we can!

    Make maximum of the task with Template and the rest will be filled with TCL script.

     

  • Altair Forum User
    Altair Forum User
    Altair Employee
    edited May 2016

    I did some benchmarking:

     

     set cname [hm_entityinfo name components $i] 	set elemnodes [list]  	set elems [hm_elemlist id $cname] # took 0 seconds 	set num_elem [llength $elems] 	foreach curele $elems {	; 		set elemnodes [concat $elemnodes [hm_nodelist $curele]] 	}  # took28 seconds 	set elemnodes [lsort -integer -unique $elemnodes] 	set num_nods [llength $elemnodes]   	foreach nodeid $elemnodes { 		foreach {x y z} [expr [hm_nodevalue $nodeid]] {break} 		} # took 1 second foreach elemid $elems { 		set elemconfig [hm_getentityvalue elems $elemid config 0 -byid] #		puts $elemconfig 		switch $elemconfig { 			204 { 			set elem_info 'TETRA  ,' 			append elem_info '[format %8i $elemid] , 1 , [hm_getentityvalue elems $elemid node3 0 -byid] , [hm_getentityvalue elems $elemid node1 0 -byid] , [hm_getentityvalue elems $elemid node2 0 -byid] , [hm_getentityvalue elems $elemid node4 0 -byid]   ' 	 			} 			 	 		} 				append elem_info ', ' append content  '\n $elem_info' 		}  #  took 11 seconds  # the groupingtook only1 

     

    So the bottleneck is the generation of the nodelist of each element with the concat operation and the getentity operation for each element

     

    Do you see some optimisation?

  • Altair Forum User
    Altair Forum User
    Altair Employee
    edited May 2016

    A test with 300000 elements took 39 minutes :wacko:/emoticons/default_wacko.png' title=':wacko:' />

  • Altair Forum User
    Altair Forum User
    Altair Employee
    edited May 2016

    Maybe your code is not so optimized.

    Try the following code:

     *createmarkpanel comps 1 'Select Component'; set mycomps [hm_getmark comps 1] hm_markclear comps 1;  foreach i $mycomps { 	set cname [hm_entityinfo name components $i] 	set elems_list [hm_elemlist id $cname] 	eval *createmark elems 1 $elems_list 	 	*findmark elems 1 1 0 nodes 0 2; 	set nodes_list [hm_getmark nodes 2] 	 	set num_node [llength $nodes_list] 	set num_elem [llength $elems_list] 	#puts [format 'ELEMENT,%d,%d,%s' $i $num_elem [join $elems_list ',']] 	puts [format 'CompID= %d CompName= %s E=%d N=%d' $i $cname $num_elem $num_node] 	*clearmark elems 1; 	*clearmark nodes 2; }

    Is this better?

     

    Update: My scripts runs within 7s with 920,000 nodes & 1,200,000 elements & 40 components

     

  • Altair Forum User
    Altair Forum User
    Altair Employee
    edited May 2016

    Thank you! This is far better. I used your code to develop the script. it is writing all the info in a file

    the execution time for 118,000 tet elements is 9 seconds total, which is very good. however on a model with 1,100,000 tets it is giving still errors

    I will debug and test it again on a big model

     

    Update: the execution time is 92 seconds, which is good for me.

  • Altair Forum User
    Altair Forum User
    Altair Employee
    edited May 2016

    Hi again,

     

    Detected another slow process in the grid point lookup for each element: example for tetras

     

      append elem_info '[format %8i $elemid] , 1 , [hm_getentityvalue elems_list $elemid node3 0 -byid] , [hm_getentityvalue elems_list $elemid node1 0 -byid] , [hm_getentityvalue elems_list $elemid node2 0 -byid] , [hm_getentityvalue elems_list $elemid node4 0 -byid]   '

     

    For each node I do the 

    hm_getentityvalue elems_list $elemid lookup. Is it possible to do the lookup only 1 time and then ask for the nodes instead of doing it 4 times for tetras an even 8 times for hexas?

     

     

  • Altair Forum User
    Altair Forum User
    Altair Employee
    edited May 2016

    Try this code:

     foreach {n1 n2 n3 n4} [hm_nodelist $elemid] {} append elem_info [format '%8d , 1 , %d , %d , %d ' $elemid $n3 $n1 $n2 $n4]

     

  • Altair Forum User
    Altair Forum User
    Altair Employee
    edited May 2016

    That's it! Q.NGUYEN-DAI. for 1,100,000 tets the time decreased from 3 mins 22 seconds to 54 secconds. I imagine that for HEX elements the difference would be much greater., thank you!

  • Altair Forum User
    Altair Forum User
    Altair Employee
    edited May 2016

    That's it! Q.NGUYEN-DAI. for 1,100,000 tets the time decreased from 3 mins 22 seconds to 54 secconds. I imagine that for HEX elements the difference would be much greater., thank you!

     

    Wow, I'm glad to hear that helps you :)/emoticons/default_smile.png' srcset='/emoticons/smile@2x.png 2x' title=':)' width='20' /> Good job! 

     

  • tinh
    tinh Altair Community Member
    edited May 2016

    Hi,

    from HM13 to query elems and nodes of a component:

     

    set ElemList [hm_getvalue comps id=$CompId dataname=elements]

    set NodeList [hm_getvalue comps id=$CompId dataname=nodes]

     

    perhaps faster than using * commands (which modify some things so that take more time)