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