# [ODE] objects in water

Ander ander_taylor at hotmail.com
Wed Jan 19 11:09:24 MST 2005

```Here is a nice way for boxes.

Is works out the speed each face of the box is moving along its own normal
and applies a force dependant on the area.

The first one just does drag, the second adds buoyancy and flow.

Ander

void BoxGeom::ApplyHydrodynamicForces(dReal viscosity)
{
const dReal *lvel = dBodyGetLinearVel(this->_body->Id);
const dReal *avel = dBodyGetAngularVel(this->_body->Id);
const dReal *R = dBodyGetRotation(this->_body->Id);
dReal ss[3];
dGeomBoxGetLengths(this->_id, ss);

dReal AreaX = ss[1] * ss[2];
dReal AreaY = ss[0] * ss[2];
dReal AreaZ = ss[0] * ss[1];

dReal nx = (R[0] * lvel[0] + R[4] * lvel[1] + R[8] * lvel[2]) *  AreaX;
dReal ny = (R[1] * lvel[0] + R[5] * lvel[1] + R[9] * lvel[2]) * AreaY;
dReal nz = (R[2] * lvel[0] + R[6] * lvel[1] + R[10] * lvel[2]) * AreaZ;

dReal temp = -nx * viscosity;
dBodyAddForce(this->_body->Id, temp * R[0], temp * R[4], temp * R[8]);

temp = -ny * viscosity;
dBodyAddForce(this->_body->Id, temp * R[1], temp * R[5], temp * R[9]);

temp =-nz * viscosity;
dBodyAddForce(this->_body->Id, temp * R[2], temp * R[6], temp * R[10]);

nx = (R[0] * avel[0] + R[4] * avel[1] + R[8] * avel[2]) * AreaZ;
ny = (R[1] * avel[0] + R[5] * avel[1] + R[9] * avel[2]) * AreaX;
nz = (R[2] * avel[0] + R[6] * avel[1] + R[10] * avel[2]) * AreaY;

temp = -nx * viscosity * 500;
dBodyAddTorque(this->_body->Id, temp * R[0], temp * R[4], temp * R[8]);

temp = -ny * viscosity * 500;
dBodyAddTorque(this->_body->Id, temp * R[1], temp * R[5], temp * R[9]);

temp = -nz * viscosity * 500;
dBodyAddTorque(this->_body->Id, temp * R[2], temp * R[6], temp * R[10]);

}

void BoxGeom::ApplyHydrodynamicForces(dReal linear_viscosity, dReal
angular_viscosity, dReal density, Vector3 flow)
{
const dReal *lvel = dBodyGetLinearVel(this->_body->Id);
const dReal *avel = dBodyGetAngularVel(this->_body->Id);
const dReal *R = dBodyGetRotation(this->_body->Id);

dVector3 compFlow;
compFlow[0] = lvel[0] - flow.x;
compFlow[1] = lvel[1] - flow.y;
compFlow[2] = lvel[2] - flow.z;

dReal ss[3];
dGeomBoxGetLengths(this->_id, ss);

dReal AreaX = ss[1] * ss[2];
dReal AreaY = ss[0] * ss[2];
dReal AreaZ = ss[0] * ss[1];

dReal nx = (R[0] * compFlow[0] + R[4] * compFlow[1] + R[8] * compFlow[2]) *
AreaX;
dReal ny = (R[1] * compFlow[0] + R[5] * compFlow[1] + R[9] * compFlow[2]) *
AreaY;
dReal nz = (R[2] * compFlow[0] + R[6] * compFlow[1] + R[10] * compFlow[2]) *
AreaZ;

dReal temp = -nx * linear_viscosity;
dBodyAddForce(this->_body->Id, temp * R[0], temp * R[4], temp * R[8]);

temp = -ny * linear_viscosity;
dBodyAddForce(this->_body->Id, temp * R[1], temp * R[5], temp * R[9]);

temp = -nz * linear_viscosity;
dBodyAddForce(this->_body->Id, temp * R[2], temp * R[6], temp * R[10]);

nx = (R[0] * avel[0] + R[4] * avel[1] + R[8] * avel[2]) * (AreaY + AreaZ);
ny = (R[1] * avel[0] + R[5] * avel[1] + R[9] * avel[2]) * (AreaX + AreaZ);
nz = (R[2] * avel[0] + R[6] * avel[1] + R[10] * avel[2]) * (AreaX + AreaY);

temp = -nx * angular_viscosity;
dBodyAddTorque(this->_body->Id, temp * R[0], temp * R[4], temp * R[8]);

temp = -ny * angular_viscosity;
dBodyAddTorque(this->_body->Id, temp * R[1], temp * R[5], temp * R[9]);

temp = -nz * angular_viscosity;
dBodyAddTorque(this->_body->Id, temp * R[2], temp * R[6], temp * R[10]);

dReal gravity[3];
dWorldGetGravity(this->_body->get_WorldId(), gravity);

temp = -density * ss[0] * ss[1] * ss[2];
dBodyAddForce(this->_body->Id, temp * gravity[0], temp * gravity[1], temp *
gravity[2]);

}

-----Original Message-----

So, does anyone have any comments on my underwater drag and buoyancy
approximation method?  Does anyone have any other ideas?

Tyler
_______________________________________________
```