Skip to content

Conversation

@Aaryan-549
Copy link
Contributor

Fixes #750
Implements derivative of ellipsoid-based fluid forces with respect to velocities. Includes all component derivatives:

  • Added mass forces
  • Viscous torque and drag
  • Kutta lift
  • Magnus force

The implementation adds the fluid force derivatives to qDeriv, following the pattern from the reference C implementation.

Implements derivative of ellipsoid-based fluid forces with respect to velocities.
Includes all component derivatives:
- Added mass forces
- Viscous torque and drag
- Kutta lift
- Magnus force

The implementation adds the fluid force derivatives to qDeriv, following the
pattern from the reference C implementation.
@thowell thowell self-requested a review December 11, 2025 16:29


@wp.kernel
def _qderiv_ellipsoid_fluid(
Copy link
Collaborator

Choose a reason for hiding this comment

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

lets rename to _deriv_ellipsoid_fluid



@wp.kernel
def _qderiv_ellipsoid_fluid(
Copy link
Collaborator

Choose a reason for hiding this comment

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

lets make this a wp.func instead of a wp.kernel. additionally, it should have worldid and bodyid inputs.

continue

size = geom_size[worldid % geom_size.shape[0], geomid]
semiaxes = _geom_semiaxes_deriv(size, geom_type[geomid])
Copy link
Collaborator

Choose a reason for hiding this comment

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

lets import _geom_semiaxes from passive.py. additionally let's change the name (in passive.py) to geom_semiaxes

slender_drag_coef = geom_fluid[geomid, 2]
ang_drag_coef = geom_fluid[geomid, 3]

if density > 0.0 and magnus_coef != 0.0:
Copy link
Collaborator

Choose a reason for hiding this comment

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

lets structure this with one if density > 0.0 check and checks for magnus_coef, kutta_coef and viscosity in the density check scope.



@wp.func
def _pow2_deriv(val: float) -> float:
Copy link
Collaborator

Choose a reason for hiding this comment

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

this function is unused, lets remove it

lin_vel = wp.spatial_bottom(local_vels)
ang_vel = wp.spatial_top(local_vels)

virtual_lin_mom = wp.vec3(
Copy link
Collaborator

Choose a reason for hiding this comment

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

fluid_density * wp.cw_mul(virtual_mass, lin_vel)

fluid_density * virtual_mass[1] * lin_vel[1],
fluid_density * virtual_mass[2] * lin_vel[2]
)
virtual_ang_mom = wp.vec3(
Copy link
Collaborator

Choose a reason for hiding this comment

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

fluid_density * wp.cw_mul(virtual_inertia, ang_vel)

ang_drag_coef * II[2] + slender_drag_coef * (I_max - II[2])
)

mom_visc = wp.vec3(x * mom_coef[0], y * mom_coef[1], z * mom_coef[2])
Copy link
Collaborator

Choose a reason for hiding this comment

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

wp.cw_mul(ang, mom_coef)


mom_visc = wp.vec3(x * mom_coef[0], y * mom_coef[1], z * mom_coef[2])
norm = wp.length(mom_visc)
density = fluid_density / wp.max(wp.static(1e-10), norm)
Copy link
Collaborator

Choose a reason for hiding this comment

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

lets utilize MJ_MINVAL instead of wp.static(1e-10)

norm = wp.length(mom_visc)
density = fluid_density / wp.max(wp.static(1e-10), norm)

mom_sq = wp.vec3(
Copy link
Collaborator

Choose a reason for hiding this comment

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

-density * wp.cw_mul(wp.cw_mul(ang, mom_coef), mom_coef)


proj_denom = aa * xx + bb * yy + cc * zz
proj_num = a * xx + b * yy + c * zz
dA_coef = wp.pi / wp.max(wp.static(1e-10), wp.sqrt(proj_num * proj_num * proj_num * proj_denom))
Copy link
Collaborator

Choose a reason for hiding this comment

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

lets utilize MJ_MINVAL

proj_num = a * xx + b * yy + c * zz
dA_coef = wp.pi / wp.max(wp.static(1e-10), wp.sqrt(proj_num * proj_num * proj_num * proj_denom))

A_proj = wp.pi * wp.sqrt(proj_denom / wp.max(wp.static(1e-10), proj_num))
Copy link
Collaborator

Choose a reason for hiding this comment

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

lets utilize MJ_MINVAL

A_proj = wp.pi * wp.sqrt(proj_denom / wp.max(wp.static(1e-10), proj_num))

norm = wp.sqrt(xx + yy + zz)
inv_norm = 1.0 / wp.max(wp.static(1e-10), norm)
Copy link
Collaborator

Choose a reason for hiding this comment

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

lets utilize MJ_MINVAL

xz, yz, zz + inner
)

D = D * (-quad_coef * inv_norm)
Copy link
Collaborator

Choose a reason for hiding this comment

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

*=

proj_num = a * xx + b * yy + c * zz
norm2 = xx + yy + zz
df_denom = wp.pi * kutta_lift_coef * fluid_density / wp.max(
wp.static(1e-10), wp.sqrt(proj_denom * proj_num * norm2)
Copy link
Collaborator

Choose a reason for hiding this comment

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

MJ_MINVAL

dfx_coef = yy * (a - b) + zz * (a - c)
dfy_coef = xx * (b - a) + zz * (b - c)
dfz_coef = xx * (c - a) + yy * (c - b)
proj_term = proj_num / wp.max(wp.static(1e-10), proj_denom)
Copy link
Collaborator

Choose a reason for hiding this comment

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

MJ_MINVAL

dfy_coef = xx * (b - a) + zz * (b - c)
dfz_coef = xx * (c - a) + yy * (c - b)
proj_term = proj_num / wp.max(wp.static(1e-10), proj_denom)
cos_term = proj_num / wp.max(wp.static(1e-10), norm2)
Copy link
Collaborator

Choose a reason for hiding this comment

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

MJ_MINVAL

proj_term = proj_num / wp.max(wp.static(1e-10), proj_denom)
cos_term = proj_num / wp.max(wp.static(1e-10), norm2)

D = wp.mat33(
Copy link
Collaborator

Choose a reason for hiding this comment

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

a - a, b - b and c - c can be replaced with 0.0

a - b, b - b, c - b,
a - c, b - c, c - c
)
D = D * (wp.static(2.0) * proj_num)
Copy link
Collaborator

Choose a reason for hiding this comment

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

*= and we can remove the parentheses

)
D = D * (wp.static(2.0) * proj_num)

inner_term = wp.vec3(
Copy link
Collaborator

Choose a reason for hiding this comment

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

we can utilize wp.cw_mul here

lin_vel_scaled = lin_vel * magnus_coef
ang_vel_scaled = ang_vel * magnus_coef

D_ang = _cross_deriv_a(ang_vel_scaled, lin_vel)
Copy link
Collaborator

Choose a reason for hiding this comment

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

should lin_vel -> lin_vel_scaled?

ang_vel_scaled = ang_vel * magnus_coef

D_ang = _cross_deriv_a(ang_vel_scaled, lin_vel)
D_lin = _cross_deriv_b(ang_vel, lin_vel_scaled)
Copy link
Collaborator

Choose a reason for hiding this comment

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

should ang_vel -> ang_vel_scaled?



@wp.func
def _cross_deriv_a(a: wp.vec3, b: wp.vec3) -> wp.mat33:
Copy link
Collaborator

Choose a reason for hiding this comment

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

lets consider combining _cross_deriv_a and _cross_deriv_b into one function that returns 2 wp.mat33 since it looks like we always compute derivatives wrt to both cross product inputs

Copy link
Collaborator

@thowell thowell left a comment

Choose a reason for hiding this comment

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

@Aaryan-549 thank you for contributing this pr!

in addition to the comments, lets add a test. please let us know if you have any questions. thanks!

…J_MINVAL, restructure density checks, combine cross derivatives
@Aaryan-549
Copy link
Contributor Author

Hey @thowell, really sorry for the delay. I have implemented all fixes that you asked for. Let me know If there are any other changes needed.

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.

add implementation of mjd_ellipsoidFluid

2 participants