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>
49 # include <simgear/compiler.h>
58 # if !defined(sgi) || defined(__GNUC__) || (_COMPILER_VERSION >= 740)
65 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
67 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
69 #define ID_GASCELL "$Id$"
71 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
79 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
81 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
83 /** Models a gas cell.
84 @author Anders Gidenstam
86 <h3>Configuration File Format:</h3>
89 <gas_cell type="{HYDROGEN | HELIUM | AIR}">
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} [lbs ft / sec]
105 <location unit="{M | IN}">
110 <x_width unit="{M | IN}"> {number} </x_width>
111 <y_radius unit="{M | IN}"> {number} </y_radius>
112 <z_radius unit="{M | IN}"> {number} </z_radius>
113 <max_overpressure unit="{PA | PSI}"> {number} </max_overpressure>
114 <valve_coefficient unit="{M4*SEC/KG | FT4*SEC/SLUG}"> {number} </valve_coefficient>
115 <fullness> {number} </fullness>
117 {heat transfer coefficients} [lb ft / (sec Rankine)]
120 {input air flow function} [ft^3 / sec]
127 Definition of the gas cell configuration file parameters:
129 One of HYDROGEN, HELIUM or AIR.
131 Location of cell center in the aircraft's structural frame.
132 Currently this is were the forces of the cell is applied.
133 - <b>{x|y|z}_radius</b> -
134 Radius along in the respective direction (both ends).
135 - <b>{x|y|z}_width</b> -
136 Width in the respective direction.
137 <b>NOTE:</b> A 'x', 'y', 'z'-radius/width combination must be specified.
139 Initial fullness of the cell, normally [0,1],
140 values >1 initialize the cell at pressure.
141 - <b>max_overpressure</b> -
142 Maximum cell overpressure (excess is automatically valved off).
143 - <b>valve_coefficient</b> -
144 Capacity of the manual valve. The valve is
145 considered to be located at the top of the cell.
146 The valve coefficient determine the flow out
147 of the cell according to:
148 <i>dVolume/dt = ValveCoefficient * DeltaPressure</i>.
150 Zero or more FGFunction:s describing the heat flow from
151 the atmosphere into the gas cell.
152 Unit: [lb ft / (sec Rankine)].
153 If there are no heat transfer functions at all the gas cell
154 temperature will equal that of the surrounding atmosphere.
155 A constant function returning 0 results in adiabatic behaviour.
157 Zero or more ballonets, i.e. air bags inside the gas cell.
158 Ballonets are used to maintain the volume of the gas cell
159 and keep its internal pressure higher than that of the
160 surrounding environment.
162 Location of ballonet center in the aircraft's structural frame.
163 - <b>{x|y|z}_radius</b> -
164 Radius along in the respective direction (both ends).
165 - <b>{x|y|z}_width</b> -
166 Width in the respective direction.
167 - <b>max_overpressure</b> -
168 Maximum ballonet overpressure (excess is automatically valved off).
169 - <b>valve_coefficient</b> -
170 Capacity of the exit valve between the ballonet
171 and the atmosphere. The valve coefficient
172 determine the flow out of the cell according to:
173 <i>dVolume/dt = ValveCoefficient * DeltaPressure</i>.
175 Zero or more FGFunction:s describing the heat flow from
176 the enclosing gas cell into the ballonet.
177 Unit: [lb ft / (sec Rankine)]
178 - <b>blower_input</b> -
179 One FGFunction describing the air flow into the
180 ballonet. Unit: [ft<sup>3</sup> / sec] (at the temperature and
181 pressure of the ballonet.)
184 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
187 class FGGasCell : public FGForce
191 @param exec Executive a pointer to the parent executive object
192 @param el Pointer to configuration file XML node
193 @param num Gas cell index number. */
194 FGGasCell(FGFDMExec* exec, Element* el, int num);
197 /** Runs the gas cell model; called by BuoyantForces
199 void Calculate(double dt);
201 /** Get the index of this gas cell
202 @return gas cell index. */
203 int GetIndex(void) {return CellNum;}
205 /** Get the center of gravity location of the gas cell
206 (including any ballonets)
207 @return CoG location in the structural frame. */
208 const FGColumnVector3& GetXYZ(void) {return vXYZ;}
210 /** Get the center of gravity location of the gas cell
211 (including any ballonets)
212 @return CoG location in the structural frame. */
213 double GetXYZ(int idx) {return vXYZ(idx);}
215 /** Get the current mass of the gas cell (including any ballonets)
216 @return gas mass in slug. */
217 double GetMass(void) {return Mass;}
219 /** Get the moments of inertia of the gas cell (including any ballonets)
220 @return moments of inertia matrix in slug ft<sup>2</sup>. */
221 FGMatrix33& GetInertia(void) {return gasCellJ;}
223 /** Get the moment due to mass of the gas cell (including any ballonets)
225 Note that the buoyancy of the gas cell is handled separately by the
226 FGForce part and not included here.
227 @return moment vector in lbs ft. */
228 FGColumnVector3& GetMassMoment(void) {return gasCellM;}
230 /** Get the current gas temperature inside the gas cell
231 @return gas temperature in Rankine. */
232 double GetTemperature(void) {return Temperature;}
234 /** Get the current gas pressure inside the gas cell
235 @return gas pressure in lbs / ft<sup>2</sup>. */
236 double GetPressure(void) {return Pressure;}
240 enum GasType {ttUNKNOWN, ttHYDROGEN, ttHELIUM, ttAIR};
245 // Structural constants
246 double MaxVolume; // [ft�]
247 double MaxOverpressure; // [lbs/ft�]
248 FGColumnVector3 vXYZ; // [in]
249 double Xradius, Yradius, Zradius; // [ft]
250 double Xwidth, Ywidth, Zwidth; // [ft]
251 double ValveCoefficient; // [ft^4 sec / slug]
252 typedef vector <FGFunction*> CoeffArray;
253 CoeffArray HeatTransferCoeff;
254 typedef vector <FGBallonet*> BallonetArray;
255 BallonetArray Ballonet;
257 double Pressure; // [lbs/ft�]
258 double Contents; // [mol]
259 double Volume; // [ft�]
260 double dVolumeIdeal; // [ft�]
261 double Temperature; // [Rankine]
262 double Buoyancy; // [lbs] Note: Gross lift.
263 // Does not include the weight of the gas itself.
264 double ValveOpen; // 0 <= ValveOpen <= 1 (or higher).
265 double Mass; // [slug]
266 FGMatrix33 gasCellJ; // [slug foot�]
267 FGColumnVector3 gasCellM; // [lbs ft]
269 FGAuxiliary* Auxiliary;
270 FGAtmosphere* Atmosphere;
271 FGPropertyManager* PropertyManager;
272 FGInertial* Inertial;
273 FGMassBalance* MassBalance;
274 void Debug(int from);
277 const static double R; // [lbs ft/(mol Rankine)]
278 const static double M_air; // [slug/mol]
279 const static double M_hydrogen; // [slug/mol]
280 const static double M_helium; // [slug/mol]
282 double M_gas() { // [slug/mol]
295 double Cv_gas() { // [??]
310 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
311 /** Models a ballonet inside a gas cell.
312 Models a ballonet inside a gas cell.
313 Not intended to be used outside FGGasCell.
314 See FGGasCell for the configuration file format.
315 @author Anders Gidenstam
317 class FGBallonet : public FGJSBBase
320 FGBallonet(FGFDMExec* exec, Element* el, int num, FGGasCell* parent);
323 /** Runs the ballonet model; called by FGGasCell
325 void Calculate(double dt);
328 /** Get the center of gravity location of the ballonet
329 @return CoG location in the structural frame. */
330 const FGColumnVector3& GetXYZ(void) {return vXYZ;}
331 /** Get the center of gravity location of the ballonet
332 @return CoG location in the structural frame. */
333 double GetXYZ(int idx) {return vXYZ(idx);}
335 /** Get the current mass of the ballonets
336 @return mass in slug. */
337 double GetMass(void) {return Contents * M_air;}
339 /** Get the moments of inertia of the ballonet
340 @return moments of inertia matrix in slug ft<sup>2</sup>. */
341 FGMatrix33& GetInertia(void) {return ballonetJ;}
343 /** Get the current volume of the ballonet
344 @return volume in ft<sup>3</sup>. */
345 double GetVolume(void) {return Volume;}
346 /** Get the current heat flow into the ballonet
347 @return heat flow in lbs ft / sec. */
348 double GetHeatFlow(void) {return dU;} // [lbs ft / sec]
352 // Structural constants
353 double MaxVolume; // [ft�]
354 double MaxOverpressure; // [lbs/ft�]
355 FGColumnVector3 vXYZ; // [in]
356 double Xradius, Yradius, Zradius; // [ft]
357 double Xwidth, Ywidth, Zwidth; // [ft]
358 double ValveCoefficient; // [ft^4 sec / slug]
359 typedef vector <FGFunction*> CoeffArray;
360 CoeffArray HeatTransferCoeff; // [lbs ft / sec]
361 FGFunction* BlowerInput; // [ft^3 / sec]
364 double Pressure; // [lbs/ft�]
365 double Contents; // [mol]
366 double Volume; // [ft�]
367 double dVolumeIdeal; // [ft�]
368 double dU; // [lbs ft / sec]
369 double Temperature; // [Rankine]
370 double ValveOpen; // 0 <= ValveOpen <= 1 (or higher).
371 FGMatrix33 ballonetJ; // [slug foot�]
373 FGAuxiliary* Auxiliary;
374 FGAtmosphere* Atmosphere;
375 FGPropertyManager* PropertyManager;
376 FGInertial* Inertial;
377 void Debug(int from);
380 const static double R; // [lbs ft/(mol Rankine)]
381 const static double M_air; // [slug/mol]
382 const static double Cv_air; // [??]
385 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%