]> git.mxchange.org Git - flightgear.git/blob - src/WeatherCM/FGPhysicalProperties.h
Panel code reorganization contributed by David Megginson:
[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 <Include/compiler.h>
61
62 #ifdef HAVE_WINDOWS_H
63 #  include <windows.h>
64 #endif
65
66 #include <iostream>
67 #include <vector>
68 #include <map>
69
70 #include <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 FG_USING_STD(vector);
82 FG_USING_STD(map);
83 FG_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 inline FGPhysicalProperties& FGPhysicalProperties::operator -= (const FGPhysicalProperties& p)
233 {
234     typedef map<FGPhysicalProperties::Altitude, FGWindItem      >::const_iterator wind_iterator;
235     typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator turbulence_iterator;
236     typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
237
238     for (wind_iterator       WindIt = p.Wind.begin(); 
239                              WindIt != p.Wind.end(); 
240                              WindIt++)
241         if (!Wind.insert( make_pair(WindIt->first, -WindIt->second) ).second)   //when it's not inserted => it's already existing
242             Wind[WindIt->first] -= WindIt->second;                              //=> substract the value
243             
244     for (turbulence_iterator TurbulenceIt = p.Turbulence.begin(); 
245                              TurbulenceIt != p.Turbulence.end(); 
246                              TurbulenceIt++)
247         if (!Turbulence.insert( make_pair(TurbulenceIt->first, -TurbulenceIt->second) ).second) 
248             Turbulence[TurbulenceIt->first] -= TurbulenceIt->second;
249             
250     for (scalar_iterator     TemperatureIt = p.Temperature.begin(); 
251                              TemperatureIt != p.Temperature.end(); 
252                              TemperatureIt++)
253         if (!Temperature.insert( make_pair(TemperatureIt->first, -TemperatureIt->second) ).second)      
254             Temperature[TemperatureIt->first] -= TemperatureIt->second;
255             
256     AirPressure -= p.AirPressure.getValue();
257             
258     for (scalar_iterator     VaporPressureIt = p.VaporPressure.begin(); 
259                              VaporPressureIt != p.VaporPressure.end(); 
260                              VaporPressureIt++)
261         if (!VaporPressure.insert( make_pair(VaporPressureIt->first, -VaporPressureIt->second) ).second)        
262             VaporPressure[VaporPressureIt->first] -= VaporPressureIt->second;
263
264
265     return *this;
266 }
267
268 inline void FGPhysicalProperties::WindAt(sgVec3 ret, const WeatherPrecision a) const
269 {
270     typedef map<FGPhysicalProperties::Altitude, FGWindItem>::const_iterator vector_iterator;
271
272     vector_iterator it = Wind.lower_bound(a);
273     vector_iterator it2 = it;
274     it--;
275
276     //now I've got it->alt < a < it2->alt so I can interpolate
277     sgSubVec3(ret, *it2->second.getValue(), *it->second.getValue());
278     sgScaleVec3(ret, (a - it2->first) / (it2->first - it->first));
279     sgAddVec3(ret, *it2->second.getValue());
280 }
281
282 inline void FGPhysicalProperties::TurbulenceAt(sgVec3 ret, const WeatherPrecision a) const
283 {
284     typedef map<FGPhysicalProperties::Altitude, FGTurbulenceItem>::const_iterator vector_iterator;
285
286     vector_iterator it = Turbulence.lower_bound(a);
287     vector_iterator it2 = it;
288     it--;
289
290     //now I've got it->alt < a < it2->alt so I can interpolate
291     sgSubVec3(ret, *it2->second.getValue(), *it->second.getValue());
292     sgScaleVec3(ret, (a - it2->first) / (it2->first - it->first));
293     sgAddVec3(ret, *it2->second.getValue());
294 }
295
296 inline WeatherPrecision FGPhysicalProperties::TemperatureAt(const WeatherPrecision a) const
297 {
298     typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
299
300     scalar_iterator it = Temperature.lower_bound(a);
301     scalar_iterator it2 = it;
302     it--;
303
304     //now I've got it->alt < a < it2->alt so I can interpolate
305     return ( (it2->second - it->second)/(it2->first - it->first) ) * (a - it2->first) + it2->second; 
306 }
307
308 //inline WeatherPrecision FGPhysicalProperties::AirPressureAt(const WeatherPrecision x) const
309 //moved to FGPhysicalProperties.cpp as it got too complex to inline
310
311 inline WeatherPrecision FGPhysicalProperties::VaporPressureAt(const WeatherPrecision a) const
312 {
313     typedef map<FGPhysicalProperties::Altitude, WeatherPrecision>::const_iterator scalar_iterator;
314
315     scalar_iterator it = VaporPressure.lower_bound(a);
316     scalar_iterator it2 = it;
317     it--;
318
319     //now I've got it->alt < a < it2->alt so I can interpolate
320     return ( (it2->second - it->second)/(it2->first - it->first) ) * (a - it2->first) + it2->second; 
321 }
322
323
324 inline FGPhysicalProperties operator * (FGPhysicalProperties a, const WeatherPrecision b)
325 {
326     return a *= b;
327 }
328
329 inline FGPhysicalProperties operator * (const WeatherPrecision b, FGPhysicalProperties a)
330 {
331     return a *= b;
332 }
333
334 inline FGPhysicalProperties operator + (FGPhysicalProperties a, const FGPhysicalProperties& b)
335 {
336     return a += b;
337 }
338
339 inline FGPhysicalProperties operator - (FGPhysicalProperties a, const FGPhysicalProperties& b)
340 {
341     return a -= b;
342 }
343
344 /****************************************************************************/
345 #endif /*FGPhysicalProperties_H*/
346