FreeCAD as pre-post processor for MBDyn

About the development of the FEM module/workbench.

Moderator: bernd

michav
Posts: 52
Joined: Mon Sep 09, 2019 7:34 am

Re: FreeCAD as pre-post processor for MBDyn

Post by michav »

Hes very active on youtube
josegegas
Posts: 255
Joined: Sat Feb 11, 2017 12:54 am
Location: New Zealand

Re: FreeCAD as pre-post processor for MBDyn

Post by josegegas »

Kunda1 wrote: Sat Oct 15, 2022 4:35 pm @josegegas are you still hacking on this project? there doesn't seem to be activity on the gitlab repo (are you developing it elsewhere?)
Yes, still working on it. There is a new version, which makes use of local coordinate systems as nodes and joints.

I stopped updating gitlab because I basically programmed everything again, in order to make use of the already existing LCSs as nodes and joints. I will upload all the new code to gitlab, but by now I just put all the workbench and the examples in a google drive:

https://drive.google.com/drive/folders/ ... M2zzlqAyED

This new version is a great improvement from the previous one, but I still make changes to the code very often, and sice it is just me working on the code, I did not see the need to update gitlab so frequently. But yes, I will upload all to gitlab soon.
josegegas
Posts: 255
Joined: Sat Feb 11, 2017 12:54 am
Location: New Zealand

Re: FreeCAD as pre-post processor for MBDyn

Post by josegegas »

saso wrote: Sat Oct 15, 2022 7:32 pm
josegegas wrote: Fri Oct 14, 2022 1:03 am ...
Jose, I would like to recommend that you change the structure of your "mbd simulation containers"...

First, I would probably prefer not to change the existing model, I understand that since FreeCAD does not really enforce a strict Assembly/Part structure the user cad models can sometimes be large and unstructured, so moving (hiding) them in to a group could be helpful, but changing the existing model is in general considered a bad practice, so I would not do it and it should be IMO more up to the user to manage the structure of the cad model in a way that works for them.

Second, add all your groups under one main group, this is also how the FEM, CFD and Path are doing it so it can be a more consistent workflow and this way is also in general common in commercial tools. So maybe something like this image (Note: my "model" in this example is just a cube, but regardless how big the cad model is or how it is structured I would not change/move it, so there is no "CAD_objects" group, everything else is as you have just under the "Dynamics" group, this would in theory also allow to have several different simulations for the same cad model)... ?


dyn.png
I agree. I will apply these two changes.

Yes, it would be great to have several simulations for the same CAD model. I was planning to force the user to have one input file seleted before running MBDyn, so that there could be more than one input files and one can compare several simulations in the same file. I think this is how FEM works?
josegegas
Posts: 255
Joined: Sat Feb 11, 2017 12:54 am
Location: New Zealand

Re: FreeCAD as pre-post processor for MBDyn

Post by josegegas »

michav wrote: Sat Oct 15, 2022 6:57 am Jose,
I got the node working,
I had to select, the reference body feature, the reference body origin and the rigid body element :)
next I am trying to get clamp joint and gravity working,

Clamp joint:
I keep getting the error: invalid property name 'node label'
I simply select the node and then click on the clamp joint.
someone in your gitlab has added this issue: https://gitlab.com/josegegas/freecad-mb ... /issues/22
according to Nils: I just add the "_" to the corresponding name and it works. , which I don't understand what he's talking about.

Static Node:
didn't work for me, I just thought to add a dynamic node and clamp it down. that is what you did in the contact example with the falling ball.

gravity:
I added gravity,
when I go to write the simulation file: it says
please provide a drive or scaler function to device the gravitation acceleration.
I want to add a scaler function, but I can't connect it to the gravity element. I select the gravity element, and select user defined function,
I get asked how many steps? and then it doens't get added to the scaler functions folder, it gets added to the bottom, and from there, I understand that it didn't work and i erased it.

I would like to introduce rigid body dynamics to an experimental high school physics class,
please help
-micha
Hello Micha.

Yes. The version in Gitlab is very old. Please download a new version of the workbench from here:

https://drive.google.com/drive/u/0/fold ... M2zzlqAyED

Sorry I did not upload all to gitlab. I will do so...
User avatar
Kunda1
Veteran
Posts: 13434
Joined: Thu Jan 05, 2017 9:03 pm

Re: FreeCAD as pre-post processor for MBDyn

Post by Kunda1 »

josegegas wrote: Mon Oct 24, 2022 4:30 pm I stopped updating gitlab because I basically programmed everything again, in order to make use of the already existing LCSs as nodes and joints. I will upload all the new code to gitlab, but by now I just put all the workbench and the examples in a google drive
Thanks for all your work. JFYI, using git really helps users to see your process (even if it totally messy or a hard re-write). You can create a new branch and hard-refactor/re-write and then merge that back in to the main branch or make it the main branch itself. So I'm just saying that I hope you can feel encouraged to do more coding on gitlab. It can attract devs to your work.
Alone you go faster. Together we go farther
Please mark thread [Solved]
Want to contribute back to FC? Checkout:
'good first issues' | Open TODOs and FIXMEs | How to Help FreeCAD | How to report Bugs
josegegas
Posts: 255
Joined: Sat Feb 11, 2017 12:54 am
Location: New Zealand

Re: FreeCAD as pre-post processor for MBDyn

Post by josegegas »

Hello. Getting back to this project.

I have the next problem. When one gets the matrix of inertia of a solid by doing:

Code: Select all

matrix_of_inertia = Body.Shape.Solids[0].MatrixOfInertia
FreeCAD returns the matrix of inetia of the first solid, expressed in the global reference frame. So that, if the orientation (placement) of the Body changes, its matrix of inertia also changes. Now, MBDyn needs the matrix of inertia of a rigid body to be expressed in the reference frame of the node connected to this body, which may be rotated relative to the global reference frame. In previous versions of my workbench I just assumed all the nodes have the same orientation as the global reference frame, so that this was not a problem. However I am now fixing this, so that the nodes can be in any orientation. Therefore I need to calculate the matrix of inertia of the bodies in the reference frame of their nodes. Since I use FreeCAD local coordinate systems as nodes, I thought this would be as simple as the next transformation:

Code: Select all

inertia = node.getGlobalPlacement().Matrix.inverse().multiply(matrix_of_inertia) 
where "node" is a local coordinate system with any random placement.

But this just does not work. The MBD simulation runs, but the matrix of inertia "inertia" is not symetric, and the model does not behave correctly. Any ideas on what am I getting wrong? Could this be because FreeCAD uses 4X4 matrices for the inertia, while only 9 of these 16 elements actually express the inertia matrix? Is there a way to work with only 3x3 matrices, so that I can get rid of the extra zeros and ones in the placement and inertia matrices?

I am a bit lost here. Any ideas will be welcome.

Thanks
User avatar
onekk
Veteran
Posts: 6222
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: FreeCAD as pre-post processor for MBDyn

Post by onekk »

josegegas wrote: Thu Feb 23, 2023 7:21 pm ...

Code: Select all

inertia = node.getGlobalPlacement().Matrix.inverse().multiply(matrix_of_inertia) 
...
At least when I manipulate placement I follow this process:

Code: Select all

m = obj.Placement.Matrix
# operate on m

# reapply Matrix to the object
obj.Placement.Matrix = m
But i don't know if is feasible to apply the Matrix to the object retrieved by node.getGlobalPlacement() as probably it is read only or derived from some calculations.

An alternative way, maybe not doable is to copy the object operate on the copy and delete at the end when finished.

Hope it helps

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
josegegas
Posts: 255
Joined: Sat Feb 11, 2017 12:54 am
Location: New Zealand

Re: FreeCAD as pre-post processor for MBDyn

Post by josegegas »

josegegas wrote: Thu Feb 23, 2023 7:21 pm Hello. Getting back to this project.

I have the next problem. When one gets the matrix of inertia of a solid by doing:

Code: Select all

matrix_of_inertia = Body.Shape.Solids[0].MatrixOfInertia
FreeCAD returns the matrix of inetia of the first solid, expressed in the global reference frame. So that, if the orientation (placement) of the Body changes, its matrix of inertia also changes. Now, MBDyn needs the matrix of inertia of a rigid body to be expressed in the reference frame of the node connected to this body, which may be rotated relative to the global reference frame. In previous versions of my workbench I just assumed all the nodes have the same orientation as the global reference frame, so that this was not a problem. However I am now fixing this, so that the nodes can be in any orientation. Therefore I need to calculate the matrix of inertia of the bodies in the reference frame of their nodes. Since I use FreeCAD local coordinate systems as nodes, I thought this would be as simple as the next transformation:

Code: Select all

inertia = node.getGlobalPlacement().Matrix.inverse().multiply(matrix_of_inertia) 
where "node" is a local coordinate system with any random placement.

But this just does not work. The MBD simulation runs, but the matrix of inertia "inertia" is not symetric, and the model does not behave correctly. Any ideas on what am I getting wrong? Could this be because FreeCAD uses 4X4 matrices for the inertia, while only 9 of these 16 elements actually express the inertia matrix? Is there a way to work with only 3x3 matrices, so that I can get rid of the extra zeros and ones in the placement and inertia matrices?

I am a bit lost here. Any ideas will be welcome.

Thanks
Hi.

Found one solution to this problem, and I wanted to document it here.

The MBDyn input file manual states:

"The inertia_matrix is always referred to the center of mass of the mass that is being added. It
can be rotated locally by means of the extra orientation_matrix supplied after the (optional) keyword
inertial. The keyword node corresponds to the default, i.e. the inertia matrix is assumed to be input
in the node reference frame."

So that MBDyn itself allows one solution this problem: by providing an extra orientation matrix after the definition of the inertia matrix. The whole code is something like:

Code: Select all

#Get the matrix of inertia of the first solid of a Body:

matrix_of_inertia = Body.Shape.Solids[0].MatrixOfInertia #The moments of inertia are returned assuming unit density.

#Get the individual moments of inertia from the matrix: 

ii11 = FreeCAD.Units.Quantity(inertia.A[0],FreeCAD.Units.Unit('mm^5'))
ii12 = FreeCAD.Units.Quantity(inertia.A[1],FreeCAD.Units.Unit('mm^5'))
ii13 = FreeCAD.Units.Quantity(inertia.A[2],FreeCAD.Units.Unit('mm^5'))

#Calculate the moments of inertia given the density of the material, in kg/mm^3:
 
i11 = FreeCAD.Units.Quantity(ii11*density, FreeCAD.Units.Unit('kg*mm^2'))
i12 = FreeCAD.Units.Quantity(ii12*density, FreeCAD.Units.Unit('kg*mm^2'))
i13 = FreeCAD.Units.Quantity(ii13*density, FreeCAD.Units.Unit('kg*mm^2'))

#Then, one has to obtain the inverse matrix of the placement of the node (local coordinate system) connected to this specific rigid body:

nodePlacement = FreeCAD.ActiveDocument.getObject("structural_" + Body.label).Placement.inverse()

#And generate the absolute orientation matrix from this inverse matrix:

oZ = "3, " + str(nodePlacement.Matrix.A13) + ", " + str(nodePlacement.Matrix.A23) + ", " + str(nodePlacement.Matrix.A33)                
oY = "2, " + str(nodePlacement.Matrix.A12) + ", " + str(nodePlacement.Matrix.A22) + ", " + str(nodePlacement.Matrix.A32)
global_orientation = oZ + ", " + oY               

Finally, the definition of the rigid body in the MBDyn input file should be like:

#-----------------------------------------------------------------------------
# [Design Variables]

#Generic bodies

#body: 1
set: real mass_1 = 0.007899999999999999; #mass [kg]
set: real volume_1 = 9.999999999999997e-07; #volume [m^3]

#-----------------------------------------------------------------------------
# [Intermediate Variables]

#Moment of inertia and relative center of mass

#body 1:
set: real Ixx_1 = 1.3166666666666672e-07; #moment of inertia [kg*m^2]
set: real Ixy_1 = 0.0; #moment of inertia [kg*m^2]
set: real Ixz_1 = 0.0; #moment of inertia [kg*m^2]

set: real Iyx_1 = 0.0; #moment of inertia [kg*m^2]
set: real Iyy_1 = 1.3166666666666672e-07; #moment of inertia [kg*m^2]
set: real Iyz_1 = 0.0; #moment of inertia [kg*m^2]

set: real Izx_1 = 0.0; #moment of inertia [kg*m^2]
set: real Izy_1 = 0.0; #moment of inertia [kg*m^2]
set: real Izz_1 = 1.3166666666666672e-07; #moment of inertia [kg*m^2]

set: real Rx_1 = 0.0; #X component of the relative center of mass [m]
set: real Ry_1 = 0.0; #Y component of the relative center of mass [m]
set: real Rz_1 = 0.0; #Z component of the relative center of mass [m]

#-----------------------------------------------------------------------------
# [Elements Block]

begin: elements;

#-----------------------------------------------------------------------------
# [Bodies]

#IMPORTANT NOTE: FreeCAD provides the inertia matrix in the global reference frame,
#while by default, MBDyn assumes it to be in the reference frame of the node,
#thus, the matrix of inertia must be rotated, using the inverse of the placement
#matrix of the node. This is done using the inertial keyword and the following
#orientation matrix.

body: 1,
1, #<node_label>
mass_1, #<mass> [kg]
Rx_1, Ry_1, Rz_1, #<relative_center_of_mass> [m]
Ixx_1, Ixy_1, Ixz_1, #<inertia_matrix> [kg*m^2]
Iyx_1, Iyy_1, Iyz_1,
Izx_1, Izy_1, Izz_1,
inertial, 3, 0.0, 0.0, 1.0, 2, 0.0, 1.0, 0.0; #Change the orientation of the inertia matrix, so that it is in the reference frame of the node....


Note that, since the orientation matrix "inertial, 3, 0.0, 0.0, 1.0, 2, 0.0, 1.0, 0.0" is parallel to the global frame, it means that the node has not been rotated. If it was, this matrix would be different...
User avatar
Kunda1
Veteran
Posts: 13434
Joined: Thu Jan 05, 2017 9:03 pm

Re: FreeCAD as pre-post processor for MBDyn

Post by Kunda1 »

@josegegas are you still using https://gitlab.com/josegegas/freecad-mb ... -workbench ?

Edit: +1 NewJoker
Alone you go faster. Together we go farther
Please mark thread [Solved]
Want to contribute back to FC? Checkout:
'good first issues' | Open TODOs and FIXMEs | How to Help FreeCAD | How to report Bugs
User avatar
NewJoker
Veteran
Posts: 3089
Joined: Sun Oct 11, 2020 7:49 pm

Re: FreeCAD as pre-post processor for MBDyn

Post by NewJoker »

Kunda1 wrote: Mon Mar 20, 2023 12:28 pm @josegegas are you still using https://gitlab.com/josegegas/freecad-mb ... -workbench ?
You missed the mention list selection here.
Post Reply