1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "momentOfInertia.H"
27 #include "polyMeshTetDecomposition.H"
29 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
31 void Foam::momentOfInertia::massPropertiesSolid
33 const pointField& pts,
34 const triFaceList& triFaces,
41 // Reimplemented from: Wm4PolyhedralMassProperties.cpp
42 // File Version: 4.10.0 (2009/11/18)
44 // Geometric Tools, LC
45 // Copyright (c) 1998-2010
46 // Distributed under the Boost Software License, Version 1.0.
47 // http://www.boost.org/LICENSE_1_0.txt
48 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
50 // Boost Software License - Version 1.0 - August 17th, 2003
52 // Permission is hereby granted, free of charge, to any person or
53 // organization obtaining a copy of the software and accompanying
54 // documentation covered by this license (the "Software") to use,
55 // reproduce, display, distribute, execute, and transmit the
56 // Software, and to prepare derivative works of the Software, and
57 // to permit third-parties to whom the Software is furnished to do
58 // so, all subject to the following:
60 // The copyright notices in the Software and this entire
61 // statement, including the above license grant, this restriction
62 // and the following disclaimer, must be included in all copies of
63 // the Software, in whole or in part, and all derivative works of
64 // the Software, unless such copies or derivative works are solely
65 // in the form of machine-executable object code generated by a
66 // source language processor.
68 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
69 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
70 // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
71 // NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
72 // ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR
73 // OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
74 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
75 // USE OR OTHER DEALINGS IN THE SOFTWARE.
77 const scalar r6 = 1.0/6.0;
78 const scalar r24 = 1.0/24.0;
79 const scalar r60 = 1.0/60.0;
80 const scalar r120 = 1.0/120.0;
82 // order: 1, x, y, z, x^2, y^2, z^2, xy, yz, zx
83 scalarField integrals(10, 0.0);
87 const triFace& tri(triFaces[i]);
89 // vertices of triangle i
90 vector v0 = pts[tri[0]];
91 vector v1 = pts[tri[1]];
92 vector v2 = pts[tri[2]];
94 // cross product of edges
99 // compute integral terms
100 scalar tmp0, tmp1, tmp2;
102 scalar f1x, f2x, f3x, g0x, g1x, g2x;
104 tmp0 = v0.x() + v1.x();
106 tmp1 = v0.x()*v0.x();
107 tmp2 = tmp1 + v1.x()*tmp0;
108 f2x = tmp2 + v2.x()*f1x;
109 f3x = v0.x()*tmp1 + v1.x()*tmp2 + v2.x()*f2x;
110 g0x = f2x + v0.x()*(f1x + v0.x());
111 g1x = f2x + v1.x()*(f1x + v1.x());
112 g2x = f2x + v2.x()*(f1x + v2.x());
114 scalar f1y, f2y, f3y, g0y, g1y, g2y;
116 tmp0 = v0.y() + v1.y();
118 tmp1 = v0.y()*v0.y();
119 tmp2 = tmp1 + v1.y()*tmp0;
120 f2y = tmp2 + v2.y()*f1y;
121 f3y = v0.y()*tmp1 + v1.y()*tmp2 + v2.y()*f2y;
122 g0y = f2y + v0.y()*(f1y + v0.y());
123 g1y = f2y + v1.y()*(f1y + v1.y());
124 g2y = f2y + v2.y()*(f1y + v2.y());
126 scalar f1z, f2z, f3z, g0z, g1z, g2z;
128 tmp0 = v0.z() + v1.z();
130 tmp1 = v0.z()*v0.z();
131 tmp2 = tmp1 + v1.z()*tmp0;
132 f2z = tmp2 + v2.z()*f1z;
133 f3z = v0.z()*tmp1 + v1.z()*tmp2 + v2.z()*f2z;
134 g0z = f2z + v0.z()*(f1z + v0.z());
135 g1z = f2z + v1.z()*(f1z + v1.z());
136 g2z = f2z + v2.z()*(f1z + v2.z());
139 integrals[0] += n.x()*f1x;
140 integrals[1] += n.x()*f2x;
141 integrals[2] += n.y()*f2y;
142 integrals[3] += n.z()*f2z;
143 integrals[4] += n.x()*f3x;
144 integrals[5] += n.y()*f3y;
145 integrals[6] += n.z()*f3z;
146 integrals[7] += n.x()*(v0.y()*g0x + v1.y()*g1x + v2.y()*g2x);
147 integrals[8] += n.y()*(v0.z()*g0y + v1.z()*g1y + v2.z()*g2y);
148 integrals[9] += n.z()*(v0.x()*g0z + v1.x()*g1z + v2.x()*g2z);
158 integrals[7] *= r120;
159 integrals[8] *= r120;
160 integrals[9] *= r120;
166 cM = vector(integrals[1], integrals[2], integrals[3])/mass;
168 // inertia relative to origin
169 J.xx() = integrals[5] + integrals[6];
170 J.xy() = -integrals[7];
171 J.xz() = -integrals[9];
173 J.yy() = integrals[4] + integrals[6];
174 J.yz() = -integrals[8];
177 J.zz() = integrals[4] + integrals[5];
179 // inertia relative to center of mass
180 J -= mass*((cM & cM)*I - cM*cM);
188 void Foam::momentOfInertia::massPropertiesShell
190 const pointField& pts,
191 const triFaceList& triFaces,
198 // Reset properties for accumulation
204 // Find centre of mass
208 const triFace& tri(triFaces[i]);
217 scalar triMag = t.mag();
219 cM += triMag*t.centre();
228 // Find inertia around centre of mass
232 const triFace& tri(triFaces[i]);
239 ).inertia(cM, density);
244 void Foam::momentOfInertia::massPropertiesSolid
246 const triSurface& surf,
253 triFaceList faces(surf.size());
257 faces[i] = triFace(surf[i]);
260 massPropertiesSolid(surf.points(), faces, density, mass, cM, J);
264 void Foam::momentOfInertia::massPropertiesShell
266 const triSurface& surf,
273 triFaceList faces(surf.size());
277 faces[i] = triFace(surf[i]);
280 massPropertiesShell(surf.points(), faces, density, mass, cM, J);
284 Foam::tensor Foam::momentOfInertia::applyParallelAxisTheorem
292 // The displacement vector (refPt = cM) is the displacement of the
293 // new reference point from the centre of mass of the body that
294 // the inertia tensor applies to.
296 vector d = (refPt - cM);
298 return J + mass*((d & d)*I - d*d);
302 Foam::tmp<Foam::tensorField> Foam::momentOfInertia::meshInertia
307 tmp<tensorField> tTf = tmp<tensorField>(new tensorField(mesh.nCells()));
309 tensorField& tf = tTf();
313 tf[cI] = meshInertia(mesh, cI);
320 Foam::tensor Foam::momentOfInertia::meshInertia
322 const polyMesh& mesh,
326 List<tetIndices> cellTets = polyMeshTetDecomposition::cellTetIndices
332 triFaceList faces(cellTets.size());
334 forAll(cellTets, cTI)
336 faces[cTI] = cellTets[cTI].faceTriIs(mesh);
340 vector cM = vector::zero;
341 tensor J = tensor::zero;
343 massPropertiesSolid(mesh.points(), faces, 1.0, m, cM, J);
349 // ************************************************************************* //