]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/models/FGGasCell.h
New version of JSBSim, a big rewrite.
[flightgear.git] / src / FDM / JSBSim / models / FGGasCell.h
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Header:       FGGasCell.h
4  Author:       Anders Gidenstam
5  Date started: 01/21/2006
6
7  ----- Copyright (C) 2006 - 2011  Anders Gidenstam (anders(at)gidenstam.org) --
8
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU Lesser General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
17  details.
18
19  You should have received a copy of the GNU Lesser General Public License along with
20  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21  Place - Suite 330, Boston, MA  02111-1307, USA.
22
23  Further information about the GNU Lesser General Public License can also be found on
24  the world wide web at http://www.gnu.org.
25
26 FUNCTIONAL DESCRIPTION
27 --------------------------------------------------------------------------------
28
29 This class simulates a generic gas cell for static buoyancy.
30
31 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32 SENTRY
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
34
35 #ifndef FGGASCELL_H
36 #define FGGASCELL_H
37
38 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39 INCLUDES
40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
41
42 #include "FGJSBBase.h"
43 #include "math/FGColumnVector3.h"
44 #include "models/propulsion/FGForce.h"
45 #include "math/FGFunction.h"
46
47 #include <string>
48
49 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
50 DEFINITIONS
51 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
52
53 #define ID_GASCELL "$Id: FGGasCell.h,v 1.12 2011/08/06 13:47:59 jberndt Exp $"
54
55 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
56 FORWARD DECLARATIONS
57 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
58
59 namespace JSBSim {
60
61 class FGBallonet;
62 class Element;
63
64 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65 CLASS DOCUMENTATION
66 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
67
68 /** Models a gas cell.
69     @author Anders Gidenstam
70
71 <h3>Configuration File Format:</h3>
72 @code
73 <buoyant_forces>
74   <gas_cell type="{HYDROGEN | HELIUM | AIR}">
75     <location unit="{M | IN}">
76       <x> {number} </x>
77       <y> {number} </y>
78       <z> {number} </z>
79     </location>
80     <x_width unit="{M | IN}"> {number} </x_width>
81     <y_radius unit="{M | IN}"> {number} </y_radius>
82     <z_radius unit="{M | IN}"> {number} </z_radius>
83     <max_overpressure unit="{PA | PSI}"> {number} </max_overpressure>
84     <valve_coefficient unit="{M4*SEC/KG | FT4*SEC/SLUG}"> {number} </valve_coefficient>
85     <fullness> {number} </fullness>  
86     <heat>
87       {heat transfer coefficients} [lbs ft / sec]
88     </heat>
89     <ballonet>
90       <location unit="{M | IN}">
91         <x> {number} </x>
92         <y> {number} </y>
93         <z> {number} </z>
94       </location>
95       <x_width unit="{M | IN}"> {number} </x_width>
96       <y_radius unit="{M | IN}"> {number} </y_radius>
97       <z_radius unit="{M | IN}"> {number} </z_radius>
98       <max_overpressure unit="{PA | PSI}"> {number} </max_overpressure>
99       <valve_coefficient unit="{M4*SEC/KG | FT4*SEC/SLUG}"> {number} </valve_coefficient>
100       <fullness> {number} </fullness>  
101       <heat>
102        {heat transfer coefficients} [lb ft / (sec Rankine)]
103       </heat>
104       <blower_input>
105        {input air flow function} [ft^3 / sec]
106       </blower_input>
107     </ballonet>
108   </gas_cell>
109 </buoyant_forces>
110 @endcode
111
112 Definition of the gas cell configuration file parameters:
113 - <b>type</b> -
114     One of HYDROGEN, HELIUM or AIR.
115 - <b>location</b> -
116     Location of cell center in the aircraft's structural frame.
117     Currently this is were the forces of the cell is applied.
118 - <b>{x|y|z}_radius</b> -
119     Radius along in the respective direction (both ends).
120 - <b>{x|y|z}_width</b> -
121     Width in the respective direction.
122     <b>NOTE:</b> A 'x', 'y', 'z'-radius/width combination must be specified.
123 - <b>fullness</b> -
124     Initial fullness of the cell, normally [0,1],
125     values >1 initialize the cell at pressure.
126 - <b>max_overpressure</b> -
127     Maximum cell overpressure (excess is automatically valved off).
128 - <b>valve_coefficient</b> -
129     Capacity of the manual valve. The valve is
130     considered to be located at the top of the cell.
131     The valve coefficient determine the flow out
132     of the cell according to:
133     <i>dVolume/dt = ValveCoefficient * DeltaPressure</i>.
134 - <b>heat</b> -
135     Zero or more FGFunction:s describing the heat flow from
136     the atmosphere into the gas cell.
137     Unit: [lb ft / (sec Rankine)].
138     If there are no heat transfer functions at all the gas cell
139     temperature will equal that of the surrounding atmosphere.
140     A constant function returning 0 results in adiabatic behaviour.
141 - <b>ballonet</b> -
142     Zero or more ballonets, i.e. air bags inside the gas cell.
143     Ballonets are used to maintain the volume of the gas cell
144     and keep its internal pressure higher than that of the
145     surrounding environment.
146   - <b>location</b> -
147       Location of ballonet center in the aircraft's structural frame.
148   - <b>{x|y|z}_radius</b> -
149       Radius along in the respective direction (both ends).
150   - <b>{x|y|z}_width</b> -
151       Width in the respective direction.
152   - <b>max_overpressure</b> -
153       Maximum ballonet overpressure (excess is automatically valved off).
154   - <b>valve_coefficient</b> -
155       Capacity of the exit valve between the ballonet
156       and the atmosphere. The valve coefficient
157       determine the flow out of the cell according to:
158       <i>dVolume/dt = ValveCoefficient * DeltaPressure</i>.
159   - <b>heat</b> -
160       Zero or more FGFunction:s describing the heat flow from
161       the enclosing gas cell into the ballonet.
162       Unit: [lb ft / (sec Rankine)]
163   - <b>blower_input</b> -
164       One FGFunction describing the air flow into the
165       ballonet. Unit: [ft<sup>3</sup> / sec] (at the temperature and
166       pressure of the ballonet.)
167   */
168
169 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
170 CLASS DECLARATION
171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
172 class FGGasCell : public FGForce
173 {
174 public:
175   struct Inputs {
176     double Pressure;
177     double Temperature;
178     double Density;
179     double gravity;
180   };
181
182   /** Constructor
183       @param exec Executive a pointer to the parent executive object
184       @param el   Pointer to configuration file XML node
185       @param num  Gas cell index number. */
186   FGGasCell(FGFDMExec* exec, Element* el, int num, const struct Inputs& input);
187   ~FGGasCell();
188
189   /** Runs the gas cell model; called by BuoyantForces
190    */
191   void Calculate(double dt);
192
193   /** Get the index of this gas cell
194       @return gas cell index. */
195   int GetIndex(void) const {return CellNum;}
196
197   /** Get the center of gravity location of the gas cell
198       (including any ballonets)
199       @return CoG location in the structural frame in inches. */
200   const FGColumnVector3& GetXYZ(void) const {return vXYZ;}
201
202   /** Get the center of gravity location of the gas cell
203       (including any ballonets)
204       @return CoG location in the structural frame in inches. */
205   double GetXYZ(int idx) const {return vXYZ(idx);}
206
207   /** Get the current mass of the gas cell (including any ballonets)
208       @return gas mass in slug. */
209   double GetMass(void) const {return Mass;}
210
211   /** Get the moments of inertia of the gas cell (including any ballonets)
212       @return moments of inertia matrix in the body frame
213       in slug ft<sup>2</sup>. */
214   const FGMatrix33& GetInertia(void) const {return gasCellJ;}
215
216   /** Get the moment due to mass of the gas cell (including any ballonets)
217
218       Note that the buoyancy of the gas cell is handled separately by the
219       FGForce part and not included here.
220       @return moment vector in the structural frame in lbs in. */
221   const FGColumnVector3& GetMassMoment(void) const {return gasCellM;}
222
223   /** Get the current gas temperature inside the gas cell
224       @return gas temperature in Rankine. */
225   double GetTemperature(void) const {return Temperature;}
226
227   /** Get the current gas pressure inside the gas cell
228       @return gas pressure in lbs / ft<sup>2</sup>. */
229   double GetPressure(void) const {return Pressure;}
230
231   const struct Inputs& in;
232
233 private:
234
235   enum GasType {ttUNKNOWN, ttHYDROGEN, ttHELIUM, ttAIR};
236
237   GasType Type;
238   std::string type;
239   int CellNum;
240   // Structural constants
241   double MaxVolume;                 // [ft^2]
242   double MaxOverpressure;           // [lbs/ft^2]
243   FGColumnVector3 vXYZ;             // [in]
244   double Xradius, Yradius, Zradius; // [ft]
245   double Xwidth, Ywidth, Zwidth;    // [ft]
246   double ValveCoefficient;          // [ft^4 sec / slug]
247   typedef vector <FGFunction*> CoeffArray;
248   CoeffArray HeatTransferCoeff;
249   typedef vector <FGBallonet*> BallonetArray;
250   BallonetArray Ballonet;
251   // Variables
252   double Pressure;          // [lbs/ft^2]
253   double Contents;          // [mol]
254   double Volume;            // [ft^2]
255   double dVolumeIdeal;      // [ft^2]
256   double Temperature;       // [Rankine]
257   double Buoyancy;          // [lbs] Note: Gross lift.
258                             // Does not include the weight of the gas itself.
259   double ValveOpen;         // 0 <= ValveOpen <= 1 (or higher).
260   double Mass;              // [slug]
261   FGMatrix33 gasCellJ;      // [slug foot^2]
262   FGColumnVector3 gasCellM; // [lbs in]
263
264   FGPropertyManager* PropertyManager;
265   FGMassBalance* MassBalance;
266   void Debug(int from);
267
268   /* Constants. */
269   const static double R;          // [lbs ft/(mol Rankine)]
270   const static double M_air;      // [slug/mol]
271   const static double M_hydrogen; // [slug/mol]
272   const static double M_helium;   // [slug/mol]
273
274   double M_gas() {                // [slug/mol]
275     switch (Type) {
276     case ttHYDROGEN:
277       return M_hydrogen;
278     case ttHELIUM:
279       return M_helium;
280     case ttAIR:
281       return M_air;
282     default:
283       return M_air;
284     }
285   }
286
287   double Cv_gas() {               // [??]
288     switch (Type) {
289     case ttHYDROGEN:
290       return 5.0/2.0;
291     case ttHELIUM:
292       return 3.0/2.0;
293     case ttAIR:
294       return 5.0/2.0;
295     default:
296       return 5.0/2.0;
297     }
298   }
299
300 };
301
302 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
303 /** Models a ballonet inside a gas cell.
304     Not intended to be used outside FGGasCell.
305     See FGGasCell for the configuration file format.
306     @author Anders Gidenstam
307 */
308 class FGBallonet : public FGJSBBase
309 {
310 public:
311   FGBallonet(FGFDMExec* exec, Element* el, int num, FGGasCell* parent, const struct FGGasCell::Inputs& input);
312   ~FGBallonet();
313
314   /** Runs the ballonet model; called by FGGasCell
315    */
316   void Calculate(double dt);
317
318
319   /** Get the center of gravity location of the ballonet
320       @return CoG location in the structural frame in inches. */
321   const FGColumnVector3& GetXYZ(void) const {return vXYZ;}
322   /** Get the center of gravity location of the ballonet
323       @return CoG location in the structural frame in inches. */
324   double GetXYZ(int idx) const {return vXYZ(idx);}
325
326   /** Get the current mass of the ballonets
327       @return mass in slug. */
328   double GetMass(void) const {return Contents * M_air;}
329
330   /** Get the moments of inertia of the ballonet
331       @return moments of inertia matrix in the body frame in
332       slug ft<sup>2</sup>. */
333   const FGMatrix33& GetInertia(void) const {return ballonetJ;}
334
335   /** Get the current volume of the ballonet
336       @return volume in ft<sup>3</sup>. */
337   double GetVolume(void) const {return Volume;}
338   /** Get the current heat flow into the ballonet
339       @return heat flow in lbs ft / sec. */
340   double GetHeatFlow(void) const {return dU;}       // [lbs ft / sec]
341
342   const struct FGGasCell::Inputs& in;
343
344 private:
345   int CellNum;
346   // Structural constants
347   double MaxVolume;                 // [ft^2]
348   double MaxOverpressure;           // [lbs/ft^2]
349   FGColumnVector3 vXYZ;             // [in]
350   double Xradius, Yradius, Zradius; // [ft]
351   double Xwidth, Ywidth, Zwidth;    // [ft]
352   double ValveCoefficient;          // [ft^4 sec / slug]
353   typedef vector <FGFunction*> CoeffArray;
354   CoeffArray HeatTransferCoeff;     // [lbs ft / sec]
355   FGFunction* BlowerInput;          // [ft^3 / sec]
356   FGGasCell* Parent;
357   // Variables
358   double Pressure;         // [lbs/ft^2]
359   double Contents;         // [mol]
360   double Volume;           // [ft^2]
361   double dVolumeIdeal;     // [ft^2]
362   double dU;               // [lbs ft / sec]
363   double Temperature;      // [Rankine]
364   double ValveOpen;        // 0 <= ValveOpen <= 1 (or higher).
365   FGMatrix33 ballonetJ;     // [slug foot^2]
366
367   FGPropertyManager* PropertyManager;
368   FGMassBalance* MassBalance;
369   void Debug(int from);
370
371   /* Constants. */
372   const static double R;          // [lbs ft/(mol Rankine)]
373   const static double M_air;      // [slug/mol]
374   const static double Cv_air;     // [??]
375 };
376 }
377 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
378 #endif