MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
body.h File Reference
#include "elem.h"
#include "strnode.h"
#include "gravity.h"
Include dependency graph for body.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

class  Mass
 
class  DynamicMass
 
class  StaticMass
 
class  Body
 
class  DynamicBody
 
class  ModalBody
 
class  StaticBody
 

Functions

ElemReadBody (DataManager *pDM, MBDynParser &HP, unsigned int uLabel)
 

Function Documentation

Elem* ReadBody ( DataManager pDM,
MBDynParser HP,
unsigned int  uLabel 
)

Definition at line 1937 of file body.cc.

References DataManager::bIsInverseDynamics(), DataManager::bIsStaticModel(), Elem::BODY, DEBUGCOUTFNAME, DEBUGLCOUT, StructDispNode::DYNAMIC, InverseDynamics::ERGONOMY, DataManager::fReadOutput(), HighParser::GetInt(), WithLabel::GetLabel(), IncludeParser::GetLineData(), DataManager::GetLogFile(), MBDynParser::GetMatRel(), MBDynParser::GetPosRel(), HighParser::GetReal(), MBDynParser::GetRotRel(), DynamicStructDispNode::GetStructDispNodeType(), StaticStructDispNode::GetStructDispNodeType(), HighParser::GetYesNoOrBool(), HighParser::IsArg(), HighParser::IsKeyWord(), LASTKEYWORD, MatCrossCross, MBDYN_EXCEPT_ARGS, Mat3x3::MulMT(), MYDEBUG_INPUT, NO_OP, StructDispNode::pGetRBK(), DataManager::ReadNode(), ReadVariableBody(), InverseDynamics::RIGHT_HAND_SIDE, SAFENEWWITHCONSTRUCTOR, Elem::SetInverseDynamicsFlags(), StructDispNode::STATIC, Node::STRUCTURAL, Zero3, and Zero3x3.

Referenced by DataManager::ReadOneElem().

1938 {
1939  DEBUGCOUTFNAME("ReadBody");
1940 
1941  const char* sKeyWords[] = {
1942  NULL
1943  };
1944 
1945  /* enum delle parole chiave */
1946  enum KeyWords {
1947  UNKNOWN = -1,
1948  LASTKEYWORD = 0
1949  };
1950 
1951  /* tabella delle parole chiave */
1952  KeyTable K(HP, sKeyWords);
1953 
1954  /* nodo collegato */
1955  const StructDispNode *pStrDispNode = pDM->ReadNode<const StructDispNode, Node::STRUCTURAL>(HP);
1956  const StructNode *pStrNode = dynamic_cast<const StructNode *>(pStrDispNode);
1957 
1958  /* may be determined by a special DataManager parameter... */
1959  bool bStaticModel = pDM->bIsStaticModel();
1960  bool bInverseDynamics = pDM->bIsInverseDynamics();
1961 
1962  if (HP.IsKeyWord("variable" "mass")) {
1963  return ReadVariableBody(pDM, HP, uLabel, pStrNode);
1964  }
1965 
1966  integer iNumMasses = 1;
1967  if (HP.IsKeyWord("condense")) {
1968  iNumMasses = HP.GetInt();
1969  if (iNumMasses < 1) {
1970  silent_cerr("Body(" << uLabel << "): "
1971  "at least one mass is required in \"condense\" "
1972  "at line " << HP.GetLineData() << std::endl);
1974  }
1976  iNumMasses << " masses will be condensed" << std::endl);
1977 
1978  /* The inertia is calculated as follows:
1979  *
1980  * dm = Sum(dm_i)
1981  *
1982  * Xgc = Sum(Xgc_i*dm_i)/Sum(dm_i)
1983  *
1984  * J = Sum(J_i)-Sum(dm_i*(Xgc_i-Xgc)/\(Xgc_i-Xgc)/\)
1985  *
1986  * and it can be accomplished by accumulating:
1987  *
1988  * dm = Sum(dm_i)
1989  *
1990  * ~S = Sum(Xgc_i*dm_i)
1991  *
1992  * ~J = Sum(J_i)-Sum(dm_i*Xgc_i/\*Xgc_i/\)
1993  *
1994  * then calculating
1995  *
1996  * Xgc = S/dm
1997  *
1998  * and finally:
1999  *
2000  * J = ~J-Xgc/\(dm*Xgc/\-2*~S)
2001  *
2002  */
2003  }
2004 
2005  doublereal dm = 0.;
2006  ReferenceFrame RF(pStrDispNode);
2007  Vec3 Xgc(::Zero3);
2008  Vec3 STmp(::Zero3);
2009  Mat3x3 J(::Zero3x3);
2010  bool bNegative(false);
2011 
2012  if (HP.IsKeyWord("allow" "negative" "mass")) {
2013  bNegative = true;
2014  }
2015 
2016  for (int iCnt = 1; iCnt <= iNumMasses; iCnt++) {
2017  /* massa */
2018  doublereal dMTmp = HP.GetReal();
2019  if (!bNegative && dMTmp < 0.) {
2020  silent_cerr("Body(" << uLabel << "): "
2021  "negative mass is not allowed at line "
2022  << HP.GetLineData() << std::endl);
2024  }
2025 
2026  DEBUGLCOUT(MYDEBUG_INPUT, "Mass(" << iCnt << ") = " << dMTmp << std::endl);
2027  dm += dMTmp;
2028 
2029  if (pStrNode) {
2030  /* posiz. c.g. */
2031  Vec3 XgcTmp(HP.GetPosRel(RF));
2032  if (iNumMasses == 1) {
2033  Xgc = XgcTmp;
2034 
2035  } else {
2036  STmp += XgcTmp*dMTmp;
2037  }
2038 
2039  DEBUGLCOUT(MYDEBUG_INPUT, "position of mass(" << iCnt
2040  << ") center of gravity = " << XgcTmp << std::endl);
2041 
2042  /*
2043  * matrice del mom. d'inerzia
2044  *
2045  * Usa la funzione che legge una matrice qualsiasi con parole chiave
2046  * per forme abbreviate:
2047  * - null: matrice vuota
2048  * - eye: matrice identita'
2049  * - diag: matrice diagonale, seguita da 3 reali
2050  * - sym: matrice simmetrica, seguita da 6 reali,
2051  * letta come triangolare superiore ordinata per righe:
2052  * m11, m12, m13, m22, m23, m33
2053  * - matrice generica, costituita da 9 reali, letta per righe:
2054  * m11, m12, m13, m21, m22, m23, m31, m32, m33
2055  *
2056  * Si assume inoltre che la matrice dei momenti di inerzia
2057  * sia espressa nel centro di massa del corpo, quindi viene
2058  * corretta per l'eventuale offset rispetto al nodo
2059  */
2060  Mat3x3 JTmp(HP.GetMatRel(RF));
2061  DEBUGLCOUT(MYDEBUG_INPUT, "Inertia matrix of mass(" << iCnt
2062  << ") =" << std::endl << JTmp << std::endl);
2063  if (!JTmp.IsSymmetric()) {
2064  silent_cerr("Body(" << uLabel << "): "
2065  "warning, non-symmetric inertia tensor at line " << HP.GetLineData() << std::endl);
2066  }
2067 
2068  if (HP.IsKeyWord("inertial")) {
2070  "supplied in inertial reference frame" << std::endl);
2071  if (HP.IsKeyWord("node")) {
2072  NO_OP;
2073  } else {
2074  Mat3x3 RTmp(HP.GetRotRel(RF));
2075  JTmp = RTmp*JTmp.MulMT(RTmp);
2076  }
2078  "Inertia matrix of mass(" << iCnt << ") "
2079  "in current frame =" << JTmp << std::endl);
2080  }
2081 
2082  J += JTmp - Mat3x3(MatCrossCross, XgcTmp, XgcTmp*dMTmp);
2083  }
2084  }
2085 
2086  if (!bNegative && dm < 0.) {
2087  silent_cerr("Body(" << uLabel << "): "
2088  "negative mass is not allowed at line "
2089  << HP.GetLineData() << std::endl);
2091  }
2092 
2093  if (iNumMasses > 1 && pStrNode) {
2094  if (dm < std::numeric_limits<doublereal>::epsilon()) {
2095  silent_cerr("Body(" << uLabel << "): "
2096  "mass value " << dm << " is too small at line "
2097  << HP.GetLineData() << std::endl);
2099  }
2100 
2101  Xgc = STmp/dm;
2102  }
2103 
2104  DEBUGLCOUT(MYDEBUG_INPUT, "Total mass: " << dm << std::endl
2105  << "Center of mass: " << Xgc << std::endl
2106  << "Inertia matrix:" << std::endl << J << std::endl);
2107 
2108  const DynamicStructDispNode* pDynamicDispNode = 0;
2109  const StaticStructDispNode* pStaticDispNode = 0;
2110  const char *sElemName;
2111  const char *sNodeName;
2112  if (pStrNode) {
2113  sElemName = "Body";
2114  sNodeName = "StructNode";
2115  } else {
2116  sElemName = "Mass";
2117  sNodeName = "StructDispNode";
2118  }
2119 
2120  if (bStaticModel || bInverseDynamics) {
2121  /* static */
2122  pStaticDispNode = dynamic_cast<const StaticStructDispNode *>(pStrDispNode);
2123  if (pStaticDispNode == 0 || pStaticDispNode->GetStructDispNodeType() != StructDispNode::STATIC) {
2124  silent_cerr(sElemName << "(" << uLabel << "): "
2125  "illegal structural node type "
2126  "for " << sNodeName << "(" << pStrDispNode->GetLabel() << ") "
2127  "in " << (bStaticModel ? "static model" : "inverse dynamics") << " analysis "
2128  "at line " << HP.GetLineData() << std::endl);
2130  }
2131 
2132  } else {
2133  pDynamicDispNode = dynamic_cast<const DynamicStructDispNode*>(pStrDispNode);
2134  if (pDynamicDispNode == 0 || pDynamicDispNode->GetStructDispNodeType() != StructDispNode::DYNAMIC) {
2135  silent_cerr(sElemName << "(" << uLabel << "): "
2136  "illegal structural node type "
2137  "for " << sNodeName << "(" << pStrDispNode->GetLabel() << ") "
2138  "at line " << HP.GetLineData() << std::endl);
2140  }
2141  }
2142 
2143  flag fOut = pDM->fReadOutput(HP, Elem::BODY);
2144 
2145  /* Allocazione e costruzione */
2146  Elem* pEl = NULL;
2147  if (bStaticModel || bInverseDynamics) {
2148  StaticBody *pSB = 0;
2149  StaticMass *pSM = 0;
2150 
2151  /* static */
2152  if (pStrNode) {
2154  StaticBody(uLabel, dynamic_cast<const StaticStructNode *>(pStaticDispNode),
2155  dm, Xgc, J, fOut));
2156  pEl = pSB;
2157 
2158  } else {
2160  StaticMass(uLabel, pStaticDispNode,
2161  dm, fOut));
2162  pEl = pSM;
2163  }
2164 
2165  if (bInverseDynamics) {
2166  bool bIsRightHandSide(true);
2167  bool bIsErgonomy(true);
2168 
2169  if (HP.IsKeyWord("inverse" "dynamics")) {
2170  bIsRightHandSide = false;
2171  if (HP.IsKeyWord("right" "hand" "side")) {
2172  bIsRightHandSide = HP.GetYesNoOrBool(bIsRightHandSide);
2173  }
2174 
2175  bIsErgonomy = false;
2176  if (HP.IsKeyWord("ergonomy")) {
2177  bIsErgonomy = HP.GetYesNoOrBool(bIsErgonomy);
2178  }
2179  }
2180 
2181  unsigned flags = 0;
2182 
2183  if (bIsRightHandSide) {
2185  }
2186 
2187  if (bIsErgonomy) {
2188  flags |= InverseDynamics::ERGONOMY;
2189  }
2190 
2191  if (pSB) {
2192  pSB->SetInverseDynamicsFlags(flags);
2193 
2194  } else {
2195  pSM->SetInverseDynamicsFlags(flags);
2196  }
2197  }
2198 
2199  } else {
2200  if (pStrNode) {
2201  const DynamicStructNode* pDynamicStructNode = dynamic_cast<const DynamicStructNode*>(pDynamicDispNode);
2202  const ModalNode* pModalNode = dynamic_cast<const ModalNode*>(pDynamicDispNode);
2203  const RigidBodyKinematics* pRBK = pDynamicStructNode->pGetRBK();
2204 
2205  if (pModalNode && pRBK) {
2206  silent_cerr("Body(" << uLabel << ") "
2207  "is connected to ModalNode(" << pModalNode->GetLabel() << ") "
2208  "which uses rigid body kinematics "
2209  "at line " << HP.GetLineData() << std::endl);
2211  }
2212 
2213  if (pModalNode) {
2215  ModalBody(uLabel, pModalNode, dm, Xgc, J, fOut));
2216 
2217  } else {
2219  DynamicBody(uLabel, pDynamicStructNode, dm, Xgc, J, fOut));
2220  }
2221  } else {
2223  DynamicMass(uLabel, pDynamicDispNode,
2224  dm, fOut));
2225  }
2226  }
2227 
2228  pDM->GetLogFile()
2229  << "body: " << uLabel
2230  << ' ' << pStrDispNode->GetLabel()
2231  << ' ' << dm
2232  << ' ' << Xgc
2233  << ' ' << J
2234  << std::endl;
2235 
2236  /* Se non c'e' il punto e virgola finale */
2237  if (HP.IsArg()) {
2238  silent_cerr("semicolon expected "
2239  "at line " << HP.GetLineData() << std::endl);
2241  }
2242 
2243  return pEl;
2244 } /* End of ReadBody() */
flag fReadOutput(MBDynParser &HP, const T &t) const
Definition: dataman.h:1064
Mat3x3 GetRotRel(const ReferenceFrame &rf)
Definition: mbpar.cc:1795
virtual StructDispNode::Type GetStructDispNodeType(void) const
Definition: strnode.cc:1101
const Vec3 Zero3(0., 0., 0.)
long int flag
Definition: mbdyn.h:43
#define MBDYN_EXCEPT_ARGS
Definition: except.h:63
Definition: matvec3.h:98
#define DEBUGCOUTFNAME(fname)
Definition: myassert.h:256
virtual integer GetInt(integer iDefval=0)
Definition: parser.cc:1050
#define NO_OP
Definition: myassert.h:74
virtual StructDispNode::Type GetStructDispNodeType(void) const
Definition: strnode.cc:1429
bool bIsStaticModel(void) const
Definition: dataman.h:482
void SetInverseDynamicsFlags(unsigned uIDF)
Definition: elem.cc:71
virtual bool GetYesNoOrBool(bool bDefval=false)
Definition: parser.cc:1038
const Mat3x3 Zero3x3(0., 0., 0., 0., 0., 0., 0., 0., 0.)
Vec3 GetPosRel(const ReferenceFrame &rf)
Definition: mbpar.cc:1331
virtual bool IsKeyWord(const char *sKeyWord)
Definition: parser.cc:910
Mat3x3 GetMatRel(const ReferenceFrame &rf)
Definition: mbpar.cc:1737
const RigidBodyKinematics * pGetRBK(void) const
Definition: strnode.cc:152
KeyWords
Definition: dataman4.cc:94
#define SAFENEWWITHCONSTRUCTOR(pnt, item, constructor)
Definition: mynewmem.h:698
const MatCrossCross_Manip MatCrossCross
Definition: matvec3.cc:640
virtual bool IsArg(void)
Definition: parser.cc:807
Definition: elem.h:75
std::ostream & GetLogFile(void) const
Definition: dataman.h:326
Elem * ReadVariableBody(DataManager *pDM, MBDynParser &HP, unsigned int uLabel, const StructNode *pStrNode)
Definition: body_vm.cc:1022
Mat3x3 MulMT(const Mat3x3 &m) const
Definition: matvec3.cc:444
double doublereal
Definition: colamd.c:52
long int integer
Definition: colamd.c:51
virtual HighParser::ErrOut GetLineData(void) const
Definition: parsinc.cc:697
unsigned int GetLabel(void) const
Definition: withlab.cc:62
Node * ReadNode(MBDynParser &HP, Node::Type type) const
Definition: dataman3.cc:2309
#define DEBUGLCOUT(level, msg)
Definition: myassert.h:244
bool bIsInverseDynamics(void) const
Definition: dataman.h:493
virtual doublereal GetReal(const doublereal &dDefval=0.0)
Definition: parser.cc:1056

Here is the call graph for this function: