]> git.mxchange.org Git - flightgear.git/blob - src/WeatherCM/FGPhysicalProperties.h
f6e8f23d9c94f384e9914200c8e4021cd6baeafa
[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 #ifdef HAVE_CONFIG_H
53 #  include <config.h>
54 #endif
55
56 #include <Include/compiler.h>
57
58 #ifdef HAVE_WINDOWS_H
59 #  include <windows.h>
60 #endif
61
62 #include <iostream>
63 #include <vector>
64 #include <map>
65
66 #include "sg.h"
67
68 #include "FGWeatherDefs.h"
69
70 #include "FGAirPressureItem.h"
71 #include "FGWindItem.h"
72 #include "FGTurbulenceItem.h"
73
74 #include "FGCloudItem.h"
75 #include "FGSnowRain.h"
76
77 FG_USING_STD(vector);
78 FG_USING_STD(map);
79 FG_USING_NAMESPACE(std);
80
81 /****************************************************************************/
82 /* FOREWARD DEFINITIONS                                                     */
83 /****************************************************************************/
84 class FGPhysicalProperties2D;
85 ostream& operator<< ( ostream& out, const FGPhysicalProperties2D& p );
86
87 class FGPhysicalProperties
88 {
89 public:
90     typedef WeatherPrecision Altitude;  
91
92     map<Altitude,FGWindItem>       Wind;            //all Wind vectors
93     map<Altitude,FGTurbulenceItem> Turbulence;      //all Turbulence vectors
94     map<Altitude,WeatherPrecision> Temperature;     //in deg. Kelvin (I *only* accept SI!)
95     FGAirPressureItem              AirPressure;     //in Pascal (I *only* accept SI!)
96     map<Altitude,WeatherPrecision> VaporPressure;   //in Pascal (I *only* accept SI!)
97
98     map<Altitude,FGCloudItem>      Clouds;          //amount of covering and type
99
100     WeatherPrecision               SnowRainIntensity;       //this also stands for hail, snow,...
101     SnowRainType                   snowRainType;            
102     WeatherPrecision               LightningProbability;    //in lightnings per second   
103
104     FGPhysicalProperties();   //consructor to fill it with FG standart weather
105
106     //return values at specified altitudes
107     void             WindAt         (sgVec3 ret, const WeatherPrecision a) const;
108     void             TurbulenceAt   (sgVec3 ret, const WeatherPrecision a) const;
109     WeatherPrecision TemperatureAt  (const WeatherPrecision a) const;
110     WeatherPrecision AirPressureAt  (const WeatherPrecision a) const;
111     WeatherPrecision VaporPressureAt(const WeatherPrecision a) const;
112
113     //for easier access to the cloud stuff:
114     unsigned int getNumberOfCloudLayers(void) const;
115     FGCloudItem  getCloudLayer(unsigned int nr) const;
116     
117     FGPhysicalProperties& operator =  ( const FGPhysicalProperties& p ); 
118     FGPhysicalProperties& operator *= ( const WeatherPrecision      d ); 
119     FGPhysicalProperties& operator += ( const FGPhysicalProperties& p ); 
120     FGPhysicalProperties& operator -= ( const FGPhysicalProperties& p ); 
121 };
122
123 class FGPhysicalProperties2D : public FGPhysicalProperties
124 {
125 public:
126     sgVec2 p;       //position of the property (lat/lon)
127     friend ostream& operator<< ( ostream& out, const FGPhysicalProperties2D& p );
128
129     FGPhysicalProperties2D() {}
130
131     FGPhysicalProperties2D(const FGPhysicalProperties& prop, const sgVec2& pos) 
132     {
133         Wind = prop.Wind; 
134         Turbulence = prop.Turbulence;
135         Temperature = prop.Temperature;
136         AirPressure = prop.AirPressure; 
137         VaporPressure = prop.VaporPressure; 
138         sgCopyVec2(p, pos);
139     }
140 };
141
142 typedef vector<FGPhysicalProperties>                 FGPhysicalPropertiesVector;
143 typedef FGPhysicalPropertiesVector::iterator         FGPhysicalPropertiesVectorIt;
144 typedef FGPhysicalPropertiesVector::const_iterator   FGPhysicalPropertiesVectorConstIt;
145
146 typedef vector<FGPhysicalProperties2D>               FGPhysicalProperties2DVector;
147 typedef FGPhysicalProperties2DVector::iterator       FGPhysicalProperties2DVectorIt;
148 typedef FGPhysicalProperties2DVector::const_iterator FGPhysicalProperties2DVectorConstIt;
149
150
151
152 inline FGPhysicalProperties& FGPhysicalProperties::operator = ( const FGPhysicalProperties& p )
153 {
154     Wind          = p.Wind; 
155     Turbulence    = p.Turbulence; 
156     Temperature   = p.Temperature;
157     AirPressure   = p.AirPressure; 
158     VaporPressure = p.VaporPressure; 
159     return *this;
160 }
161
162 inline FGPhysicalProperties& FGPhysicalProperties::operator *= ( const WeatherPrecision d )
163 {
164     typedef map<FGPhysicalProperties::Altitude, FGWindItem      >::iterator wind_iterator;
165     typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::iterator turbulence_iterator;
166     typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::iterator scalar_iterator;
167
168     for (wind_iterator       WindIt = Wind.begin(); 
169                              WindIt != Wind.end(); 
170                              WindIt++)
171         WindIt->second*= d;
172
173     for (turbulence_iterator TurbulenceIt = Turbulence.begin(); 
174                              TurbulenceIt != Turbulence.end(); 
175                              TurbulenceIt++)
176         TurbulenceIt->second *= d;
177
178     for (scalar_iterator     TemperatureIt = Temperature.begin(); 
179                              TemperatureIt != Temperature.end(); 
180                              TemperatureIt++)
181         TemperatureIt->second *= d;
182
183     AirPressure *= d;
184
185     for (scalar_iterator     VaporPressureIt = VaporPressure.begin(); 
186                              VaporPressureIt != VaporPressure.end(); 
187                              VaporPressureIt++)
188         VaporPressureIt->second *= d;
189
190     return *this;
191 }
192
193 inline FGPhysicalProperties& FGPhysicalProperties::operator += (const FGPhysicalProperties& p)
194 {
195     typedef map<FGPhysicalProperties::Altitude, FGWindItem      >::const_iterator wind_iterator;
196     typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator turbulence_iterator;
197     typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
198
199     for (wind_iterator       WindIt = p.Wind.begin(); 
200                              WindIt != p.Wind.end(); 
201                              WindIt++)
202         if (!Wind.insert(*WindIt).second)           //when it's not inserted => it's already existing
203             Wind[WindIt->first] += WindIt->second;  //=> add the value
204             
205     for (turbulence_iterator TurbulenceIt = p.Turbulence.begin(); 
206                              TurbulenceIt != p.Turbulence.end(); 
207                              TurbulenceIt++)
208         if (!Turbulence.insert(*TurbulenceIt).second)   
209             Turbulence[TurbulenceIt->first] += TurbulenceIt->second;
210
211     for (scalar_iterator     TemperatureIt = p.Temperature.begin(); 
212                              TemperatureIt != p.Temperature.end(); 
213                              TemperatureIt++)
214         if (!Temperature.insert(*TemperatureIt).second) 
215             Temperature[TemperatureIt->first] += TemperatureIt->second;
216             
217     AirPressure += p.AirPressure.getValue(0.0);
218             
219     for (scalar_iterator     VaporPressureIt = p.VaporPressure.begin(); 
220                              VaporPressureIt != p.VaporPressure.end(); 
221                              VaporPressureIt++)
222         if (!VaporPressure.insert(*VaporPressureIt).second)     
223             VaporPressure[VaporPressureIt->first] += VaporPressureIt->second;
224
225     return *this;
226 }
227
228 inline FGPhysicalProperties& FGPhysicalProperties::operator -= (const FGPhysicalProperties& p)
229 {
230     typedef map<FGPhysicalProperties::Altitude, FGWindItem      >::const_iterator wind_iterator;
231     typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator turbulence_iterator;
232     typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
233
234     for (wind_iterator       WindIt = p.Wind.begin(); 
235                              WindIt != p.Wind.end(); 
236                              WindIt++)
237         if (!Wind.insert( make_pair(WindIt->first, -WindIt->second) ).second)   //when it's not inserted => it's already existing
238             Wind[WindIt->first] -= WindIt->second;                              //=> substract the value
239             
240     for (turbulence_iterator TurbulenceIt = p.Turbulence.begin(); 
241                              TurbulenceIt != p.Turbulence.end(); 
242                              TurbulenceIt++)
243         if (!Turbulence.insert( make_pair(TurbulenceIt->first, -TurbulenceIt->second) ).second) 
244             Turbulence[TurbulenceIt->first] -= TurbulenceIt->second;
245             
246     for (scalar_iterator     TemperatureIt = p.Temperature.begin(); 
247                              TemperatureIt != p.Temperature.end(); 
248                              TemperatureIt++)
249         if (!Temperature.insert( make_pair(TemperatureIt->first, -TemperatureIt->second) ).second)      
250             Temperature[TemperatureIt->first] -= TemperatureIt->second;
251             
252     AirPressure -= p.AirPressure.getValue(0.0);
253             
254     for (scalar_iterator     VaporPressureIt = p.VaporPressure.begin(); 
255                              VaporPressureIt != p.VaporPressure.end(); 
256                              VaporPressureIt++)
257         if (!VaporPressure.insert( make_pair(VaporPressureIt->first, -VaporPressureIt->second) ).second)        
258             VaporPressure[VaporPressureIt->first] -= VaporPressureIt->second;
259
260
261     return *this;
262 }
263
264
265 inline void FGPhysicalProperties::WindAt(sgVec3 ret, const WeatherPrecision a) const
266 {
267     typedef map<FGPhysicalProperties::Altitude, FGWindItem>::const_iterator vector_iterator;
268
269     vector_iterator it = Wind.lower_bound(a);
270     vector_iterator it2 = it;
271     it--;
272
273     //now I've got it->alt < a < it2->alt so I can interpolate
274     sgSubVec3(ret, *it2->second.getValue(), *it->second.getValue());
275     sgScaleVec3(ret, (a - it2->first) / (it2->first - it->first));
276     sgAddVec3(ret, *it2->second.getValue());
277 }
278
279 inline void FGPhysicalProperties::TurbulenceAt(sgVec3 ret, const WeatherPrecision a) const
280 {
281     typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator vector_iterator;
282
283     vector_iterator it = Turbulence.lower_bound(a);
284     vector_iterator it2 = it;
285     it--;
286
287     //now I've got it->alt < a < it2->alt so I can interpolate
288     sgSubVec3(ret, *it2->second.getValue(), *it->second.getValue());
289     sgScaleVec3(ret, (a - it2->first) / (it2->first - it->first));
290     sgAddVec3(ret, *it2->second.getValue());
291 }
292
293 inline WeatherPrecision FGPhysicalProperties::TemperatureAt(const WeatherPrecision a) const
294 {
295     typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
296
297     scalar_iterator it = Temperature.lower_bound(a);
298     scalar_iterator it2 = it;
299     it--;
300
301     //now I've got it->alt < a < it2->alt so I can interpolate
302     return ( (it2->second - it->second)/(it2->first - it->first) ) * (a - it2->first) + it2->second; 
303 }
304
305 inline WeatherPrecision FGPhysicalProperties::AirPressureAt(const WeatherPrecision a) const
306 {
307     return AirPressure.getValue(a);
308 }
309
310 inline WeatherPrecision FGPhysicalProperties::VaporPressureAt(const WeatherPrecision a) const
311 {
312     typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
313
314     scalar_iterator it = VaporPressure.lower_bound(a);
315     scalar_iterator it2 = it;
316     it--;
317
318     //now I've got it->alt < a < it2->alt so I can interpolate
319     return ( (it2->second - it->second)/(it2->first - it->first) ) * (a - it2->first) + it2->second; 
320 }
321
322
323 inline FGPhysicalProperties operator * (FGPhysicalProperties a, const WeatherPrecision b)
324 {
325     return a *= b;
326 }
327
328 inline FGPhysicalProperties operator * (const WeatherPrecision b, FGPhysicalProperties a)
329 {
330     return a *= b;
331 }
332
333 inline FGPhysicalProperties operator + (FGPhysicalProperties a, const FGPhysicalProperties& b)
334 {
335     return a += b;
336 }
337
338 inline FGPhysicalProperties operator - (FGPhysicalProperties a, const FGPhysicalProperties& b)
339 {
340     return a -= b;
341 }
342
343 /****************************************************************************/
344 #endif /*FGPhysicalProperties_H*/
345