🎉Community Raffle - Win $25

An exclusive raffle opportunity for active members like you! Complete your profile, answer questions and get your first accepted badge to enter the raffle.
Join and Win

Duplication of elements with different orientation

User: "Jeffersondhv"
Altair Community Member
Updated by Jeffersondhv

Hello all,

 

I'm working on a script to duplicate elements from a reference component containing a solid to a new component with the same exact solid, but in another position and orientation.

image.png.3fecf883a2fc328860c2adcafa7ffa22.png

 

The translation part was easy as the hm_getcentroid function provides the solid centroid position, so I can use the command *translatemark to translate the desired mesh to the correct position.

image.png.b714f9b1374eca63d827615eb1046212.png

 

But to match the orientation, it has been a task more difficult that I was expecting.

My approach has been to extract the moment of inertia of the reference solid and the target solid using hm_getmoiofsolid. Once I get these values, I compute the principal moment of inertia for each solid, so I have a comparable reference to use. Then I calculate the Euler parameters (or Quaternions) to obtain the rotation angles that I can use to rotate the elements from the reference solid to match the target solid orientation.

The problem I'm facing is that it seems that the inertia calculation performed by hm_getmoiofsolid seems not to be consistent, in a sense that even extracting the principal moments of inertia from them, these principal directions do not coincide with the solid orientation.

 

What could be done in this case?

 

Thanks in advance,

Jefferson Vieira

 

Find more posts tagged with

Sort by:
1 - 13 of 131
    User: "tinh"
    Altair Community Member
    Updated by tinh

    Hi, you should use *positionmark command

    User: "Jeffersondhv"
    Altair Community Member
    OP
    Updated by Jeffersondhv

    Hi, you should use *positionmark command

     

    Thanks for the answer tinh.

    I have actually already tried using *positionmark in one of my code versions, but I still get some cases where the elements end up somewhat flipped.

    I guess I might need to properly order the inertia tensor to get the correct orientation.

     

    Right now I'm using an auxiliary Python code to compute the principal moments of inertia for the solids. Is there a way to do this using Hypermesh's or TCL's functions?

     

    Thanks,

    Jefferson Vieira

    User: "tinh"
    Altair Community Member
    Updated by tinh

    I think yes.

     

    Could you show the code using *positionmark? Perhaps something's wrong, it must work

    User: "Jeffersondhv"
    Altair Community Member
    OP
    Updated by Jeffersondhv
    User: "tinh"
    Altair Community Member
    Updated by tinh

    Your code is very long, so it is not efficient

    I see some comps are reflected, so *positionmark will not work on them (need *reflectmark to eliminate flipping)

     

     

     

     

    I think approach can be simplify based on specification of the comp:

    - it has 1 max surface

    - its max surf is irregular

     

    So we will match max surf of source comp to target ones

    To do that, we take 3 mid nodes of 3 edges of the max surf

     

     

    User: "tinh"
    Altair Community Member
    Updated by tinh

    Code is like this

     proc p_GetMaxSurf {SurfList {n 1}} { 	set SaList {} 	foreach SurfId $SurfList { 		lappend SaList '$SurfId [hm_getareaofsurface surfs $SurfId]' 	} 	lrange [dict keys [join [lsort -decreasing -real -index 1 $SaList]]] 0 $n-1 } proc p_GetMaxLine {LineList {n 1}} { 	set ElList {} 	foreach EdgeId $LineList { 		lappend ElList '$EdgeId [hm_linelength $EdgeId]' 	} 	lrange [dict keys [join [lsort -decreasing -real -index 1 $ElList]]] 0 $n-1 } proc p_Mcopy args { 	*createmarkpanel comps 1 'Select source comp:' 	if {[hm_marklength comps 1]!=1} {return -code error 'Select 1 comp only'} 	set SourceComp [hm_getmark comps 1] 	*createmark elems 1 'by comp id' $SourceComp 	if {![hm_marklength elems 1]} {return -code error 'Comp #$SourceComp has no element'} 	set SourceElems [hm_getmark elems 1] 	*createmark surfs 1 'by comp id' $SourceComp 	if {![hm_marklength comps 1]} {return -code error 'Comp #$SourceComp has no surface'} 	set SourceSurfs [hm_getmark surfs 1] 	set MaxSurf [p_GetMaxSurf $SourceSurfs] 	lassign [p_GetMaxLine [join [hm_getsurfaceedges $MaxSurf]] 3] Line1 Line2 Line3 	*createmark lines 1 $Line1 	*nodecreateonlines lines 1 1 0 0 	set N1 [hm_latestentityid nodes] 	*createmark lines 1 $Line2 	*nodecreateonlines lines 1 1 0 0 	set N2 [hm_latestentityid nodes] 	*createmark lines 1 $Line3 	*nodecreateonlines lines 1 1 0 0 	set N3 [hm_latestentityid nodes] 	############################################### 	*createmarkpanel comps 1 'Select target comps:' 	hm_markremove comps 1 $SourceComp 	foreach TargetComp [hm_getmark comps 1] { 		*createmark surfs 1 'by comp id' $TargetComp 		if {[hm_marklength surfs 1]} { 			set MaxSurf [p_GetMaxSurf [hm_getmark surfs 1]] 			lassign [p_GetMaxLine [join [hm_getsurfaceedges $MaxSurf]] 3] Line1 Line2 Line3 			*createmark lines 1 $Line1 			*nodecreateonlines lines 1 1 0 0 			set N1_ [hm_latestentityid nodes] 			*createmark lines 1 $Line2 			*nodecreateonlines lines 1 1 0 0 			set N2_ [hm_latestentityid nodes] 			*createmark lines 1 $Line3 			*nodecreateonlines lines 1 1 0 0 			set N3_ [hm_latestentityid nodes] 			*currentcollector comps [hm_getcollectorname comps $TargetComp] 			eval *createmark elems 1 $SourceElems 			*duplicatemark elems 1 1 			*positionmark elems 1 $N1 $N2 $N3 $N1_ $N2_ $N3_ 		} 	} 	*clearmark all 1 }

     

    User: "Jeffersondhv"
    Altair Community Member
    OP
    Updated by Jeffersondhv

    Thanks a lot. That is very helpful. I haven't thought about this approach.

     

    As I would like to have this code more general, what could be done if the max surface is regular?

     

    Thank you

    User: "tinh"
    Altair Community Member
    Updated by tinh

    Hi

    In general, you have to identify an unique specification of the comp, it could be an irregular surf smaller than max surf, or 3 holes,... which forms a fundamental system. Inertial axles is such a system

    As the comp could be regular shapes like sphere, cube,... then it is simple case

    User: "Jeffersondhv"
    Altair Community Member
    OP
    Updated by Jeffersondhv

    Got it.

     

    So do you know a way to compute the principal moments of inertia for the solids using TCL?

    I found that to compute eigenvalues and eigenvectors I would need to add a TCL extension, but I really don't want to use that as it would add an additional step to be able to share this code with my colleagues.

    I see that using the approaches you suggested it works for a lot of cases, but I would like to use the inertia as it would provide me a more general solution.

     

    Thanks

    User: "tinh"
    Altair Community Member
    Updated by tinh

    Yes, you don't need tcllib extension package

    use templex.exe of hyperworks:

     proc p_GetPrincInertia {Ixx Iyy Izz Ixy Iyz Izx} {           set fpt [open GetEIGRL.tpl w]           puts $fpt '{eigvalreal({{$Ixx,$Ixy,$Izx},{$Ixy,$Iyy,$Iyz},{$Izx,$Iyz,$Izz}})}'           close $fpt           exec  [file join [hm_info -appinfo ALTAIR_HOME] hw bin [file tail [hm_info -appinfo HMBIN_DIR]] templex.exe] [file normalize GetEIGRL.tpl]  }

     

    User: "tinh"
    Altair Community Member
    Updated by tinh

     

    You don't need eigen values but eigen vectors,

    So change eigvalreal to eigvecreal

     

     

    User: "tinh"
    Altair Community Member
    Updated by tinh

    But I think using principle vectors are not as exact as using max surf

     

    code is like this

     

     proc p_GetEIGRL {Ixx Iyy Izz Ixy Iyz Izx} { 	set fpt [open GetEIGRL.tpl w] 	puts $fpt '{eigvalreal({{$Ixx,$Ixy,$Izx},{$Ixy,$Iyy,$Iyz},{$Izx,$Iyz,$Izz}})}' 	puts $fpt '{eigvecreal({{$Ixx,$Ixy,$Izx},{$Ixy,$Iyy,$Iyz},{$Izx,$Iyz,$Izz}})}' 	close $fpt 	exec [file join [hm_info -appinfo ALTAIR_HOME] hw bin [file tail [hm_info -appinfo HMBIN_DIR]] templex.exe] [file normalize GetEIGRL.tpl] } proc p_MCopy args { 	*createmarkpanel comps 1 'Select source comp:' 	if {[hm_marklength comps 1]!=1} {return -code error 'Select 1 source comp only'} 	set SourceComp [hm_getmark comps 1] 	*createmark elems 1 'by comp id' $SourceComp 	set ElemList [hm_getmark elems 1] 	if {![llength $ElemList]} {return -code error 'Not found element in comp #$SourceComp'} 	*createmark solids 1 'by comp id' $SourceComp 	set SolidId [hm_getmark solids 1] 	if {[llength $SolidId]!=1} {return -code error 'Source comp must have 1 solid'} 	set PrincInertia [string map {, ''} [eval p_GetEIGRL [hm_getmoiofsolid $SolidId]]] 	eval *createnode [hm_getcentroidofsolids 1] 	set Node1 [hm_latestentityid nodes] 	lassign $PrincInertia > > > V1 V2 V3 	*createmark nodes 1 $Node1 	*duplicatemark nodes 1 25 	set Node2 [hm_getmark nodes 1] 	eval *createvector 1 $V1 	*translatemark nodes 1 1 1 	*createmark nodes 1 $Node1 	*duplicatemark nodes 1 25 	set Node3 [hm_getmark nodes 1] 	eval *createvector 1 $V2 	*translatemark nodes 1 1 1 	*createmarkpanel comps 1 'Select target comps:' 	foreach TargetComp [hm_getmark comps 1] { 		*createmark solids 1 'by comp id' $TargetComp 		if {[hm_marklength solids 1]!=1} continue 		set PrincInertia [string map {, ''} [eval p_GetEIGRL [hm_getmoiofsolid [hm_getmark solids 1]]]] 		eval *createnode [hm_getcentroidofsolids 1] 		set Node1_ [hm_latestentityid nodes] 		lassign $PrincInertia > > > V1 V2 V3 		*createmark nodes 1 $Node1_ 		*duplicatemark nodes 1 25 		set Node2_ [hm_getmark nodes 1] 		eval *createvector 1 $V1 		*translatemark nodes 1 1 1 		*createmark nodes 1 $Node1_ 		*duplicatemark nodes 1 25 		set Node3_ [hm_getmark nodes 1] 		eval *createvector 1 $V2 		*translatemark nodes 1 1 1 		eval *createmark elems 1 $ElemList 		*currentcollector comps [hm_getcollectorname comps $TargetComp] 		*duplicatemark elems 1 1 		*positionmark elems 1 $Node1 $Node2 $Node3 $Node1_ $Node2_ $Node3_ 	} }

     

    User: "Jeffersondhv"
    Altair Community Member
    OP
    Updated by Jeffersondhv

    Thank you, that's very helpful.

     

    It seems like the max surf does the job better, but I've found some cases where it does not work well.

    I'll run further tests and comment later.