1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4 Author: Anders Gidenstam
5 Date started: 01/21/2006
7 ----- Copyright (C) 2006 - 2011 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.12 2011/08/06 13:47:59 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
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);
189 /** Runs the gas cell model; called by BuoyantForces
191 void Calculate(double dt);
193 /** Get the index of this gas cell
194 @return gas cell index. */
195 int GetIndex(void) const {return CellNum;}
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;}
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);}
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;}
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;}
216 /** Get the moment due to mass of the gas cell (including any ballonets)
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;}
223 /** Get the current gas temperature inside the gas cell
224 @return gas temperature in Rankine. */
225 double GetTemperature(void) const {return Temperature;}
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;}
231 const struct Inputs& in;
235 enum GasType {ttUNKNOWN, ttHYDROGEN, ttHELIUM, ttAIR};
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;
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]
264 FGPropertyManager* PropertyManager;
265 FGMassBalance* MassBalance;
266 void Debug(int from);
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]
274 double M_gas() { // [slug/mol]
287 double Cv_gas() { // [??]
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
308 class FGBallonet : public FGJSBBase
311 FGBallonet(FGFDMExec* exec, Element* el, int num, FGGasCell* parent, const struct FGGasCell::Inputs& input);
314 /** Runs the ballonet model; called by FGGasCell
316 void Calculate(double dt);
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);}
326 /** Get the current mass of the ballonets
327 @return mass in slug. */
328 double GetMass(void) const {return Contents * M_air;}
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;}
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]
342 const struct FGGasCell::Inputs& in;
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]
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]
367 FGPropertyManager* PropertyManager;
368 FGMassBalance* MassBalance;
369 void Debug(int from);
372 const static double R; // [lbs ft/(mol Rankine)]
373 const static double M_air; // [slug/mol]
374 const static double Cv_air; // [??]
377 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%