1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/mbdyn/aero/indvel.h,v 1.20 2017/01/12 14:45:58 masarati Exp $ */ 2 /* 3 * MBDyn (C) is a multibody analysis code. 4 * http://www.mbdyn.org 5 * 6 * Copyright (C) 1996-2017 7 * 8 * Pierangelo Masarati <masarati@aero.polimi.it> 9 * Paolo Mantegazza <mantegazza@aero.polimi.it> 10 * 11 * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano 12 * via La Masa, 34 - 20156 Milano, Italy 13 * http://www.aero.polimi.it 14 * 15 * Changing this copyright notice is forbidden. 16 * 17 * This program is free software; you can redistribute it and/or modify 18 * it under the terms of the GNU General Public License as published by 19 * the Free Software Foundation (version 2 of the License). 20 * 21 * 22 * This program is distributed in the hope that it will be useful, 23 * but WITHOUT ANY WARRANTY; without even the implied warranty of 24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 * GNU General Public License for more details. 26 * 27 * You should have received a copy of the GNU General Public License 28 * along with this program; if not, write to the Free Software 29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 30 */ 31 32 #ifndef INDVEL_H 33 #define INDVEL_H 34 35 #include <cfloat> 36 37 #include "ac/pthread.h" 38 #ifdef USE_MPI 39 #include "ac/mpi.h" 40 #endif // USE_MPI 41 42 #include "aerodyn.h" 43 #include "strnode.h" 44 #include "resforces.h" 45 46 /* InducedVelocity - begin */ 47 48 class InducedVelocity 49 : virtual public Elem { 50 public: 51 enum Type { 52 UNKNOWN = -1, 53 54 // non-rotating... 55 56 USER_DEFINED = 0x01000000U, 57 ROTOR = 0x10000000U, 58 59 // rotating... 60 61 NO = (0U | ROTOR), 62 UNIFORM = (1U | ROTOR), 63 GLAUERT = (2U | ROTOR), 64 MANGLER = (3U | ROTOR), 65 DYNAMICINFLOW = (4U | ROTOR), 66 PETERS_HE = (5U | ROTOR), 67 68 CYCLOCOPTER = (11U | ROTOR), 69 70 LASTROTORTYPE 71 }; 72 73 public: 74 class ErrInfiniteMeanInducedVelocity : public MBDynErrBase { 75 public: ErrInfiniteMeanInducedVelocity(MBDYN_EXCEPT_ARGS_DECL)76 ErrInfiniteMeanInducedVelocity(MBDYN_EXCEPT_ARGS_DECL) : MBDynErrBase(MBDYN_EXCEPT_ARGS_PASSTHRU) {}; 77 }; 78 79 protected: 80 #ifdef USE_MPI 81 // Communicator per il calcolo della trazione totale 82 bool is_parallel; 83 // Gruppo di macchine su cui si scambiano dati relativi al rotore 84 MPI::Intracomm IndVelComm; 85 int* pBlockLenght; 86 // vettore di indirizzi di dati 87 MPI::Aint* pDispl; 88 // request per le comunicazioni Send Receive 89 MPI::Request ReqV; 90 // dimensioni vettore forze scambiato fra i processi 91 integer iForcesVecDim; 92 // vettori temporanei per scambio forze 93 doublereal* pTmpVecR; 94 doublereal* pTmpVecS; 95 // datatype che contiene le posizioni 96 // dei dati da scambiare ad ogni passo 97 MPI::Datatype* pIndVelDataType; 98 #endif // USE_MPI 99 100 #if defined(USE_MULTITHREAD) && defined(MBDYN_X_MT_ASSRES) 101 mutable pthread_mutex_t forces_mutex; 102 103 mutable pthread_mutex_t induced_velocity_mutex; 104 mutable pthread_cond_t induced_velocity_cond; 105 mutable bool bDone; 106 107 void Wait(void) const; 108 void Done(void) const; 109 #endif // USE_MULTITHREAD && MBDYN_X_MT_ASSRES 110 111 const StructNode* pCraft; 112 113 // force, couple and pole for resultants 114 ExternResForces Res; 115 // extra forces 116 ResForceSet **ppRes; 117 118 public: 119 InducedVelocity(unsigned int uL, 120 const StructNode* pCraft, 121 ResForceSet **ppres, flag fOut); 122 virtual ~InducedVelocity(void); 123 124 // funzioni di servizio 125 126 /* Metodi per l'estrazione di dati "privati". 127 * Si suppone che l'estrattore li sappia interpretare. 128 * Come default non ci sono dati privati estraibili */ 129 virtual unsigned int iGetNumPrivData(void) const; 130 virtual unsigned int iGetPrivDataIdx(const char *s) const; 131 virtual doublereal dGetPrivData(unsigned int i) const; 132 133 // Return "true" if sectional forces are needed 134 virtual bool bSectionalForces(void) const; 135 136 /* Il metodo iGetNumDof() serve a ritornare il numero di gradi di liberta' 137 * propri che l'elemento definisce. Non e' virtuale in quanto serve a 138 * ritornare 0 per gli elementi che non possiedono gradi di liberta'. 139 * Viene usato nella costruzione dei DofOwner e quindi deve essere 140 * indipendente da essi. In genere non comporta overhead in quanto il 141 * numero di dof aggiunti da un tipo e' una costante e non richede dati 142 * propri. 143 * Il metodo pGetDofOwner() ritorna il puntatore al DofOwner dell'oggetto. 144 * E' usato da tutti quelli che agiscono direttamente sui DofOwner. 145 * Non e' virtuale in quanto ritorna NULL per tutti i tipi che non hanno 146 * dof propri. 147 * Il metodo GetDofType() ritorna, per ogni dof dell'elemento, l'ordine. 148 * E' usato per completare i singoli Dof relativi all'elemento. 149 */ 150 151 // ritorna il numero di Dofs per gli elementi che sono anche DofOwners iGetNumDof(void)152 virtual unsigned int iGetNumDof(void) const { 153 return 0; 154 }; 155 156 // Type 157 virtual InducedVelocity::Type GetInducedVelocityType(void) const = 0; 158 GetXCurr(void)159 virtual inline const Vec3& GetXCurr(void) const { 160 return pCraft->GetXCurr(); 161 }; 162 GetForces(void)163 virtual inline const Vec3& GetForces(void) const { 164 #if defined(USE_MULTITHREAD) && defined(MBDYN_X_MT_ASSRES) 165 Wait(); 166 #endif // USE_MULTITHREAD && MBDYN_X_MT_ASSRES 167 return Res.Force(); 168 }; 169 GetMoments(void)170 virtual inline const Vec3& GetMoments(void) const { 171 #if defined(USE_MULTITHREAD) && defined(MBDYN_X_MT_ASSRES) 172 Wait(); 173 #endif // USE_MULTITHREAD && MBDYN_X_MT_ASSRES 174 return Res.Moment(); 175 }; 176 177 // Elements use this function to pass induced velocity models 178 // their contribution to forces and moments at a specific location X. 179 // Each element can call this function multiple times to provide 180 // multiple contributions in one iteration. 181 // Elements must not call this function when bSectionalForces() 182 // returns "true" 183 virtual void AddForce(const Elem *pEl, const StructNode *pNode, 184 const Vec3& F, const Vec3& M, const Vec3& X); 185 186 // Elements use this function to pass induced velocity models 187 // their contribution to sectional forces and moments at a specific 188 // location X. 189 // Each element can call this function multiple times to provide 190 // multiple contributions in one iteration. 191 // Elements should not call this function when bSectionalForces() 192 // returns "false" 193 virtual void AddSectionalForce(Elem::Type type, 194 const Elem *pEl, unsigned uPnt, 195 const Vec3& F, const Vec3& M, doublereal dW, 196 const Vec3& X, const Mat3x3& R, 197 const Vec3& V, const Vec3& W); 198 199 virtual void ResetForce(void); 200 201 // Restituisce ad un elemento la velocita' indotta 202 // in base alla posizione azimuthale 203 virtual Vec3 GetInducedVelocity(Elem::Type type, 204 unsigned uLabel, unsigned uPnt, const Vec3& X) const = 0; 205 206 // Dimensioni del workspace 207 virtual void WorkSpaceDim(integer * piNumRows,integer * piNumCols)208 WorkSpaceDim(integer* piNumRows, integer* piNumCols) const { 209 *piNumRows = 0; 210 *piNumCols = 0; 211 }; 212 213 // assemblaggio jacobiano 214 virtual VariableSubMatrixHandler& 215 AssJac(VariableSubMatrixHandler& WorkMat, 216 doublereal dCoef, 217 const VectorHandler& XCurr, 218 const VectorHandler& XPrimeCurr); 219 220 // Elaborazione stato interno dopo la convergenza 221 virtual void 222 AfterConvergence(const VectorHandler& X, const VectorHandler& XP); 223 224 // Relativo ai ...WithDofs SetInitialValue(VectorHandler &)225 virtual void SetInitialValue(VectorHandler& /* X */ ) { 226 NO_OP; 227 }; 228 229 // Relativo ai ...WithDofs 230 virtual void 231 SetValue(DataManager *pDM, 232 VectorHandler& /* X */ , VectorHandler& /* XP */ , 233 SimulationEntity::Hints *ph = 0) 234 { 235 NO_OP; 236 }; 237 238 // *******PER IL SOLUTORE PARALLELO******** 239 // Fornisce il tipo e la label dei nodi che sono connessi all'elemento 240 // utile per l'assemblaggio della matrice di connessione fra i dofs 241 virtual void GetConnectedNodes(std::vector<const Node * > & connectedNodes)242 GetConnectedNodes(std::vector<const Node *>& connectedNodes) const { 243 connectedNodes.resize(1); 244 connectedNodes[0] = pCraft; 245 }; 246 // ************************************************ 247 248 #ifdef USE_MPI 249 void ExchangeLoads(flag fWhat); // ExchangeLoads 250 void InitializeIndVelComm(MPI::Intracomm* Rot); // InitializeIndVelComm 251 void ExchangeVelocity(void); 252 #endif /* USE_MPI */ 253 }; 254 255 /* InducedVelocity - end */ 256 257 /* InducedVelocityElem - begin */ 258 259 class InducedVelocityElem 260 : virtual public Elem, public AerodynamicElem, public InducedVelocity { 261 public: 262 InducedVelocityElem(unsigned int uL, const DofOwner* pDO, 263 const StructNode* pCraft, 264 ResForceSet **ppres, flag fOut); 265 virtual ~InducedVelocityElem(void); 266 267 // funzioni di servizio 268 269 // Tipo dell'elemento (usato per debug ecc.) 270 virtual Elem::Type GetElemType(void) const; 271 virtual AerodynamicElem::Type GetAerodynamicElemType(void) const; 272 273 /* Il metodo iGetNumDof() serve a ritornare il numero di gradi di liberta' 274 * propri che l'elemento definisce. Non e' virtuale in quanto serve a 275 * ritornare 0 per gli elementi che non possiedono gradi di liberta'. 276 * Viene usato nella costruzione dei DofOwner e quindi deve essere 277 * indipendente da essi. In genere non comporta overhead in quanto il 278 * numero di dof aggiunti da un tipo e' una costante e non richede dati 279 * propri. 280 * Il metodo pGetDofOwner() ritorna il puntatore al DofOwner dell'oggetto. 281 * E' usato da tutti quelli che agiscono direttamente sui DofOwner. 282 * Non e' virtuale in quanto ritorna NULL per tutti i tipi che non hanno 283 * dof propri. 284 * Il metodo GetDofType() ritorna, per ogni dof dell'elemento, l'ordine. 285 * E' usato per completare i singoli Dof relativi all'elemento. 286 */ 287 288 // esegue operazioni sui dof di proprieta' dell'elemento GetDofType(unsigned int i)289 virtual DofOrder::Order GetDofType(unsigned int i) const { 290 ASSERT(i >= 0 && i < this->iGetNumDof()); 291 return DofOrder::DIFFERENTIAL; 292 }; 293 }; 294 295 /* InducedVelocityElem - end */ 296 297 #endif // INDVEL_H 298 299