Esempio n. 1
0
        public void Save(string title)
        {
            FileSupport.Save(TE, title, "T_TE_MAP");
            FileSupport.Save(TW, title, "T_TW_MAP");
            FileSupport.Save(TL, title, "T_TL_MAP");
            FileSupport.Save(TS, title, "T_TS_MAP");

            FileSupport.Save(SNOW, title, "N_00_MAP");
            FileSupport.Save(RAIN, title, "R_00_MAP");

            FileSupport.Save(BLIZZARD, title, "B_00_MAP");
            FileSupport.Save(ALBEDO, title, "A_00_MAP");

            FileSupport.Save(Precip, title, "C_00_MAP");
            FileSupport.Save(TLow, title, "T_SL_MAP");
            FileSupport.Save(THigh, title, "T_SH_MAP");
            FileSupport.Save(LIDX, title, "L_00_MAP");

            FileSupport.Save(FOG, title, "F_SI_MAP");

            FileSupport.Save(TNormLow, title, "T_NL_MAP");
            FileSupport.Save(TNormHigh, title, "T_NH_MAP");

            FileSupport.Save(TLow - TNormLow, title, "T_DL_MAP");
            FileSupport.Save(THigh - TNormHigh, title, "T_DH_MAP");
            FileSupport.Save(0.5f * (TLow - TNormLow + THigh - TNormHigh).EQ(), title, "T_DA_MAP");

            FileSupport.Save((1000 * WL - MatrixFactory.Init(500)), title, "E_00_MAP");
        }
Esempio n. 2
0
        public Atmosphere(EarthModel earth, bool loadFromStateFiles, float defaultValue = 0)
        {
            this.Earth = earth;

            SeaLevel = new SeaLevel(earth, loadFromStateFiles, defaultValue);
            MidLevel = new MidLevel(earth, loadFromStateFiles, defaultValue);
            TopLevel = new TopLevel(earth, loadFromStateFiles, defaultValue);
            JetLevel = new JetLevel(earth, loadFromStateFiles, defaultValue);

            if (loadFromStateFiles == false)
            {
                if (defaultValue == 0)
                {
                    TopLevel.LoadInitialConditions();

                    MidLevel.LoadInitialConditions();
                    CalculateAirMassType();

                    SeaLevel.LoadInitialConditions();
                }
                else
                {
                    AirMass = MatrixFactory.Init(defaultValue);
                }
            }
            else
            {
                AirMass = FileSupport.Load(Earth.UTC.Title, "M_00_MAP");
            }
        }
Esempio n. 3
0
 public static DenseMatrix LoadMatrixFromFile(string filePath)
 {
     try
     {
         return(new MatrixFile(filePath, true).Matrix);
     }
     catch
     {
         return(MatrixFactory.Init());
     }
 }
Esempio n. 4
0
        private DenseMatrix ImportLevelData(string dataFile, string paramName, int levelIdx, Func <float, float> conversionFunc)
        {
            if (string.IsNullOrEmpty(dataFile) == false)
            {
                if (File.Exists(dataFile))
                {
                    File.Delete(dataFile);
                }
            }

            int level = (levelIdx < 0) ? 0 : _levels[levelIdx];

            var messages = _messages.Where(m => m.Name.Contains(paramName) && m.Level == level).First();

            var nodes = messages.GeoSpatialValues.Where(gs => gs.IsMissing == false &&
                                                        (gs.Latitude >= EarthModel.MinLat && gs.Latitude <= EarthModel.MaxLat) &&
                                                        (gs.Longitude >= 180 + EarthModel.MinLon && gs.Longitude <= 180 + EarthModel.MaxLon) &&
                                                        (gs.Latitude == Math.Truncate(gs.Latitude)) &&
                                                        gs.Longitude == Math.Truncate(gs.Longitude))
                        .ToArray();

            if (!time)
            {
                DateTime    dt  = messages.ReferenceTime;
                SimDateTime sdt = new SimDateTime(dt);

                string timeSeedFile = "timeSeed.thd";
                CorrectFilePath(ref timeSeedFile);
                File.WriteAllText(timeSeedFile, sdt.Title);

                time = true;
            }

            DenseMatrix mat = MatrixFactory.Init();

            foreach (var node in nodes)
            {
                int r = EarthModel.MaxLat - (int)node.Latitude;
                int c = ((int)node.Longitude - EarthModel.MinLon) % 360;
                mat[r, c] = conversionFunc((float)node.Value);
            }

            if (string.IsNullOrEmpty(dataFile) == false)
            {
                FileSupport.SaveMatrixToFile(mat, dataFile, false);
            }

            return(mat);
        }
        public AtmosphericLevel(EarthModel earth, int levelType, bool loadFromStateFiles, float defaultValue = 0)
        {
            this.Earth = earth;
            _levelType = levelType;

            if (loadFromStateFiles)
            {
                P = FileSupport.Load(Earth.UTC.Title, string.Format("P_{0:d2}_MAP", _levelType));
                T = FileSupport.Load(Earth.UTC.Title, string.Format("T_{0:d2}_MAP", _levelType));
                H = FileSupport.Load(Earth.UTC.Title, string.Format("H_{0:d2}_MAP", _levelType));
            }
            else if (defaultValue != 0)
            {
                P = MatrixFactory.Init(defaultValue);
                T = MatrixFactory.Init(defaultValue);
                H = MatrixFactory.Init(defaultValue);
            }
        }
        protected virtual void ApplyCyclogenesys(DenseMatrix[] applyDevs, DenseMatrix T0, DenseMatrix P0)
        {
            DenseMatrix rawP = P0.Clone() as DenseMatrix;

            DenseMatrix deltaT = null;
            DenseMatrix deltaP = null;

            float thickness     = 0;
            float levelPressure = 0;

            switch (_levelType)
            {
            case LevelType.TopLevel:
                deltaT        = (Earth.ATM.TopLevel.T - MatrixFactory.Init(-55));
                deltaP        = (Earth.ATM.TopLevel.P - MatrixFactory.Init(300));
                thickness     = -4.5f;
                levelPressure = LevelPressure.TopLevelPressure;
                break;

            case LevelType.MidLevel:
                deltaT        = (Earth.ATM.MidLevel.T - Earth.ATM.TopLevel.T);
                deltaP        = (Earth.ATM.MidLevel.P - Earth.ATM.TopLevel.P);
                thickness     = -4f;
                levelPressure = LevelPressure.MidLevelPressure;
                break;

            case LevelType.SeaLevel:
                deltaT        = (Earth.ATM.SeaLevel.T - Earth.ATM.MidLevel.T);
                deltaP        = (Earth.ATM.SeaLevel.P - Earth.ATM.MidLevel.P);
                thickness     = -1.5f;
                levelPressure = LevelPressure.SeaLevelPressure;
                break;
            }

            var weakBlock   = Earth.ATM.JetLevel.WeakBlockTH;
            var strongBlock = Earth.ATM.JetLevel.StrongBlockTH;

            var DIV = (10 * Earth.ATM.JetLevel.P.Divergence()).EQ(4);

            rawP.Assign((r, c) =>
            {
                var front     = Earth.ATM.Fronts[r, c];
                var pJetLevel = Earth.ATM.JetLevel.P[r, c];

                var t  = T[r, c] + AbsoluteConstants.WaterFreezePoint;
                var t0 = T0[r, c] + AbsoluteConstants.WaterFreezePoint;
                var p0 = P0[r, c];

                var lapseRate = Math.Abs(deltaT[r, c] / thickness);

                var unitDp = levelPressure * Math.Abs((t - t0) / AbsoluteConstants.WaterFreezePoint);

                var cf  = -SimulationParameters.Instance.CyclogeneticFactor;
                var acf = SimulationParameters.Instance.AntiCyclogeneticFactor;

                var div = DIV[r, c];

                const float strong           = 2.5f;
                const float weak             = 0.5f;
                const float pseudoStationary = 0.1f;

                //bool stable = ((lapseRate > SimulationParameters.Instance.HumidLapseRate) || (pJetLevel > strongBlock));
                //bool unstable = ((lapseRate < SimulationParameters.Instance.HumidLapseRate) || (pJetLevel < weakBlock));

                //bool stable = ((pJetLevel >= strongBlock));
                //bool unstable = ((pJetLevel <= weakBlock));

                bool stable   = ((div <= -1));
                bool unstable = ((div >= 1));

                float actualDp = 0;


                if (front < 0)
                {
                    if (stable)
                    {
                        actualDp = cf * pseudoStationary * unitDp;
                    }
                    else if (unstable)
                    {
                        actualDp = cf * strong * unitDp;
                    }
                    else
                    {
                        actualDp = cf * weak * unitDp;
                    }
                }
                else if (front > 0)
                {
                    actualDp = acf * pseudoStationary * unitDp;
                }
                else
                {
                    if (stable)
                    {
                        actualDp = acf * strong * unitDp;
                    }
                    else if (unstable)
                    {
                        actualDp = acf * pseudoStationary * unitDp;
                    }
                    else
                    {
                        actualDp = acf * weak * unitDp;
                    }
                }


                var p = p0 + Earth.SnapshotDivFactor * actualDp;

                if (p < PressureExtremes[0])
                {
                    p = PressureExtremes[0];
                }
                if (p > PressureExtremes[1])
                {
                    p = PressureExtremes[1];
                }

                return(p);
            });

            var pNorth = rawP.RegionSubMatrix(-180, 179, 0, 89);
            var pSouth = rawP.RegionSubMatrix(-180, 179, -89, -1);

            var projPNorth = pNorth.Divide(pNorth.Mean()).Multiply(levelPressure) as DenseMatrix;
            var projPSouth = pSouth.Divide(pSouth.Mean()).Multiply(levelPressure) as DenseMatrix;

            var projP = MatrixFactory.Init();

            projP.SetSubMatrix(0, pNorth.RowCount, 0, pNorth.ColumnCount, projPNorth);
            projP.SetSubMatrix(pNorth.RowCount, pSouth.RowCount, 0, pSouth.ColumnCount, projPSouth);

            P = projP.EQ(4).ApplyDeviations(applyDevs, null).EQ(4);
        }
Esempio n. 7
0
        public SurfaceLevel(EarthModel earth, bool loadFromStateFiles, float defaultValue = 0)
        {
            this.Earth = earth;
            InitGeographicalParams();

            if (loadFromStateFiles == false)
            {
                if (defaultValue == 0)
                {
                    // ------------
                    // Soil temperature where applicable
                    string filePath = Path.Combine(SimulationData.WorkFolder, "SOIL.thd");
                    if (File.Exists(filePath))
                    {
                        var tl = FileSupport.LoadMatrixFromFile(filePath);
                        TL.Assign((r, c) =>
                        {
                            if (WL[r, c] == 0)
                            {
                                return(tl[r, c]);
                            }

                            return(0);
                        });
                    }

                    // ------------
                    // Sea temperature where applicable
                    filePath = Path.Combine(SimulationData.WorkFolder, "SST.thd");
                    if (File.Exists(filePath))
                    {
                        var tw = FileSupport.LoadMatrixFromFile(filePath);
                        TW.Assign((r, c) =>
                        {
                            if (WL[r, c] != 0)
                            {
                                return(tw[r, c]);
                            }

                            return(0);
                        });
                    }

                    // Combined surface temperature
                    TS.Assign((r, c) =>
                    {
                        if (WL[r, c] != 0)
                        {
                            return(TW[r, c]);
                        }

                        return(TL[r, c]);
                    });

                    // ------------
                    // Snow cover
                    filePath = Path.Combine(SimulationData.WorkFolder, "SNOW.thd");
                    if (File.Exists(filePath))
                    {
                        this.SNOW = FileSupport.LoadMatrixFromFile(filePath);
                    }
                }
                else
                {
                    TE       = MatrixFactory.Init(defaultValue);
                    TW       = MatrixFactory.Init(defaultValue);
                    TL       = MatrixFactory.Init(defaultValue);
                    TS       = MatrixFactory.Init(defaultValue);
                    SNOW     = MatrixFactory.Init(defaultValue);
                    RAIN     = MatrixFactory.Init(defaultValue);
                    BLIZZARD = MatrixFactory.Init(defaultValue);
                    ALBEDO   = MatrixFactory.Init(defaultValue);

                    Precip = MatrixFactory.Init(defaultValue);
                    TLow   = MatrixFactory.Init(defaultValue);
                    THigh  = MatrixFactory.Init(defaultValue);
                    LIDX   = MatrixFactory.Init(defaultValue);

                    FOG = MatrixFactory.Init(defaultValue);

                    TNormLow  = MatrixFactory.Init(defaultValue);
                    TNormHigh = MatrixFactory.Init(defaultValue);
                }
            }
            else
            {
                TE = FileSupport.Load(Earth.UTC.Title, "T_TE_MAP");
                TW = FileSupport.Load(Earth.UTC.Title, "T_TW_MAP");
                TL = FileSupport.Load(Earth.UTC.Title, "T_TL_MAP");
                TS = FileSupport.Load(Earth.UTC.Title, "T_TS_MAP");

                SNOW = FileSupport.Load(Earth.UTC.Title, "N_00_MAP");
                RAIN = FileSupport.Load(Earth.UTC.Title, "R_00_MAP");

                BLIZZARD = FileSupport.Load(Earth.UTC.Title, "B_00_MAP");
                ALBEDO   = FileSupport.Load(Earth.UTC.Title, "A_00_MAP");

                Precip = FileSupport.Load(Earth.UTC.Title, "C_00_MAP");
                TLow   = FileSupport.Load(Earth.UTC.Title, "T_SL_MAP");
                THigh  = FileSupport.Load(Earth.UTC.Title, "T_SH_MAP");
                LIDX   = FileSupport.Load(Earth.UTC.Title, "L_00_MAP");

                FOG = FileSupport.Load(Earth.UTC.Title, "F_SI_MAP");

                TNormLow  = FileSupport.Load(Earth.UTC.Title, "T_NL_MAP");
                TNormHigh = FileSupport.Load(Earth.UTC.Title, "T_NH_MAP");
            }
        }
Esempio n. 8
0
        public void CalculateTotalPrecipitation()
        {
            var GP = Earth.ATM.MidLevel.P.Gradient2().Rescale(new float[] { 0, 100 });
            var GT = Earth.ATM.MidLevel.T.Gradient2().Rescale(new float[] { 0, 100 });
            var TS = Earth.SFC.TS;
            var TE = Earth.SFC.TE;

            DenseMatrix WIND = MatrixFactory.Init();

            if (Earth.ATM.SeaLevel.P != null)
            {
                WIND = Earth.ATM.SeaLevel.P.Gradient2();
            }

            var HMid = Earth.ATM.MidLevel.H;
            var HSea = Earth.ATM.SeaLevel.H;

            if (HSea == null)
            {
                HSea = HMid;
            }

            var eqFronts = Earth.ATM.Fronts;//.EQ();

            // Calculate convective precipitation (thunderstorms)
            CalculateInstabilityIndex(eqFronts);

            var FP = Earth.ATM.JetLevel.FP;

            Precip.Assign((r, c) =>
            {
                var hgt = Earth.SFC.Height[r, c];
                float h = 0;

                var hTop = Earth.ATM.TopLevel.H[r, c];
                var hMid = Earth.ATM.MidLevel.H[r, c];
                var hSea = Earth.ATM.SeaLevel.H[r, c];

                if (hgt > SimConstants.LevelHeights[LevelType.TopLevel])
                {
                    h = 0.5f * hTop;
                }
                else if (hgt > SimConstants.LevelHeights[LevelType.MidLevel])
                {
                    h = 0.5f * (hTop + hMid);
                }
                else
                {
                    h = 0.5f * (hSea + hMid);
                }

                var lidx = LIDX[r, c];
                var gp   = GP[r, c];
                var gt   = GT[r, c];
                var fp   = FP[r, c];

                // Baric gradient precipitation
                var pRate = 0.5f * Math.Abs(gp);

                // Frontal precipitation
                var f     = eqFronts[r, c];
                var dx    = (f > 0) ? 0.75f : 1.5f;
                var fRate = dx * 20 * Math.Abs(f);

                // Orographic precipitation
                var oRate = 0.3f * ((hgt >= 900) ? h : 0);

                // Convective precipitation
                var cRate = 0f;
                if (lidx < 0)
                {
                    var lidxRate = Math.Abs(lidx);

                    var mul = 1;
                    if (lidx > 3)
                    {
                        mul = 2;
                    }
                    if (lidx > 5)
                    {
                        mul = 3;
                    }
                    if (lidx > 7)
                    {
                        mul = 4;
                    }
                    if (lidx > 9)
                    {
                        mul = 5;
                    }

                    cRate = fp * mul * Math.Abs(lidxRate);
                }

                var totalRate = (pRate + fRate + oRate + cRate) * h / 100;

                return(Math.Min(300, totalRate));
            });


            DenseMatrix SolidPrecip = MatrixFactory.Init();

            for (int r = 0; r < SolidPrecip.RowCount; r++)
            {
                for (int c = 0; c < SolidPrecip.ColumnCount; c++)
                {
                    var wl  = WL[r, c];
                    var ts  = TS[r, c];
                    var te  = TE[r, c];
                    var cl  = Precip[r, c];
                    var t01 = Earth.ATM.MidLevel.T[r, c];

                    var totalRain = RAIN[r, c];
                    var totalSnow = SNOW[r, c];

                    var fogMeltFactor = Math.Min(1, 1 - FOG[r, c] / 100);

                    const float precipClThreshold = 10f;

                    if (te >= -10f || cl <= precipClThreshold)
                    {
                        if (te >= 0)
                        {
                            // Accumulated soil moisture evaporation
                            totalRain -= 0.5f * te * Earth.SnapshotLength;
                            if (totalRain < 0)
                            {
                                totalRain = 0;
                            }

                            // Old snow cover is melting and transforming into water
                            // OBS: Snow melts faster when we have fog
                            var meltedSnow = Math.Min(totalSnow, 0.2f * (1 + fogMeltFactor) * te * Earth.SnapshotLength);
                            totalSnow -= meltedSnow;
                            if (totalSnow < 0)
                            {
                                totalSnow = 0;
                            }

                            // Consider melted snow as rain because it contributes to the total soil moisture
                            totalRain += meltedSnow;
                        }
                        else
                        {
                            // Old snow cover is slowly compacting due to daytime melt / night time freeze
                            totalSnow -= 0.025f * (1 + fogMeltFactor) * Earth.SnapshotLength;

                            if (totalSnow < 0)
                            {
                                totalSnow = 0;
                            }
                        }
                    }

                    DaysSinceLastRainFall[r, c] = (DaysSinceLastRainFall[r, c] + Earth.SnapshotDivFactor);
                    DaysSinceLastSnowFall[r, c] = (DaysSinceLastSnowFall[r, c] + Earth.SnapshotDivFactor);

                    float actualPrecipRate = (cl - precipClThreshold);
                    if (actualPrecipRate > 0)
                    {
                        var unitPrecipFall = actualPrecipRate * Earth.SnapshotDivFactor;

                        PrecipTypeComputer <float> .Compute(

                            // Actual temperatures
                            te, ts, t01,

                            // Boundary temperatures as read from simulation parameters
                            SimulationParameters.Instance,

                            // Computed precip type: snow
                            () =>
                        {
                            totalSnow                  += 0.3f * unitPrecipFall;
                            SolidPrecip[r, c]           = 1;
                            DaysSinceLastSnowFall[r, c] = 0;
                            return(0);
                        },

                            // Computed precip type: rain
                            () =>
                        {
                            totalRain += unitPrecipFall;
                            DaysSinceLastRainFall[r, c] = 0;
                            return(0);
                        },

                            // Computed precip type: freezing rain
                            () =>
                        {
                            totalSnow                  += 0.1f * unitPrecipFall;
                            totalRain                  += 0.9f * unitPrecipFall;
                            SolidPrecip[r, c]           = 1;
                            DaysSinceLastSnowFall[r, c] = 0;
                            return(0);
                        },

                            // Computed precip type: sleet
                            () =>
                        {
                            totalSnow                  += 0.2f * unitPrecipFall;
                            totalRain                  += 0.8f * unitPrecipFall;
                            SolidPrecip[r, c]           = 1;
                            DaysSinceLastSnowFall[r, c] = 0;
                            return(0);
                        }
                            );
                    }

                    if (totalSnow < 0 ||
                        // Snow does not accumulate on a water surface if water is not frozen
                        (wl != 0 && ts > 0))
                    {
                        totalSnow = 0;
                    }

                    if (totalRain < 0 ||
                        // Rain water does not accumulate on a water surface
                        wl != 0)
                    {
                        totalRain = 0;
                    }

                    RAIN[r, c] = totalRain;
                    SNOW[r, c] = totalSnow;
                }
            }
            ;

            Earth.SFC.BLIZZARD.Assign((r, c) =>
            {
                var wind         = WIND[r, c];
                var cl           = Precip[r, c] / 20f;
                bool solidPrecip = (SolidPrecip[r, c] != 0);

                if (solidPrecip)
                {
                    return(Math.Abs(cl * wind));
                }

                return(0);
            });

            Earth.SFC.ALBEDO.Assign((r, c) =>
            {
                var wl        = WL[r, c];
                var defAlbedo = DEF_ALBEDO[r, c];

                //if (wl == 0)
                {
                    var snowAlbedo = 0f;
                    var rainAlbedo = 0f;

                    if (SNOW[r, c] > 3f)
                    {
                        snowAlbedo = SNOW[r, c] + 20f * Math.Max(0, 5 - DaysSinceLastSnowFall[r, c]);
                    }

                    if (RAIN[r, c] >= 10f)
                    {
                        rainAlbedo = 0.5f * RAIN[r, c] + 10f * Math.Max(0, 3 - DaysSinceLastRainFall[r, c]);
                    }

                    var total = Math.Min(100f, defAlbedo + snowAlbedo + rainAlbedo);

                    return(total);

                    //return Math.Max(total, defAlbedo);
                }

                //return defAlbedo;
            });
        }