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 "input_output/FGXMLElement.h"
44 #include "math/FGColumnVector3.h"
45 #include "models/propulsion/FGForce.h"
46 #include "math/FGFunction.h"
54 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
56 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
58 #define ID_GASCELL "$Id$"
60 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
62 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
68 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
70 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
72 /** Models a gas cell.
73 @author Anders Gidenstam
75 <h3>Configuration File Format:</h3>
78 <gas_cell type="{HYDROGEN | HELIUM | AIR}">
79 <location unit="{M | IN}">
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>
91 {heat transfer coefficients} [lbs ft / sec]
94 <location unit="{M | IN}">
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>
106 {heat transfer coefficients} [lb ft / (sec Rankine)]
109 {input air flow function} [ft^3 / sec]
116 Definition of the gas cell configuration file parameters:
118 One of HYDROGEN, HELIUM or AIR.
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.
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>.
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.
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.
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>.
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.)
173 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
176 class FGGasCell : public FGForce
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);
186 /** Runs the gas cell model; called by BuoyantForces
188 void Calculate(double dt);
190 /** Get the index of this gas cell
191 @return gas cell index. */
192 int GetIndex(void) const {return CellNum;}
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) const {return vXYZ;}
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) const {return vXYZ(idx);}
204 /** Get the current mass of the gas cell (including any ballonets)
205 @return gas mass in slug. */
206 double GetMass(void) const {return Mass;}
208 /** Get the moments of inertia of the gas cell (including any ballonets)
209 @return moments of inertia matrix relative the gas cell location
210 in slug ft<sup>2</sup>. */
211 const FGMatrix33& GetInertia(void) const {return gasCellJ;}
213 /** Get the moment due to mass of the gas cell (including any ballonets)
215 Note that the buoyancy of the gas cell is handled separately by the
216 FGForce part and not included here.
217 @return moment vector in lbs ft. */
218 const FGColumnVector3& GetMassMoment(void) const {return gasCellM;}
220 /** Get the current gas temperature inside the gas cell
221 @return gas temperature in Rankine. */
222 double GetTemperature(void) const {return Temperature;}
224 /** Get the current gas pressure inside the gas cell
225 @return gas pressure in lbs / ft<sup>2</sup>. */
226 double GetPressure(void) const {return Pressure;}
230 enum GasType {ttUNKNOWN, ttHYDROGEN, ttHELIUM, ttAIR};
235 // Structural constants
236 double MaxVolume; // [ft�]
237 double MaxOverpressure; // [lbs/ft�]
238 FGColumnVector3 vXYZ; // [in]
239 double Xradius, Yradius, Zradius; // [ft]
240 double Xwidth, Ywidth, Zwidth; // [ft]
241 double ValveCoefficient; // [ft^4 sec / slug]
242 typedef vector <FGFunction*> CoeffArray;
243 CoeffArray HeatTransferCoeff;
244 typedef vector <FGBallonet*> BallonetArray;
245 BallonetArray Ballonet;
247 double Pressure; // [lbs/ft�]
248 double Contents; // [mol]
249 double Volume; // [ft�]
250 double dVolumeIdeal; // [ft�]
251 double Temperature; // [Rankine]
252 double Buoyancy; // [lbs] Note: Gross lift.
253 // Does not include the weight of the gas itself.
254 double ValveOpen; // 0 <= ValveOpen <= 1 (or higher).
255 double Mass; // [slug]
256 FGMatrix33 gasCellJ; // [slug foot�]
257 FGColumnVector3 gasCellM; // [lbs ft]
259 FGAuxiliary* Auxiliary;
260 FGAtmosphere* Atmosphere;
261 FGPropertyManager* PropertyManager;
262 FGInertial* Inertial;
263 FGMassBalance* MassBalance;
264 void Debug(int from);
267 const static double R; // [lbs ft/(mol Rankine)]
268 const static double M_air; // [slug/mol]
269 const static double M_hydrogen; // [slug/mol]
270 const static double M_helium; // [slug/mol]
272 double M_gas() { // [slug/mol]
285 double Cv_gas() { // [??]
300 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
301 /** Models a ballonet inside a gas cell.
302 Models a ballonet inside a gas cell.
303 Not intended to be used outside FGGasCell.
304 See FGGasCell for the configuration file format.
305 @author Anders Gidenstam
307 class FGBallonet : public FGJSBBase
310 FGBallonet(FGFDMExec* exec, Element* el, int num, FGGasCell* parent);
313 /** Runs the ballonet model; called by FGGasCell
315 void Calculate(double dt);
318 /** Get the center of gravity location of the ballonet
319 @return CoG location in the structural frame. */
320 const FGColumnVector3& GetXYZ(void) const {return vXYZ;}
321 /** Get the center of gravity location of the ballonet
322 @return CoG location in the structural frame. */
323 double GetXYZ(int idx) const {return vXYZ(idx);}
325 /** Get the current mass of the ballonets
326 @return mass in slug. */
327 double GetMass(void) const {return Contents * M_air;}
329 /** Get the moments of inertia of the ballonet
330 @return moments of inertia matrix in slug ft<sup>2</sup>. */
331 const FGMatrix33& GetInertia(void) const {return ballonetJ;}
333 /** Get the current volume of the ballonet
334 @return volume in ft<sup>3</sup>. */
335 double GetVolume(void) const {return Volume;}
336 /** Get the current heat flow into the ballonet
337 @return heat flow in lbs ft / sec. */
338 double GetHeatFlow(void) const {return dU;} // [lbs ft / sec]
342 // Structural constants
343 double MaxVolume; // [ft�]
344 double MaxOverpressure; // [lbs/ft�]
345 FGColumnVector3 vXYZ; // [in]
346 double Xradius, Yradius, Zradius; // [ft]
347 double Xwidth, Ywidth, Zwidth; // [ft]
348 double ValveCoefficient; // [ft^4 sec / slug]
349 typedef vector <FGFunction*> CoeffArray;
350 CoeffArray HeatTransferCoeff; // [lbs ft / sec]
351 FGFunction* BlowerInput; // [ft^3 / sec]
354 double Pressure; // [lbs/ft�]
355 double Contents; // [mol]
356 double Volume; // [ft�]
357 double dVolumeIdeal; // [ft�]
358 double dU; // [lbs ft / sec]
359 double Temperature; // [Rankine]
360 double ValveOpen; // 0 <= ValveOpen <= 1 (or higher).
361 FGMatrix33 ballonetJ; // [slug foot�]
363 FGAuxiliary* Auxiliary;
364 FGAtmosphere* Atmosphere;
365 FGPropertyManager* PropertyManager;
366 FGInertial* Inertial;
367 void Debug(int from);
370 const static double R; // [lbs ft/(mol Rankine)]
371 const static double M_air; // [slug/mol]
372 const static double Cv_air; // [??]
375 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%