]> git.mxchange.org Git - flightgear.git/blob - src/WeatherCM/FGPhysicalProperties.h
3d235f291313d4a3df4e702cf577aa4d91e98daa
[flightgear.git] / src / WeatherCM / FGPhysicalProperties.h
1 /*****************************************************************************
2
3  Header:       FGPhysicalProperties.h   
4  Author:       Christian Mayer
5  Date started: 28.05.99
6
7  -------- Copyright (C) 1999 Christian Mayer (fgfs@christianmayer.de) --------
8
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13
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 General Public License for more
17  details.
18
19  You should have received a copy of the GNU 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.
22
23  Further information about the GNU General Public License can also be found on
24  the world wide web at http://www.gnu.org.
25
26 FUNCTIONAL DESCRIPTION
27 ------------------------------------------------------------------------------
28 Define the simulated physical properties of the weather
29
30 HISTORY
31 ------------------------------------------------------------------------------
32 28.05.1999 Christian Mayer      Created
33 16.06.1999 Durk Talsma          Portability for Linux
34 20.06.1999 Christian Mayer      Changed struct to class 
35 20.06.1999 Christian Mayer      added lots of consts
36 30.06.1999 Christian Mayer      STL portability
37 11.10.1999 Christian Mayer      changed set<> to map<> on Bernie Bright's 
38                                 suggestion
39 19.10.1999 Christian Mayer      change to use PLIB's sg instead of Point[2/3]D
40                                 and lots of wee code cleaning
41 *****************************************************************************/
42
43 /****************************************************************************/
44 /* SENTRY                                                                   */
45 /****************************************************************************/
46 #ifndef FGPhysicalProperties_H
47 #define FGPhysicalProperties_H
48
49 /****************************************************************************/
50 /* INCLUDES                                                                 */
51 /****************************************************************************/
52 #include <Include/compiler.h>
53
54 #include <iostream>
55 #include <vector>
56 #include <map>
57
58 #include "sg.h"
59
60 #include "FGWeatherDefs.h"
61
62 #include "FGAirPressureItem.h"
63 #include "FGWindItem.h"
64 #include "FGTurbulenceItem.h"
65
66 #include "FGCloudItem.h"
67 #include "FGSnowRain.h"
68
69 FG_USING_STD(vector);
70 FG_USING_STD(map);
71 FG_USING_NAMESPACE(std);
72
73 /****************************************************************************/
74 /* FOREWARD DEFINITIONS                                                     */
75 /****************************************************************************/
76 class FGPhysicalProperties2D;
77 ostream& operator<< ( ostream& out, const FGPhysicalProperties2D& p );
78
79 class FGPhysicalProperties
80 {
81 public:
82     typedef WeatherPrecision Altitude;  
83
84     map<Altitude,FGWindItem>       Wind;            //all Wind vectors
85     map<Altitude,FGTurbulenceItem> Turbulence;      //all Turbulence vectors
86     map<Altitude,WeatherPrecision> Temperature;     //in deg. Kelvin (I *only* accept SI!)
87     FGAirPressureItem              AirPressure;     //in Pascal (I *only* accept SI!)
88     map<Altitude,WeatherPrecision> VaporPressure;   //in Pascal (I *only* accept SI!)
89
90     map<Altitude,FGCloudItem>      Clouds;          //amount of covering and type
91
92     WeatherPrecision               SnowRainIntensity;     //this also stands for hail, snow,...
93     SnowRainType                   snowRainType;            
94     WeatherPrecision               LightningProbability;
95
96     FGPhysicalProperties();   //consructor to fill it with FG standart weather
97
98     //return values at specified altitudes
99     void             WindAt         (sgVec3 ret, const WeatherPrecision a) const;
100     void             TurbulenceAt   (sgVec3 ret, const WeatherPrecision a) const;
101     WeatherPrecision TemperatureAt  (const WeatherPrecision a) const;
102     WeatherPrecision AirPressureAt  (const WeatherPrecision a) const;
103     WeatherPrecision VaporPressureAt(const WeatherPrecision a) const;
104
105     //for easier access to the cloud stuff:
106     unsigned int getNumberOfCloudLayers(void) const;
107     FGCloudItem  getCloudLayer(unsigned int nr) const;
108     
109     FGPhysicalProperties& operator =  ( const FGPhysicalProperties& p ); 
110     FGPhysicalProperties& operator *= ( const WeatherPrecision      d ); 
111     FGPhysicalProperties& operator += ( const FGPhysicalProperties& p ); 
112     FGPhysicalProperties& operator -= ( const FGPhysicalProperties& p ); 
113 };
114
115 class FGPhysicalProperties2D : public FGPhysicalProperties
116 {
117 public:
118     sgVec2 p;       //position of the property (lat/lon)
119     friend ostream& operator<< ( ostream& out, const FGPhysicalProperties2D& p );
120
121     FGPhysicalProperties2D() {}
122
123     FGPhysicalProperties2D(const FGPhysicalProperties& prop, const sgVec2& pos) 
124     {
125         Wind = prop.Wind; 
126         Turbulence = prop.Turbulence;
127         Temperature = prop.Temperature;
128         AirPressure = prop.AirPressure; 
129         VaporPressure = prop.VaporPressure; 
130         sgCopyVec2(p, pos);
131     }
132 };
133
134 typedef vector<FGPhysicalProperties>                 FGPhysicalPropertiesVector;
135 typedef FGPhysicalPropertiesVector::iterator         FGPhysicalPropertiesVectorIt;
136 typedef FGPhysicalPropertiesVector::const_iterator   FGPhysicalPropertiesVectorConstIt;
137
138 typedef vector<FGPhysicalProperties2D>               FGPhysicalProperties2DVector;
139 typedef FGPhysicalProperties2DVector::iterator       FGPhysicalProperties2DVectorIt;
140 typedef FGPhysicalProperties2DVector::const_iterator FGPhysicalProperties2DVectorConstIt;
141
142 inline ostream& operator<< ( ostream& out, const FGPhysicalProperties2D& p )
143 {
144     typedef map<FGPhysicalProperties::Altitude, FGWindItem      >::const_iterator wind_iterator;
145     typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator turbulence_iterator;
146     typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
147
148     out << "Position: (" << p.p[0] << ", " << p.p[1] << ", " << p.p[2] << ")\n";
149     
150     out << "Stored Wind: ";
151     for (wind_iterator       WindIt = p.Wind.begin(); 
152                              WindIt != p.Wind.end(); 
153                              WindIt++)
154         out << "(" << WindIt->first << ") at (" << WindIt->second.x() << ", " << WindIt->second.y() << ", " << WindIt->second.z() << ") m; ";
155     out << "\n";
156
157     out << "Stored Turbulence: ";
158     for (turbulence_iterator TurbulenceIt = p.Turbulence.begin(); 
159                              TurbulenceIt != p.Turbulence.end(); 
160                              TurbulenceIt++)
161         out << "(" << TurbulenceIt->first << ") at (" << TurbulenceIt->second.x() << ", " << TurbulenceIt->second.y() << ", " << TurbulenceIt->second.z() << ") m; ";
162     out << "\n";
163
164     out << "Stored Temperature: ";
165     for (scalar_iterator     TemperatureIt = p.Temperature.begin(); 
166                              TemperatureIt != p.Temperature.end(); 
167                              TemperatureIt++)
168         out << TemperatureIt->first << " at " << TemperatureIt->second << "m; ";
169     out << "\n";
170
171     out << "Stored AirPressure: ";
172     out << p.AirPressure.getValue(0) << " at " << 0.0 << "m; ";
173     out << "\n";
174
175     out << "Stored VaporPressure: ";
176     for (scalar_iterator     VaporPressureIt = p.VaporPressure.begin(); 
177                              VaporPressureIt != p.VaporPressure.end(); 
178                              VaporPressureIt++)
179         out << VaporPressureIt->first << " at " << VaporPressureIt->second << "m; ";
180     out << "\n";
181
182     return out << "\n";
183 }
184
185
186 inline FGPhysicalProperties& FGPhysicalProperties::operator = ( const FGPhysicalProperties& p )
187 {
188     Wind          = p.Wind; 
189     Turbulence    = p.Turbulence; 
190     Temperature   = p.Temperature;
191     AirPressure   = p.AirPressure; 
192     VaporPressure = p.VaporPressure; 
193     return *this;
194 }
195
196 inline FGPhysicalProperties& FGPhysicalProperties::operator *= ( const WeatherPrecision d )
197 {
198     typedef map<FGPhysicalProperties::Altitude, FGWindItem      >::iterator wind_iterator;
199     typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::iterator turbulence_iterator;
200     typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::iterator scalar_iterator;
201
202     for (wind_iterator       WindIt = Wind.begin(); 
203                              WindIt != Wind.end(); 
204                              WindIt++)
205         WindIt->second*= d;
206
207     for (turbulence_iterator TurbulenceIt = Turbulence.begin(); 
208                              TurbulenceIt != Turbulence.end(); 
209                              TurbulenceIt++)
210         TurbulenceIt->second *= d;
211
212     for (scalar_iterator     TemperatureIt = Temperature.begin(); 
213                              TemperatureIt != Temperature.end(); 
214                              TemperatureIt++)
215         TemperatureIt->second *= d;
216
217     AirPressure *= d;
218
219     for (scalar_iterator     VaporPressureIt = VaporPressure.begin(); 
220                              VaporPressureIt != VaporPressure.end(); 
221                              VaporPressureIt++)
222         VaporPressureIt->second *= d;
223
224     return *this;
225 }
226
227 inline FGPhysicalProperties& FGPhysicalProperties::operator += (const FGPhysicalProperties& p)
228 {
229     typedef map<FGPhysicalProperties::Altitude, FGWindItem      >::const_iterator wind_iterator;
230     typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator turbulence_iterator;
231     typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
232
233     for (wind_iterator       WindIt = p.Wind.begin(); 
234                              WindIt != p.Wind.end(); 
235                              WindIt++)
236         if (!Wind.insert(*WindIt).second)           //when it's not inserted => it's already existing
237             Wind[WindIt->first] += WindIt->second;  //=> add the value
238             
239     for (turbulence_iterator TurbulenceIt = p.Turbulence.begin(); 
240                              TurbulenceIt != p.Turbulence.end(); 
241                              TurbulenceIt++)
242         if (!Turbulence.insert(*TurbulenceIt).second)   
243             Turbulence[TurbulenceIt->first] += TurbulenceIt->second;
244
245     for (scalar_iterator     TemperatureIt = p.Temperature.begin(); 
246                              TemperatureIt != p.Temperature.end(); 
247                              TemperatureIt++)
248         if (!Temperature.insert(*TemperatureIt).second) 
249             Temperature[TemperatureIt->first] += TemperatureIt->second;
250             
251     AirPressure += p.AirPressure.getValue(0.0);
252             
253     for (scalar_iterator     VaporPressureIt = p.VaporPressure.begin(); 
254                              VaporPressureIt != p.VaporPressure.end(); 
255                              VaporPressureIt++)
256         if (!VaporPressure.insert(*VaporPressureIt).second)     
257             VaporPressure[VaporPressureIt->first] += VaporPressureIt->second;
258
259     return *this;
260 }
261
262 inline FGPhysicalProperties& FGPhysicalProperties::operator -= (const FGPhysicalProperties& p)
263 {
264     typedef map<FGPhysicalProperties::Altitude, FGWindItem      >::const_iterator wind_iterator;
265     typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator turbulence_iterator;
266     typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
267
268     for (wind_iterator       WindIt = p.Wind.begin(); 
269                              WindIt != p.Wind.end(); 
270                              WindIt++)
271         if (!Wind.insert( make_pair(WindIt->first, -WindIt->second) ).second)   //when it's not inserted => it's already existing
272             Wind[WindIt->first] -= WindIt->second;                              //=> substract the value
273             
274     for (turbulence_iterator TurbulenceIt = p.Turbulence.begin(); 
275                              TurbulenceIt != p.Turbulence.end(); 
276                              TurbulenceIt++)
277         if (!Turbulence.insert( make_pair(TurbulenceIt->first, -TurbulenceIt->second) ).second) 
278             Turbulence[TurbulenceIt->first] -= TurbulenceIt->second;
279             
280     for (scalar_iterator     TemperatureIt = p.Temperature.begin(); 
281                              TemperatureIt != p.Temperature.end(); 
282                              TemperatureIt++)
283         if (!Temperature.insert( make_pair(TemperatureIt->first, -TemperatureIt->second) ).second)      
284             Temperature[TemperatureIt->first] -= TemperatureIt->second;
285             
286     AirPressure -= p.AirPressure.getValue(0.0);
287             
288     for (scalar_iterator     VaporPressureIt = p.VaporPressure.begin(); 
289                              VaporPressureIt != p.VaporPressure.end(); 
290                              VaporPressureIt++)
291         if (!VaporPressure.insert( make_pair(VaporPressureIt->first, -VaporPressureIt->second) ).second)        
292             VaporPressure[VaporPressureIt->first] -= VaporPressureIt->second;
293
294
295     return *this;
296 }
297
298
299 inline void FGPhysicalProperties::WindAt(sgVec3 ret, const WeatherPrecision a) const
300 {
301     typedef map<FGPhysicalProperties::Altitude, FGWindItem>::const_iterator vector_iterator;
302
303     vector_iterator it = Wind.lower_bound(a);
304     vector_iterator it2 = it;
305     it--;
306
307     //now I've got it->alt < a < it2->alt so I can interpolate
308     sgSubVec3(ret, *it2->second.getValue(), *it->second.getValue());
309     sgScaleVec3(ret, (a - it2->first) / (it2->first - it->first));
310     sgAddVec3(ret, *it2->second.getValue());
311 }
312
313 inline void FGPhysicalProperties::TurbulenceAt(sgVec3 ret, const WeatherPrecision a) const
314 {
315     typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator vector_iterator;
316
317     vector_iterator it = Turbulence.lower_bound(a);
318     vector_iterator it2 = it;
319     it--;
320
321     //now I've got it->alt < a < it2->alt so I can interpolate
322     sgSubVec3(ret, *it2->second.getValue(), *it->second.getValue());
323     sgScaleVec3(ret, (a - it2->first) / (it2->first - it->first));
324     sgAddVec3(ret, *it2->second.getValue());
325 }
326
327 inline WeatherPrecision FGPhysicalProperties::TemperatureAt(const WeatherPrecision a) const
328 {
329     typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
330
331     scalar_iterator it = Temperature.lower_bound(a);
332     scalar_iterator it2 = it;
333     it--;
334
335     //now I've got it->alt < a < it2->alt so I can interpolate
336     return ( (it2->second - it->second)/(it2->first - it->first) ) * (a - it2->first) + it2->second; 
337 }
338
339 inline WeatherPrecision FGPhysicalProperties::AirPressureAt(const WeatherPrecision a) const
340 {
341     return AirPressure.getValue(a);
342 }
343
344 inline WeatherPrecision FGPhysicalProperties::VaporPressureAt(const WeatherPrecision a) const
345 {
346     typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
347
348     scalar_iterator it = VaporPressure.lower_bound(a);
349     scalar_iterator it2 = it;
350     it--;
351
352     //now I've got it->alt < a < it2->alt so I can interpolate
353     return ( (it2->second - it->second)/(it2->first - it->first) ) * (a - it2->first) + it2->second; 
354 }
355
356
357 inline FGPhysicalProperties operator * (FGPhysicalProperties a, const WeatherPrecision b)
358 {
359     return a *= b;
360 }
361
362 inline FGPhysicalProperties operator * (const WeatherPrecision b, FGPhysicalProperties a)
363 {
364     return a *= b;
365 }
366
367 inline FGPhysicalProperties operator + (FGPhysicalProperties a, const FGPhysicalProperties& b)
368 {
369     return a += b;
370 }
371
372 inline FGPhysicalProperties operator - (FGPhysicalProperties a, const FGPhysicalProperties& b)
373 {
374     return a -= b;
375 }
376
377 /****************************************************************************/
378 #endif /*FGPhysicalProperties_H*/
379