MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
indvel.cc
Go to the documentation of this file.
1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/mbdyn/aero/indvel.cc,v 1.19 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 /* Rotore */
33 
34 #include "mbconfig.h" /* This goes first in every *.c,*.cc file */
35 
36 #include <limits>
37 #include <cmath>
38 
39 #ifdef USE_MPI
40 #include "mysleep.h"
41 const int mysleeptime = 300;
42 
43 #ifdef MPI_PROFILING
44 extern "C" {
45 #include <mpe.h>
46 }
47 #include <cstdio>
48 #endif /* MPI_PROFILING */
49 #include "mbcomm.h"
50 #endif /* USE_MPI */
51 
52 #include "indvel.h"
53 #include "dataman.h"
54 
55 /* InducedVelocity - begin */
56 
58  const StructNode *pCraft,
59  ResForceSet **ppres, flag fOut)
60 : Elem(uL, fOut),
61 #ifdef USE_MPI
62 is_parallel(false),
63 pBlockLenght(0),
64 pDispl(0),
65 ReqV(MPI::REQUEST_NULL),
66 pIndVelDataType(0),
67 #endif /* USE_MPI */
68 pCraft(pCraft),
69 ppRes(ppres)
70 {
71 #ifdef USE_MPI
72  iForcesVecDim = 6;
73  for (int i = 0; ppRes && ppRes[i]; i++) {
74  iForcesVecDim += 6;
75  }
76  SAFENEWARR(pTmpVecR, doublereal, iForcesVecDim);
77  SAFENEWARR(pTmpVecS, doublereal, iForcesVecDim);
78  if (MPI::Is_initialized()) {
79  is_parallel = true;
80  IndVelComm = MBDynComm.Dup();
81  }
82 #endif /* USE_MPI */
83 
84 #if defined(USE_MULTITHREAD) && defined(MBDYN_X_MT_ASSRES)
85  pthread_mutex_init(&induced_velocity_mutex, NULL);
86  pthread_cond_init(&induced_velocity_cond, NULL);
87  pthread_mutex_init(&forces_mutex, NULL);
88 #endif /* USE_MULTITHREAD && MBDYN_X_MT_ASSRES */
89 }
90 
92 {
93 #ifdef USE_MPI
94  SAFEDELETEARR(pTmpVecR);
95  SAFEDELETEARR(pTmpVecS);
96 #endif /* USE_MPI */
97 
98 #if defined(USE_MULTITHREAD) && defined(MBDYN_X_MT_ASSRES)
99  pthread_mutex_destroy(&induced_velocity_mutex);
100  pthread_cond_destroy(&induced_velocity_cond);
101  pthread_mutex_destroy(&forces_mutex);
102 #endif /* USE_MULTITHREAD && MBDYN_X_MT_ASSRES */
103 }
104 
105 bool
107 {
108  return false;
109 }
110 
111 unsigned int
113  return 6;
114 }
115 
116 unsigned int
118 {
119  ASSERT(s != 0);
120 
121  unsigned int idx = 0;
122 
123  // sanity check
124  if (s[0] == '\0' || s[1] == '\0' || s[2] != '\0' ) {
125  return 0;
126  }
127 
128  switch (s[0]) {
129  case 'M':
130  idx += 3;
131  // fallthru
132 
133  case 'T':
134  switch (s[1]) {
135  case 'x':
136  return idx + 1;
137 
138  case 'y':
139  return idx + 2;
140 
141  case 'z':
142  return idx + 3;
143  }
144  }
145 
146  return 0;
147 }
148 
150 InducedVelocity::dGetPrivData(unsigned int i) const
151 {
152  ASSERT(i > 0 && i <= 6);
153 
154  switch (i) {
155  case 1:
156  case 2:
157  case 3:
158  return Res.Force()(i);
159 
160  case 4:
161  case 5:
162  case 6:
163  return Res.Moment()(i - 3);
164  }
165 
167 }
168 
169 void
171  const VectorHandler& /* XP */ )
172 {
173 #if defined(USE_MULTITHREAD) && defined(MBDYN_X_MT_ASSRES)
174  ASSERT(bDone);
175  bDone = false;
176 #endif // USE_MULTITHREAD && MBDYN_X_MT_ASSRES
177 }
178 
179 /* assemblaggio jacobiano (nullo per tutti tranne che per il DynamicInflow) */
182  doublereal /* dCoef */ ,
183  const VectorHandler& /* XCurr */ ,
184  const VectorHandler& /* XPrimeCurr */ )
185 {
186  DEBUGCOUT("Entering InducedVelocity::AssJac()" << std::endl);
187  WorkMat.SetNullMatrix();
188 
189  return WorkMat;
190 }
191 
192 #ifdef USE_MPI
193 void
194 InducedVelocity::ExchangeLoads(flag fWhat)
195 {
196 #ifdef MPI_PROFILING
197  MPE_Log_event(33, 0, "start Induced Velocity Loads Exchange ");
198 #endif /* MPI_PROFILING */
199  /* Se il rotore è connesso ad una sola macchina non è necessario scambiare messaggi */
200  if (is_parallel && IndVelComm.Get_size() > 1) {
201  if (fWhat) {
202  /* Scambia F e M */
203  Res.Force().PutTo(&pTmpVecS[0]);
204  Res.Moment().PutTo(&pTmpVecS[3]);
205  for (int i = 0; ppRes && ppRes[i]; i++) {
206  ppRes[i]->pRes->Force().PutTo(&pTmpVecS[6 + 6*i]);
207  ppRes[i]->pRes->Moment().PutTo(&pTmpVecS[9 + 6*i]);
208  }
209  IndVelComm.Allreduce(pTmpVecS, pTmpVecR, iForcesVecDim, MPI::DOUBLE, MPI::SUM);
210  Res.PutForces(Vec3(&pTmpVecR[0]), Vec3(&pTmpVecR[3]));
211  for (int i = 0; ppRes && ppRes[i]; i++) {
212  ppRes[i]->pRes->PutForces(Vec3(&pTmpVecR[6 + 6*i]), Vec3(&pTmpVecR[9 + 6*i]));
213  }
214 
215  } else {
216  IndVelComm.Allreduce(Res.Force().pGetVec(), pTmpVecR, 3, MPI::DOUBLE, MPI::SUM);
217  Res.PutForce(Vec3(pTmpVecR));
218  }
219  }
220 #ifdef MPI_PROFILING
221  MPE_Log_event(34, 0, "end Induced Velocity Loads Exchange ");
222 #endif /* MPI_PROFILING */
223 }
224 
225 void
226 InducedVelocity::InitializeIndVelComm(MPI::Intracomm* iv)
227 {
228  ASSERT(is_parallel);
229  IndVelComm = *iv;
230 }
231 
232 void
233 InducedVelocity::ExchangeVelocity(void)
234 {
235 #define ROTDATATYPELABEL 100
236  if (is_parallel && IndVelComm.Get_size() > 1) {
237  if (IndVelComm.Get_rank() == 0) {
238  for (int i = 1; i < IndVelComm.Get_size(); i++) {
239  IndVelComm.Send(MPI::BOTTOM, 1, *pIndVelDataType,
240  i, ROTDATATYPELABEL);
241  }
242  } else {
243  ReqV = IndVelComm.Irecv((void *)MPI::BOTTOM, 1,
244  *pIndVelDataType, 0, ROTDATATYPELABEL);
245  }
246  }
247 }
248 #endif // USE_MPI
249 
250 // Somma alla trazione il contributo di forza di un elemento generico
251 void
252 InducedVelocity::AddForce(const Elem *pEl, const StructNode *pNode,
253  const Vec3& F, const Vec3& M, const Vec3& X)
254 {
255  for (int i = 0; ppRes && ppRes[i]; i++) {
256  if (ppRes[i]->is_in(pEl->GetLabel())) {
257  ppRes[i]->pRes->AddForces(F, M, X);
258  }
259  }
260 }
261 
262 // Somma alla trazione il contributo di forza di un elemento generico
263 // usando la forza e il momento per unita' di apertura e il peso
264 void
266  const Elem *pEl, unsigned uPnt,
267  const Vec3& F, const Vec3& M, doublereal dW,
268  const Vec3& X, const Mat3x3& R,
269  const Vec3& V, const Vec3& W)
270 {
271  ASSERT(bSectionalForces() == true);
272  InducedVelocity::AddForce(pEl, 0, F*dW, M*dW, X);
273 }
274 
275 void
277 {
278  Res.Reset(pCraft->GetXCurr());
279  for (int i = 0; ppRes && ppRes[i]; i++) {
280  ppRes[i]->pRes->Reset();
281  }
282 }
283 
284 #if defined(USE_MULTITHREAD) && defined(MBDYN_X_MT_ASSRES)
285 void
286 InducedVelocity::Wait(void) const
287 {
288  pthread_mutex_lock(&induced_velocity_mutex);
289  if (!bDone) {
290  pthread_cond_wait(&induced_velocity_cond,
291  &induced_velocity_mutex);
292  }
293  pthread_mutex_unlock(&induced_velocity_mutex);
294 }
295 
296 void
297 InducedVelocity::Done(void) const
298 {
299  pthread_mutex_lock(&induced_velocity_mutex);
300  ASSERT(!bDone);
301  bDone = true;
302  pthread_cond_broadcast(&induced_velocity_cond);
303  pthread_mutex_unlock(&induced_velocity_mutex);
304 }
305 #endif // USE_MULTITHREAD && MBDYN_X_MT_ASSRES
306 
307 /* InducedVelocity - end */
308 
309 /* InducedVelocityElem - begin */
310 
312  const StructNode *pCraft,
313  ResForceSet **ppres, flag fOut)
314 : Elem(uL, fOut),
315 AerodynamicElem(uL, pDO, fOut),
316 InducedVelocity(uL, pCraft, ppres, fOut)
317 {
318  NO_OP;
319 }
320 
322 {
323  NO_OP;
324 }
325 
326 /* Tipo dell'elemento (usato per debug ecc.) */
329 {
330  return Elem::INDUCEDVELOCITY;
331 }
332 
333 /* Tipo dell'elemento (usato per debug ecc.) */
336 {
338 }
339 
340 /* InducedVelocity - end */
341 
ExternResForces Res
Definition: indvel.h:114
void PutForces(const Vec3 &f, const Vec3 &c)
Definition: resforces.cc:96
virtual void AfterConvergence(const VectorHandler &X, const VectorHandler &XP)
Definition: indvel.cc:170
long int flag
Definition: mbdyn.h:43
virtual Elem::Type GetElemType(void) const
Definition: indvel.cc:328
virtual void ResetForce(void)
Definition: indvel.cc:276
#define MBDYN_EXCEPT_ARGS
Definition: except.h:63
Definition: matvec3.h:98
ResForceSet ** ppRes
Definition: indvel.h:116
virtual ~InducedVelocity(void)
Definition: indvel.cc:91
void Reset(void)
Definition: resforces.cc:126
virtual doublereal dGetPrivData(unsigned int i) const
Definition: indvel.cc:150
virtual const Vec3 & Force(void) const
Definition: resforces.cc:103
#define SAFEDELETEARR(pnt)
Definition: mynewmem.h:713
virtual AerodynamicElem::Type GetAerodynamicElemType(void) const
Definition: indvel.cc:335
#define NO_OP
Definition: myassert.h:74
virtual const Vec3 & Moment(void) const
Definition: resforces.cc:109
virtual unsigned int iGetNumPrivData(void) const
Definition: indvel.cc:112
virtual void AddSectionalForce(Elem::Type type, const Elem *pEl, unsigned uPnt, const Vec3 &F, const Vec3 &M, doublereal dW, const Vec3 &X, const Mat3x3 &R, const Vec3 &V, const Vec3 &W)
Definition: indvel.cc:265
virtual ~InducedVelocityElem(void)
Definition: indvel.cc:321
virtual bool bSectionalForces(void) const
Definition: indvel.cc:106
virtual void AddForce(const Elem *pEl, const StructNode *pNode, const Vec3 &F, const Vec3 &M, const Vec3 &X)
Definition: indvel.cc:252
InducedVelocityElem(unsigned int uL, const DofOwner *pDO, const StructNode *pCraft, ResForceSet **ppres, flag fOut)
Definition: indvel.cc:311
InducedVelocity(unsigned int uL, const StructNode *pCraft, ResForceSet **ppres, flag fOut)
Definition: indvel.cc:57
void SetNullMatrix(void)
Definition: submat.h:1159
Definition: mbdyn.h:76
void PutTo(doublereal *pd) const
Definition: matvec3.h:339
#define DEBUGCOUT(msg)
Definition: myassert.h:232
#define ASSERT(expression)
Definition: colamd.c:977
virtual const Vec3 & GetXCurr(void) const
Definition: strnode.h:310
Definition: elem.h:75
Type
Definition: elem.h:91
const doublereal * pGetVec(void) const
Definition: matvec3.h:192
void PutForce(const Vec3 &f)
Definition: resforces.cc:84
#define SAFENEWARR(pnt, item, sz)
Definition: mynewmem.h:701
virtual unsigned int iGetPrivDataIdx(const char *s) const
Definition: indvel.cc:117
double doublereal
Definition: colamd.c:52
unsigned int GetLabel(void) const
Definition: withlab.cc:62
virtual VariableSubMatrixHandler & AssJac(VariableSubMatrixHandler &WorkMat, doublereal dCoef, const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
Definition: indvel.cc:181
Mat3x3 R
const StructNode * pCraft
Definition: indvel.h:111