-
Notifications
You must be signed in to change notification settings - Fork 486
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fea linear elements refactor #552
base: main
Are you sure you want to change the base?
fea linear elements refactor #552
Conversation
…ulation to limit number of expensive length calculations
…step. Refactor force calculations
This is done for simplicity but I also think there might be a bug in SetupInitial(). When the beam is created from 2 nodes, or 1 node and 1 position, the end nodes may have different Y axes, and there is no reason why this Y axis should correspond to that of the beam element since those are determined by who created these nodes.
do nothing if corotate is disabled. use cheaper quaternion representation of rotation rather than matrix multiplication
Hi - question: in ChElementSpring, you changed |
In ChElementBar, same question... you compute the two forces via |
Hi @tasora ! The changes in the force calculation were made to avoid computing the length and scaling multiple times. In the original code below chrono/src/chrono/fea/ChElementBar.cpp Lines 112 to 114 in 19e970e
GetNormalized internally computes the length, and then line 114 recomputes the same length. Inside GetNormalized the vector gets scaled by 1/length , i.e., each 3 components are multiplied by 1/length .
In the refactor below chrono/src/chrono/fea/ChElementBar.cpp Lines 100 to 109 in f6b06bf
With the non-normalized node-to-node vector We actually do 2 rescalings, with the damping on 106, so this only saves 1 multiplication by I ran all CORE, COLLISION, PHYSICS, Chrono joints, SMC contact in CORE module, FEA, MODAL, VEHICLE, MULTICORE, SMC contact in MULTICORE, SYNCHRONO unit tests and they all pass. |
…nce for clarity. store unchanged values that were computed each step
@jibril-b-coulibaly Please note that it is not enough to run the FEA unit tests to ensure the changes you are making are correct and do not break things. Indeed, most FEA unit tests are for the ANCF formulation. Instead, you should compare results on all appropriate FEA demos. |
@rserban thank you for the information. I additionally ran
chrono/src/chrono/fea/ChBuilderBeam.cpp Lines 744 to 790 in 19e970e
Looking forward, I think the purpose of unit tests is to check that functions operate the way they are supposed to, and for a refactor like the one here, I believe we should be able to rely on them. Does that mean the unit tests coverage is insufficient to test such changes and should be expanded for Euler Bernoulli beams? If the specific functions refactored have identical behavior as the original per unit testing, there should be no issue. There is always the possibility of functions side effects and I do agree that regression tests are also necessary to see how the changes propagate to the rest of the code. Thank you |
Hi Jibril
Thank you for the refactoring of FEA code.
I had no much time to review all the changes because I am quite busy these days. But all looks correct so far.
Just keep in mind that many finite elements in Chrono were implemented many years ago, and they really need a refresh. For example I was planning to rewrite the solid elements (tetrahedrons etc. ) both to use a total lagrangian formulation and to accommodate a new design that uncouples the pde from the element, in the sense that one could apply both elasticity and thermal problems to the same element for example. I am doing something along this line in the peridynamics/ branch.
Etc etc.
Thanks
Alessandro
…________________________________
From: Jibril B. Coulibaly ***@***.***>
Sent: Thursday, February 27, 2025 5:19:43 PM
To: projectchrono/chrono ***@***.***>
Cc: Alessandro TASORA ***@***.***>; Mention ***@***.***>
Subject: Re: [projectchrono/chrono] fea linear elements refactor (PR #552)
Hi @tasora<https://github.com/tasora> !
The changes in the force calculation were made to avoid computing the length and scaling multiple times. In the original code below
https://github.com/projectchrono/chrono/blob/19e970e97778ee0064ecf03c6d2049884001353f/src/chrono/fea/ChElementBar.cpp#L112-L114
GetNormalized internally computes the length, and then line 114 recomputes the same length. Inside GetNormalized the vector gets scaled by 1/length, i.e., each 3 components are multiplied by 1/length.
In the refactor below
https://github.com/projectchrono/chrono/blob/f6b06bf9a1ee52fbbbeba838a5642cda76987a10/src/chrono/fea/ChElementBar.cpp#L100-L109
With the non-normalized node-to-node vector dPos, we only compute the length once on 102.
the internal_force_local in 107 is scaled by Linv, so "force" here is a bit of an abuse of language but the math ends up being the same as the original.
The difference is that instead of re-scaling every component of the vector, we rescale the magnitude, doing 1 rescaling instead of 3.
We actually do 2 rescalings, with the damping on 106, so this only saves 1 multiplication by Linv compared to the original and is insignificant in terms of performance.
However, once we decide to compute the length only once by not calling GetNormalized- which does save compute - this is the more natural way to write the rest of the code in my opinion.
I ran all FEA unit tests and they all pass.
—
Reply to this email directly, view it on GitHub<#552 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ABHTOBFIV74HRADT4ICVM4D2R43JPAVCNFSM6AAAAABX6RKLRGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMOBYGQ2TKOBTGI>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
[jibril-b-coulibaly]jibril-b-coulibaly left a comment (projectchrono/chrono#552)<#552 (comment)>
Hi @tasora<https://github.com/tasora> !
The changes in the force calculation were made to avoid computing the length and scaling multiple times. In the original code below
https://github.com/projectchrono/chrono/blob/19e970e97778ee0064ecf03c6d2049884001353f/src/chrono/fea/ChElementBar.cpp#L112-L114
GetNormalized internally computes the length, and then line 114 recomputes the same length. Inside GetNormalized the vector gets scaled by 1/length, i.e., each 3 components are multiplied by 1/length.
In the refactor below
https://github.com/projectchrono/chrono/blob/f6b06bf9a1ee52fbbbeba838a5642cda76987a10/src/chrono/fea/ChElementBar.cpp#L100-L109
With the non-normalized node-to-node vector dPos, we only compute the length once on 102.
the internal_force_local in 107 is scaled by Linv, so "force" here is a bit of an abuse of language but the math ends up being the same as the original.
The difference is that instead of re-scaling every component of the vector, we rescale the magnitude, doing 1 rescaling instead of 3.
We actually do 2 rescalings, with the damping on 106, so this only saves 1 multiplication by Linv compared to the original and is insignificant in terms of performance.
However, once we decide to compute the length only once by not calling GetNormalized- which does save compute - this is the more natural way to write the rest of the code in my opinion.
I ran all FEA unit tests and they all pass.
—
Reply to this email directly, view it on GitHub<#552 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ABHTOBFIV74HRADT4ICVM4D2R43JPAVCNFSM6AAAAABX6RKLRGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMOBYGQ2TKOBTGI>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
This PR refactors the Spring, Bar, and some Beam elements.
This is ongoing work, we should decide when it is a good enough point to merge it
Springs
Modifications
possible issues / bugs to be discussed
Bars
Modifications
possible issues / bugs to be discussed
Euler-Bernoulli beams
Modifications
YDir
vectors in the Builder, rather than using the average Y directions of the end nodes after the fact. This is more practical, but I also believe this was a bug since the average Y direction of the nodes after Gram-Schmidt has no guarantee to be colinear with user provided Y direction of the beams when the nodes pre-exist the beam.possible issues / bugs to be discussed
char
as an index, why not anint
orsize_t
?while
loop and used to access a 3-vector, there is a risk to access out of boundschrono/src/chrono/core/ChVector3.h
Lines 887 to 910 in 6f4d94c