1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4 Author: Anders Gidenstam
5 Date started: 01/21/2006
7 ----- Copyright (C) 2006 - 2008 Anders Gidenstam (anders(at)gidenstam.org) --
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
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
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.
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.
26 FUNCTIONAL DESCRIPTION
27 --------------------------------------------------------------------------------
29 This class simulates a generic gas cell for static buoyancy.
31 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
38 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
42 #include "FGJSBBase.h"
43 #include "math/FGColumnVector3.h"
44 #include "models/propulsion/FGForce.h"
45 #include "math/FGFunction.h"
49 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
51 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
53 #define ID_GASCELL "$Id: FGGasCell.h,v 1.10 2009/10/24 22:59:30 jberndt Exp $"
55 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
57 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
64 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
68 /** Models a gas cell.
69 @author Anders Gidenstam
71 <h3>Configuration File Format:</h3>
74 <gas_cell type="{HYDROGEN | HELIUM | AIR}">
75 <location unit="{M | IN}">
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>
87 {heat transfer coefficients} [lbs ft / sec]
90 <location unit="{M | IN}">
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>
102 {heat transfer coefficients} [lb ft / (sec Rankine)]
105 {input air flow function} [ft^3 / sec]
112 Definition of the gas cell configuration file parameters:
114 One of HYDROGEN, HELIUM or AIR.
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.
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>.
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.
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.
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>.
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.)
169 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
172 class FGGasCell : public FGForce
176 @param exec Executive a pointer to the parent executive object
177 @param el Pointer to configuration file XML node
178 @param num Gas cell index number. */
179 FGGasCell(FGFDMExec* exec, Element* el, int num);
182 /** Runs the gas cell model; called by BuoyantForces
184 void Calculate(double dt);
186 /** Get the index of this gas cell
187 @return gas cell index. */
188 int GetIndex(void) const {return CellNum;}
190 /** Get the center of gravity location of the gas cell
191 (including any ballonets)
192 @return CoG location in the structural frame. */
193 const FGColumnVector3& GetXYZ(void) const {return vXYZ;}
195 /** Get the center of gravity location of the gas cell
196 (including any ballonets)
197 @return CoG location in the structural frame. */
198 double GetXYZ(int idx) const {return vXYZ(idx);}
200 /** Get the current mass of the gas cell (including any ballonets)
201 @return gas mass in slug. */
202 double GetMass(void) const {return Mass;}
204 /** Get the moments of inertia of the gas cell (including any ballonets)
205 @return moments of inertia matrix relative the gas cell location
206 in slug ft<sup>2</sup>. */
207 const FGMatrix33& GetInertia(void) const {return gasCellJ;}
209 /** Get the moment due to mass of the gas cell (including any ballonets)
211 Note that the buoyancy of the gas cell is handled separately by the
212 FGForce part and not included here.
213 @return moment vector in lbs ft. */
214 const FGColumnVector3& GetMassMoment(void) const {return gasCellM;}
216 /** Get the current gas temperature inside the gas cell
217 @return gas temperature in Rankine. */
218 double GetTemperature(void) const {return Temperature;}
220 /** Get the current gas pressure inside the gas cell
221 @return gas pressure in lbs / ft<sup>2</sup>. */
222 double GetPressure(void) const {return Pressure;}
226 enum GasType {ttUNKNOWN, ttHYDROGEN, ttHELIUM, ttAIR};
231 // Structural constants
232 double MaxVolume; // [ft�]
233 double MaxOverpressure; // [lbs/ft�]
234 FGColumnVector3 vXYZ; // [in]
235 double Xradius, Yradius, Zradius; // [ft]
236 double Xwidth, Ywidth, Zwidth; // [ft]
237 double ValveCoefficient; // [ft^4 sec / slug]
238 typedef vector <FGFunction*> CoeffArray;
239 CoeffArray HeatTransferCoeff;
240 typedef vector <FGBallonet*> BallonetArray;
241 BallonetArray Ballonet;
243 double Pressure; // [lbs/ft�]
244 double Contents; // [mol]
245 double Volume; // [ft�]
246 double dVolumeIdeal; // [ft�]
247 double Temperature; // [Rankine]
248 double Buoyancy; // [lbs] Note: Gross lift.
249 // Does not include the weight of the gas itself.
250 double ValveOpen; // 0 <= ValveOpen <= 1 (or higher).
251 double Mass; // [slug]
252 FGMatrix33 gasCellJ; // [slug foot�]
253 FGColumnVector3 gasCellM; // [lbs ft]
255 FGAuxiliary* Auxiliary;
256 FGAtmosphere* Atmosphere;
257 FGPropertyManager* PropertyManager;
258 FGInertial* Inertial;
259 FGMassBalance* MassBalance;
260 void Debug(int from);
263 const static double R; // [lbs ft/(mol Rankine)]
264 const static double M_air; // [slug/mol]
265 const static double M_hydrogen; // [slug/mol]
266 const static double M_helium; // [slug/mol]
268 double M_gas() { // [slug/mol]
281 double Cv_gas() { // [??]
296 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
297 /** Models a ballonet inside a gas cell.
298 Models a ballonet inside a gas cell.
299 Not intended to be used outside FGGasCell.
300 See FGGasCell for the configuration file format.
301 @author Anders Gidenstam
303 class FGBallonet : public FGJSBBase
306 FGBallonet(FGFDMExec* exec, Element* el, int num, FGGasCell* parent);
309 /** Runs the ballonet model; called by FGGasCell
311 void Calculate(double dt);
314 /** Get the center of gravity location of the ballonet
315 @return CoG location in the structural frame. */
316 const FGColumnVector3& GetXYZ(void) const {return vXYZ;}
317 /** Get the center of gravity location of the ballonet
318 @return CoG location in the structural frame. */
319 double GetXYZ(int idx) const {return vXYZ(idx);}
321 /** Get the current mass of the ballonets
322 @return mass in slug. */
323 double GetMass(void) const {return Contents * M_air;}
325 /** Get the moments of inertia of the ballonet
326 @return moments of inertia matrix in slug ft<sup>2</sup>. */
327 const FGMatrix33& GetInertia(void) const {return ballonetJ;}
329 /** Get the current volume of the ballonet
330 @return volume in ft<sup>3</sup>. */
331 double GetVolume(void) const {return Volume;}
332 /** Get the current heat flow into the ballonet
333 @return heat flow in lbs ft / sec. */
334 double GetHeatFlow(void) const {return dU;} // [lbs ft / sec]
338 // Structural constants
339 double MaxVolume; // [ft�]
340 double MaxOverpressure; // [lbs/ft�]
341 FGColumnVector3 vXYZ; // [in]
342 double Xradius, Yradius, Zradius; // [ft]
343 double Xwidth, Ywidth, Zwidth; // [ft]
344 double ValveCoefficient; // [ft^4 sec / slug]
345 typedef vector <FGFunction*> CoeffArray;
346 CoeffArray HeatTransferCoeff; // [lbs ft / sec]
347 FGFunction* BlowerInput; // [ft^3 / sec]
350 double Pressure; // [lbs/ft�]
351 double Contents; // [mol]
352 double Volume; // [ft�]
353 double dVolumeIdeal; // [ft�]
354 double dU; // [lbs ft / sec]
355 double Temperature; // [Rankine]
356 double ValveOpen; // 0 <= ValveOpen <= 1 (or higher).
357 FGMatrix33 ballonetJ; // [slug foot�]
359 FGAuxiliary* Auxiliary;
360 FGAtmosphere* Atmosphere;
361 FGPropertyManager* PropertyManager;
362 FGInertial* Inertial;
363 void Debug(int from);
366 const static double R; // [lbs ft/(mol Rankine)]
367 const static double M_air; // [slug/mol]
368 const static double Cv_air; // [??]
371 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%