Skip to content
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

Fixes #207 #231

Merged
merged 11 commits into from
Jul 4, 2024
Merged

Fixes #207 #231

merged 11 commits into from
Jul 4, 2024

Conversation

sanguinariojoe
Copy link
Collaborator

@sanguinariojoe sanguinariojoe commented Jul 2, 2024

See #207

@sanguinariojoe sanguinariojoe changed the base branch from master to dev July 2, 2024 07:32
@sanguinariojoe sanguinariojoe changed the title Fix Fixes #207 Jul 2, 2024
@sanguinariojoe sanguinariojoe self-assigned this Jul 2, 2024
source/Rod.cpp Outdated
vec F = vec::Zero();
for (unsigned int i = 0; i <= N; i++) {
const vec rRel = r[i] - rRef;
F += w.squaredNorm() * (M[i] * rRel);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be worth checking this assumption, but I don't think $|\omega|^2$ is correct. It would break down in the case where the axis of rotation is not perpendicular to the rRel vector.

The simplest case is where the axis of rotation is parallel to the rRel vector. In that case you should expect a net zero centrifugal force.

Unfortunately, I don't know what the correct equation is off hand, but I would guess it's something like

$$F_c = M (\omega \times (\omega \times r))$$

based on the wikipedia page for centrifugal force.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hahaha, I started implementing it as omega x omega x..., and then I
thought, what a waste!

Sometimes I amuse myself... Anyway, you are totally right. I am correcting
that ASAP

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solved in 0838d46

source/Body.cpp Outdated Show resolved Hide resolved
@RyanDavies19
Copy link
Collaborator

RyanDavies19 commented Jul 2, 2024

@AlexWKinley @sanguinariojoe Thank you all for putting this together and working out the math. This all looks good on my end, and I agree that MD was failing to account for the non-inertial reference frame. I will talk with @RBergua about this on the MDF side and address it in a PR there. I'm curious @AlexWKinley does this resolve your surface piercing buoys issues? USFLOWT is using MoorDyn for the same purpose.

@AlexWKinley
Copy link
Contributor

I think this will do a solid job addressing my issues. I haven't had a chance to particularly rigorously test this. I'll try to find some time in the next day or two.

The overall surface piercing behavior is probably more complicated than just this particular issue, but that can be a later investigation.

@RyanDavies19
Copy link
Collaborator

Once I get this in on the OpenFAST side I'll let you all know how it does resolving issues with USFLOWT. Agreed though the surface piercing is probably more than just this. If I come across any fixes on the MD-F side I'l open an issue here

@AlexWKinley
Copy link
Contributor

AlexWKinley commented Jul 3, 2024

Alright, I've had some time to test out this PR. Overall, everything works as expected.

The only additional thought I have related to this PR, is that we might want to also handle when the body CG is defined as not being at the origin of the body. I think this should be pretty straight forward. The code below seems to work at least in the context where there isn't added mass.

	// First, the body's own mass matrix must be adjusted based on its
	// orientation so that we have a mass matrix in the global orientation frame
	M = rotateMass6(OrMat, M0);

	// gravity forces and moments about body ref point given CG location
	const vec body_rCGrotated = OrMat * body_rCG;
	// weight+buoyancy vector
	const vec Fgrav =
	    vec(0.0, 0.0, bodyV * env->rho_w * env->g - bodyM * env->g);
	F6net(Eigen::seqN(0, 3)) = Fgrav;
	F6net(Eigen::seqN(3, 3)) = body_rCGrotated.cross(Fgrav);

	// Centrifugal force due to COM not being at body origin
	const vec w = v6.tail<3>();
	F6net.head<3>() -=
	    M.topLeftCorner(3, 3) * (w.cross(w.cross(body_rCGrotated)));

As potential future investigation, I now think @sanguinariojoe is correct that our 6dof kinematics are missing some sort of $\omega \times I_{cm} \omega$ term. This comes up if you give a body (with an attached rod), rotation around two separate axes. In those sitatuions the kinematics differ depending on where the body is, but both of the kinematics are incorrect so I don't think that should prevent merging this PR.

@sanguinariojoe
Copy link
Collaborator Author

sanguinariojoe commented Jul 3, 2024 via email

@sanguinariojoe sanguinariojoe merged commit 8b68967 into FloatingArrayDesign:dev Jul 4, 2024
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants