5
5
Date started: 01/21/99
6
6
Called by: FGAircraft
8
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
8
------------- Copyright (C) 1999 Jon S. Berndt (jon@jsbsim.org) -------------
10
10
This program is free software; you can redistribute it and/or modify it under
11
11
the terms of the GNU Lesser General Public License as published by the Free Software
52
56
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
54
58
FGTank::FGTank(FGFDMExec* exec, Element* el, int tank_number)
55
: TankNumber(tank_number)
59
: TankNumber(tank_number), Exec(exec)
61
string token, strFuelName;
59
63
Element* element_Grain;
61
Temperature = -9999.0;
66
InitialTemperature = Temperature = -9999.0;
62
67
Ixx = Iyy = Izz = 0.0;
63
Auxiliary = exec->GetAuxiliary();
64
Radius = Capacity = Contents = Standpipe = Length = InnerRadius = 0.0;
65
PropertyManager = exec->GetPropertyManager();
68
Radius = Contents = Standpipe = Length = InnerRadius = 0.0;
70
Priority = InitialPriority = 1;
71
PropertyManager = Exec->GetPropertyManager();
67
73
vXYZ_drain.InitMatrix();
92
98
InitialTemperature = Temperature = el->FindElementValueAsNumber("temperature");
93
99
if (el->FindElement("standpipe"))
94
100
InitialStandpipe = Standpipe = el->FindElementValueAsNumberConvertTo("standpipe", "LBS");
99
PctFull = 100.0*Contents/Capacity; // percent full; 0 to 100.0
101
if (el->FindElement("priority"))
102
InitialPriority = Priority = el->FindElementValueAsNumber("priority");
103
if (el->FindElement("density"))
104
Density = el->FindElementValueAsNumberConvertTo("density", "LBS/GAL");
105
if (el->FindElement("type"))
106
strFuelName = el->FindElementValue("type");
109
SetPriority( InitialPriority ); // this will also set the Selected flag
112
cerr << "Tank capacity must not be zero. Reset to 0.00001 lbs!" << endl;
116
PctFull = 100.0*Contents/Capacity; // percent full; 0 to 100.0
105
118
// Check whether this is a solid propellant "tank". Initialize it if true.
139
152
Density = (Contents*lbtoslug)/Volume; // slugs/in^3
143
char property_name[80];
144
snprintf(property_name, 80, "propulsion/tank[%d]/contents-lbs", TankNumber);
145
PropertyManager->Tie( property_name, (FGTank*)this, &FGTank::GetContents,
156
string property_name, base_property_name;
157
base_property_name = CreateIndexedPropertyName("propulsion/tank", TankNumber);
158
property_name = base_property_name + "/contents-lbs";
159
PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetContents,
146
160
&FGTank::SetContents );
161
property_name = base_property_name + "/priority";
162
PropertyManager->Tie( property_name.c_str(), (FGTank*)this, &FGTank::GetPriority,
163
&FGTank::SetPriority );
148
165
if (Temperature != -9999.0) InitialTemperature = Temperature = FahrenheitToCelsius(Temperature);
149
166
Area = 40.0 * pow(Capacity/1975, 0.666666667);
168
// A named fuel type will override a previous density value
169
if (!strFuelName.empty()) Density = ProcessFuelName(strFuelName);
163
183
void FGTank::ResetToIC(void)
165
Temperature = InitialTemperature;
166
Standpipe = InitialStandpipe;
167
Contents = InitialContents;
185
SetTemperature( InitialTemperature );
186
SetStandpipe ( InitialStandpipe );
187
SetContents ( InitialContents );
168
188
PctFull = 100.0*Contents/Capacity;
189
SetPriority( InitialPriority );
172
192
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
240
259
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
261
void FGTank::SetContentsGallons(double gallons)
263
SetContents(gallons * Density);
267
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
242
269
double FGTank::Calculate(double dt)
244
271
if (Temperature == -9999.0) return 0.0;
245
272
double HeatCapacity = 900.0; // Joules/lbm/C
246
273
double TempFlowFactor = 1.115; // Watts/sqft/C
247
double TAT = Auxiliary->GetTAT_C();
274
double TAT = Exec->GetAuxiliary()->GetTAT_C();
248
275
double Tdiff = TAT - Temperature;
249
276
double dTemp = 0.0; // Temp change due to one surface
250
277
if (fabs(Tdiff) > 0.1) {
263
290
double Mass = Contents*lbtoslug;
264
291
double RadSumSqr;
265
292
double Rad2 = Radius*Radius;
266
Volume = (Contents*lbtoslug)/Density; // in^3
295
Volume = (Contents*lbtoslug)/Density; // in^3
297
cerr << endl << " Solid propellant grain density is zero!" << endl << endl;
268
301
switch (grainType) {
269
302
case gtCYLINDRICAL:
277
310
Ixx = 0.5*Mass*Rad2/144.0;
278
311
Iyy = Mass*(3.0*Rad2 + Length*Length)/(144.0*12.0);
314
cerr << "Unknown grain type found." << endl;
285
322
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
324
double FGTank::ProcessFuelName(std::string const& name)
326
if (name == "AVGAS") return 6.02;
327
else if (name == "JET-A") return 6.74;
328
else if (name == "JET-A1") return 6.74;
329
else if (name == "JET-B") return 6.48;
330
else if (name == "JP-1") return 6.76;
331
else if (name == "JP-2") return 6.38;
332
else if (name == "JP-3") return 6.34;
333
else if (name == "JP-4") return 6.48;
334
else if (name == "JP-5") return 6.81;
335
else if (name == "JP-6") return 6.55;
336
else if (name == "JP-7") return 6.61;
337
else if (name == "JP-8") return 6.66;
338
else if (name == "JP-8+100") return 6.66;
339
//else if (name == "JP-9") return 6.74;
340
//else if (name == "JPTS") return 6.74;
341
else if (name == "RP-1") return 6.73;
342
else if (name == "T-1") return 6.88;
343
else if (name == "ETHANOL") return 6.58;
344
else if (name == "HYDRAZINE")return 8.61;
345
else if (name == "F-34") return 6.66;
346
else if (name == "F-35") return 6.74;
347
else if (name == "F-40") return 6.48;
348
else if (name == "F-44") return 6.81;
349
else if (name == "AVTAG") return 6.48;
350
else if (name == "AVCAT") return 6.81;
352
cerr << "Unknown fuel type specified: "<< name << endl;
359
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
286
360
// The bitmasked value choices are as follows:
287
361
// unset: In this case (the default) JSBSim would only print
288
362
// out the normally expected messages, essentially echoing
312
386
cout << " Tank location (X, Y, Z): " << vXYZ(eX) << ", " << vXYZ(eY) << ", " << vXYZ(eZ) << endl;
313
387
cout << " Effective radius: " << Radius << " inches" << endl;
314
388
cout << " Initial temperature: " << Temperature << " Fahrenheit" << endl;
389
cout << " Priority: " << Priority << endl;
317
392
if (debug_lvl & 2 ) { // Instantiation/Destruction notification