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