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