Esempio n. 1
0
        //Формування рядка матриці коефіцієнтів рівнянь поправок
        public static double[] getCoefMatrixLineKoop(ReferenceSystem rs, int n, int[][] t_nm, double r, double coLatitude, double longitude, MathFunc.AngleType angType = AngleType.Radians)
        {
            if (angType == AngleType.Degrees)
            {
                deg2rad(ref longitude);
            }
            List <double> line = new List <double>((getArraySize(n) - 3) * 2 - (rs.maxDegree - 1));

            double[][] legPol = getLegendreP_lm_cos_phi(n, Math.PI / 2d - coLatitude);
            double     u_1 = rs.GM / Math.Pow(rs.a, 3d), u_2 = rs.a / rs.satelliteSphere;

            for (int l = 2; l <= rs.maxDegree; l++)
            {
                double u_3 = u_1 * Math.Pow(u_2, l + 3) * (l + 1) * (l + 2);
                for (int m = 0; m <= l; m++)
                {
                    line.Add(u_3 * legPol[l][m] * Math.Cos((double)m * longitude));
                    if (m != 0)
                    {
                        line.Add(u_3 * legPol[l][m] * Math.Sin((double)m * longitude));
                    }
                }
            }
            return(line.ToArray());
        }
Esempio n. 2
0
 public static string matrixToString(MathNet.Numerics.LinearAlgebra.Double.DenseMatrix dm, ReferenceSystem rs)
 {
     StringBuilder sb = new StringBuilder();
     int index = 0;
     for (int i = 0; i < 21; i++)
     {
         sb.AppendLine();
     }
     for (int i = 2; i <= rs.maxDegree; i++)
     {
         for (int j = 0; j <= i; j++)
         {
             if (j != 0)
             {
                 sb.AppendLine(string.Format("{0}\t{1}\t{2:0.000000000000e+00}\t{3:0.000000000000e+00}", i, j, dm.Values[index], dm.Values[index + 1]));
                 index += 2;
             }
             else {
                 sb.AppendLine(string.Format("{0}\t{1}\t{2:0.000000000000e+00}\t{3:0.000000000000e+00}", i, j, dm.Values[index], 0));
                 index += 1;
             }
         }
     }
     return sb.ToString();
 }
Esempio n. 3
0
        //Обчислення коефіцієнтів збурюючого потенціалу відностно Нормальної Землі "rs"
        public static GravityModel getDisturbingModel(ReferenceSystem rs, GravityModel model)
        {
            GravityModel result = new GravityModel(model, model.model_a, model.model_GM);

            double[] normalModel = generateNormalModel(rs, 8);
            for (int i = 0; i < normalModel.Length; i += 2)
            {
                result.c_coef[i][0] = result.c_coef[i][0] - normalModel[i];
            }
            return(result);
        }
Esempio n. 4
0
 //Метод генерує масив з коефіцієнтами моделі нормального потенціалу [1,0,c_20,0,c_40,0,c_80...c_maxDegree0]
 public static double[] generateNormalModel(ReferenceSystem rs, int maxDegree = 8)
 {
     double[] normalModel = new double[maxDegree + 1];
     normalModel[0] = 1D; double C_2k = 0, k = 0, tmp = 1d - 2d / 15d * (rs.m_gamma * Math.Sqrt(rs.secondExcentricity_2)) / rs.q0;
     for (int i = 2; i <= maxDegree; i += 2)
     {
         k    = i / 2;
         C_2k = Math.Pow(-1d, k) * 3d * Math.Pow(rs.firstExcentricity_2, k) / ((2d * k + 1d) * (2d * k + 3d)) * (1d - k + 5d * k / 3d * tmp) / Math.Sqrt(2d * i + 1d);
         normalModel[i - 1] = 0D;
         normalModel[i]     = C_2k;
     }
     return(normalModel);
 }
Esempio n. 5
0
        public static double convertBToThetha(double thetha, ReferenceSystem rs, MathFunc.AngleType angType = MathFunc.AngleType.Radians)
        {
            double phi = 0;

            if (angType == MathFunc.AngleType.Degrees)
            {
                phi = deg2rad(90d - thetha);
            }
            else
            {
                phi = Math.PI / 2d - thetha;
            };
            return(Math.Atan(Math.Tan(phi) * (1d - rs.firstExcentricity_2)));
        }
 /// <summary>
 /// Конструктор для створення об'єкту ReferenceSystem з параметрами за замовчуванням
 /// </summary>
 public ReferenceSystem(ReferenceSystem.Default defaulParams, double satelliteSphere=6500000)
 {
     //Система "вільна від припливних чинників"
     //http://earth-info.nga.mil/GandG/wgs84/gravitymod/egm2008/egm08_wgs84.html
     if (defaulParams == Default.TideFree)
     {
         this.GM = 0.3986004415E+15;
         this.a = 6378136.46;
         this.f = (double)1 / 298.257686;
         this.omega = 7292115E-11;
         this.gridParameters = new Grid(1.6,25);
         this.maxDegree = 90;
         this.satelliteSphere = satelliteSphere;
         mainInit();
     }
     if (defaulParams == Default.ITRF)
     {
         this.GM = 3.986004418E14;
         this.a = 6378136.6;
         this.f = (double)1 / 298.25642;
         this.omega = 7292115E-11;
         this.gridParameters = new Grid(1.6, 25);
         this.maxDegree = 90;
         this.satelliteSphere = satelliteSphere;
         mainInit();
     }
     if (defaulParams == Default.WGS84)
     {
         this.GM = 3986004.418E8;
         this.a = 6378137;
         this.f = (double)1 / 298.257223563;
         this.omega = 7292115E-11;
         this.gridParameters = new Grid(1.6, 25);
         this.maxDegree = 90;
         this.satelliteSphere = satelliteSphere;
         mainInit();
     }
     if (defaulParams == Default.USC2000)
     {
         this.GM = 3.986004418E14;
         this.a = 6378245;
         this.f = (double)1 / 298.3;
         this.omega = 7292115E-11;
         this.gridParameters = new Grid(1.6, 25);
         this.maxDegree = 90;
         this.satelliteSphere = satelliteSphere;
         mainInit();
     }
 }
Esempio n. 7
0
        /// <summary>
        /// Маштабування моделі для використання з Нормальною Землею "rs"
        /// </summary>
        public GravityModel rescaleModel(ReferenceSystem rs)
        {
            GravityModel output       = new GravityModel(this, rs.a, rs.GM);
            double       rescaleFctor = 1;

            for (int n = 0; n < this.c_coef.Length; n++)
            {
                rescaleFctor = (this.model_GM / rs.GM) * Math.Pow(this.model_a / rs.a, n);
                for (int m = 0; m < this.c_coef[n].Length; m++)
                {
                    output.c_coef[n][m] = this.c_coef[n][m] * rescaleFctor;
                    output.s_coef[n][m] = this.s_coef[n][m] * rescaleFctor;
                }
            }
            return(output);
        }
Esempio n. 8
0
        public static void checkMap(double[][] SGG_data, List<int>[] map, List<double[]> greed, ReferenceSystem el)
        {
            Parallel.For(0, map.Length, (i) =>
              {
                  if (map[i].Count > 0)
                  {
                      foreach (int p in map[i])
                      {
                          double d_phi = greed[i][0] - SGG_data[p][1];
                          double d_lam = greed[i][1] - SGG_data[p][2];
                          if (d_phi > MathFunc.deg2rad(el.gridParameters.cellSize) || d_lam > MathFunc.deg2rad(el.gridParameters.cellSize))
                          {
                              System.Windows.Forms.MessageBox.Show(string.Format("F**k!\r\np{0},l{1}__{2}", MathFunc.rad2deg(d_phi), MathFunc.rad2deg(d_lam),i));
                          }
                      }

                  };
              });
        }
Esempio n. 9
0
        /// <summary>
        /// Визначає, до якої клітинки сітки відноситься кожен результат. Кожен елемент List() відповідає елементу Greed, і є масивом номерів точок з pointsData
        /// </summary>
        /// <param name="rs">Референсна система</param>
        /// <param name="pointsData">Масив точок типу: {radius,coLatitude,Longitude,Gradient}</param>
        /// <param name="greed">Масив з клітинками сітки типу: {{colat,long},{colat,long},{colat,long}...}</param>
        /// <param name="rowCount">Кількість рядків сітки</param>
        /// <param name="colsCount">Кількість стовпчиків сітки</param>
        /// <returns>Повертає масив з номерами точок з масиву pointsData</returns>
        public static List <int>[] getMappingOfPoints(ReferenceSystem rs, double[][] pointsData, double[][] greed, int rowCount, int colsCount, double avgRadius)
        {
            List <int>[] map = new List <int> [greed.Length];
            for (int i = 0; i < map.Length; i++)
            {
                map[i] = new List <int>();
            }
            double cellSize = MathFunc.deg2rad(rs.gridParameters.cellSize);
            double zero     = greed[0][0] - cellSize / 2D;
            double l_zero   = greed[0][1] - cellSize / 2d;

            Parallel.For(0, pointsData.Length, (i) =>
            {
                double fi, lambda, r;
                lock (pointsData)
                {
                    fi = pointsData[i][1]; lambda = pointsData[i][2]; r = pointsData[i][0];
                }
                if (fi >= greed[0][0] && fi <= greed[greed.Length - 1][0] && lambda >= greed[0][1] && lambda <= greed[greed.Length - 1][1] && Math.Abs(r - avgRadius) < 10000d)
                {
                    fi        = fi - (zero);
                    lambda    = lambda - l_zero;
                    int n     = (int)Math.Floor(fi / cellSize);
                    int m     = (int)Math.Floor(lambda / cellSize);
                    int index = (colsCount * n) + m;
                    lock (map)
                    {
                        var x1 = cellSize / 2D - Math.Abs(greed[index][0] - zero - fi);
                        var x2 = cellSize / 2D - Math.Abs(greed[index][1] - l_zero - lambda);
                        if (x1 < 0 || x2 < 0)
                        {
                            System.Windows.Forms.MessageBox.Show("getMappingOfPoints: неправильна визначена клітинка точки " + i.ToString());
                        }
                        else
                        {
                            map[index].Add(i);
                        }
                    }
                }
                ;
            });
            return(map);
        }
Esempio n. 10
0
        /// <summary>
        /// Генерує об'єкт GravityModel з коефіцієнтами Нормальної Землі "rs"
        /// </summary>
        public static GravityModel getNormalModel(ReferenceSystem rs, int maxDegree = 8)
        {
            double[]     m  = generateNormalModel(rs, maxDegree);
            GravityModel gm = new GravityModel(maxDegree);

            gm.model_a  = rs.a;
            gm.model_GM = rs.GM;
            for (int i = 0; i < m.Length; i++)
            {
                gm.c_coef[i]    = new double[i + 1];
                gm.s_coef[i]    = new double[i + 1];
                gm.c_coef[i][0] = m[i];
                i++;
                if (i < gm.c_coef.Length)
                {
                    gm.c_coef[i] = new double[i + 1];
                    gm.s_coef[i] = new double[i + 1];
                }
            }
            return(gm);
        }
Esempio n. 11
0
        /// <summary>
        /// Обчислює масив з коефіцієнтами рядка в матриці
        /// </summary>
        /// <param name="rs">Еліпсоїд</param>
        /// <param name="n">Порядок розвинення</param>
        /// <param name="r">Радіус сфери, до якої віднесені виміри</param>
        /// <param name="coLatitude">Полярний кут tetha = 90deg-phi</param>
        /// <param name="longitude">Довгота</param>
        /// <param name="angType">Одиниці, в яких задано попередні кути</param>
        /// <returns></returns>
        public static double[] getCoefMatrixLine(ReferenceSystem rs, int n, int[][] t_nm, double r, double coLatitude, double longitude, MathFunc.AngleType angType = AngleType.Radians)
        {
            if (angType == AngleType.Degrees)
            {
                deg2rad(ref longitude);
            }
            double[] line = new double[(getArraySize(n) - 3) * 2 - (rs.maxDegree - 1)];
            double   u_1  = rs.GM / (Math.Pow(rs.a, 3d));

            double[] legPol = null;
            getLegendre(n, coLatitude, out legPol, angType);
            double tmp_n     = 0;
            double tmp_m     = 0;
            int    lineIndex = 0;

            for (int i = 0; i <= legPol.Length; i++)
            {
                if (i < 4)
                {
                    continue;
                }
                tmp_n = t_nm[i - 1][0];
                tmp_m = t_nm[i - 1][1];
                double b  = legPol[getArraySize(t_nm[i - 1][0] - 1) + t_nm[i - 1][0] - t_nm[i - 1][1]];
                double a  = (tmp_n + 1D) * (tmp_n + 2D) * Math.Pow(rs.a / rs.satelliteSphere, (double)tmp_n + 3d) * u_1;
                double a1 = a * Math.Cos(tmp_m * longitude);
                line[lineIndex] = a1 * b;
                if (tmp_m > 0)
                {
                    double a2 = a * Math.Sin(tmp_m * longitude);
                    line[lineIndex + 1] = a2 * b;
                    lineIndex          += 2;
                }
                else
                {
                    lineIndex++;
                }
            }
            return(line);
        }
Esempio n. 12
0
        /// <summary>
        /// Обчислення градієнту V_zz для заданих координат по моделі "in_model"
        /// </summary>
        public static double getGradient(ReferenceSystem rs, GravityModel in_model, double coLat, double longit, MathFunc.AngleType angType = MathFunc.AngleType.Radians)
        {
            GravityModel gm;

            if (in_model.model_a != rs.a || in_model.model_GM != rs.GM)
            {
                gm = in_model.rescaleModel(rs);
            }
            else
            {
                gm = new GravityModel(in_model);
            };
            if (angType == MathFunc.AngleType.Degrees)
            {
                MathFunc.deg2rad(ref longit);
            }
            double grad = 0;
            double tmp = 0, sum_tmp = 0, sum_tmp_2 = 0;

            double[] legendrePolynoms = null;
            MathFunc.getLegendre(rs.maxDegree, coLat, out legendrePolynoms, angType);
            for (int i = 0; i <= rs.maxDegree; i++)
            {
                int n = MathFunc.getArraySize(i - 1) - 1;
                sum_tmp_2 = 0;
                sum_tmp   = (i + 1) * (i + 2) * Math.Pow(rs.a / rs.satelliteSphere, i + 3);
                for (int m = 0; m < gm.c_coef[i].Length; m++)
                {
                    double a1 = legendrePolynoms[n + m + 1], a2 = gm.c_coef[i][m] * Math.Cos(m * longit), a3 = gm.s_coef[i][m] * Math.Sin(m * longit);
                    double x = a1 * (a2 + a3);
                    sum_tmp_2 += x;
                }
                tmp += sum_tmp * sum_tmp_2;
            }
            grad = rs.GM / Math.Pow(rs.a, 3D) * tmp;
            return(grad);
        }
Esempio n. 13
0
        /// <summary>
        /// Обчислення градієнту V_zz для сітки "grid"
        /// </summary>
        public double[] getGradientForGrid(ReferenceSystem rs, List <double[]> grid)
        {
            GravityModel gm;

            if (this.model_a != rs.a || this.model_GM != rs.GM)
            {
                gm = this.rescaleModel(rs);
            }
            else
            {
                gm = this;
            };
            double[] Gradients = new double[grid.Count];
            int      progress  = 0;

            Parallel.For(0, grid.Count, (i) =>
            {
                lock (Gradients){
                    Gradients[i] = getGradient(rs, gm, grid[i][0], grid[i][1]);
                    progress++;
                }
            });
            return(Gradients);
        }
Esempio n. 14
0
 public static void writeModeVectorlToTxtFile(MathNet.Numerics.LinearAlgebra.Double.DenseVector dm, ReferenceSystem rs, string file)
 {
     System.IO.File.WriteAllText(file, matrixToString((MathNet.Numerics.LinearAlgebra.Double.DenseMatrix)dm.ToColumnMatrix(), rs), System.Text.Encoding.Default);
 }
Esempio n. 15
0
        public static double[][] getGeoidHeightAndAnomalys(ReferenceSystem rs, GravityModel model, List <double[]> grid, System.Threading.CancellationToken ct, System.Threading.CancellationToken ct2, NormalGammaFormula gamma_0_formula = NormalGammaFormula.Somigliana, MainForm.setProgressDel d = null)
        {
            GravityModel gm;

            if (model.model_a != rs.a || model.model_GM != rs.GM)
            {
                gm = new GravityModel(model.rescaleModel(rs), rs.a, rs.GM);
            }
            else
            {
                gm = new GravityModel(model, model.model_a, model.model_GM);
            };
            gm = getDisturbingModel(rs, gm);
            double[]        heights = new double[grid.Count];
            double[]        anomaly = new double[grid.Count];
            int[][]         t_nm = MathFunc.get_nm(gm.maxDegree);
            double[]        legendrePolys_old = null; double point_old = double.MinValue; object locker = new object(), locker2 = new object();
            int             position = 0;
            int             count = grid.Count, position_p = (rs.maxDegree < 150)?(int)Math.Round(0.01d * count):5;
            ParallelOptions po = new ParallelOptions();

            po.MaxDegreeOfParallelism = Environment.ProcessorCount;
            po.CancellationToken      = ct;
            try
            {
                Parallel.For(0, grid.Count, po, (pointIndex) =>
                {
                    Label1: if (ct2.IsCancellationRequested)
                    {
                        System.Threading.Thread.Sleep(1000);
                    }
                    else
                    {
                        goto label2;
                    }
                    goto Label1;
                    label2:    double gamma_0 = 0, B = 0, r = 0;
                    double[] legendrePolys    = null;
                    double[] point            = grid[pointIndex];
                    lock (locker2)
                    {
                        if (point_old != double.MinValue)
                        {
                            if (point[0] == point_old)
                            {
                                legendrePolys = new double[legendrePolys_old.Length];
                                legendrePolys_old.CopyTo(legendrePolys, 0);
                            }
                            MathFunc.getLegendre(rs.maxDegree, point[0], out legendrePolys);
                            legendrePolys_old = new double[legendrePolys.Length];
                            legendrePolys.CopyTo(legendrePolys_old, 0);
                            point_old = point[0];
                        }
                        else
                        {
                            MathFunc.getLegendre(rs.maxDegree, point[0], out legendrePolys);
                            legendrePolys_old = new double[legendrePolys.Length];
                            legendrePolys.CopyTo(legendrePolys_old, 0);
                            point_old = point[0];
                        }
                    }
                    B = MathFunc.convertThethaToB(point[0], rs);
                    r = MathFunc.getGeocentrDistanceToPointOnElips(rs, B);
                    if (gamma_0_formula == NormalGammaFormula.Somigliana)
                    {
                        gamma_0 = rs.gamma_a * (1d + rs.k * Math.Pow(Math.Sin(B), 2d)) / Math.Sqrt(1d - rs.firstExcentricity_2 * Math.Pow(Math.Sin(B), 2d));
                    }
                    else
                    {
                        gamma_0 = 9.78030d * (1d + 0.005302 * Math.Pow(Math.Sin(B), 2d) - 0.000007 * Math.Pow(Math.Sin(2d * B), 2d));
                    }
                    double a1, a2_x = rs.a / r, a2_t, a3, cosMlambda, sinMlambda, a1_a, a2_a = 0, a2 = 0, a2_x_m = a2_x;
                    a1     = rs.GM / (r * gamma_0);
                    a1_a   = rs.GM / (r * r);
                    int az = 0;
                    for (int n = 0; n < rs.maxDegree; n++)
                    {
                        int x = (n == 0) ? 0 : -1;
                        a3    = 0;
                        az   += (n - 1) + 1;
                        for (int m = 0; m <= n; m++)
                        {
                            cosMlambda = Math.Cos(m * point[1]);
                            sinMlambda = Math.Sin(m * point[1]);
                            a3        += (gm.c_coef[n][m] * cosMlambda + gm.s_coef[n][m] * sinMlambda) * legendrePolys[az + (n - m)];
                        }
                        if (n > 1)
                        {
                            a2_x *= a2_x_m; a2_t = a2_x;
                        }
                        else
                        {
                            a2_t = Math.Pow(a2_x, n);
                        };
                        a2   += a2_t * a3;
                        a2_a += a2_t * (n - 1) * a3;
                    }

                    double tmp_h = a1 * a2, tmp_a = a1_a * a2_a * 1e5;
                    lock (heights)
                    { heights[pointIndex] = tmp_h; }
                    lock (anomaly)
                    { anomaly[pointIndex] = tmp_a; }
                    if (d != null)
                    {
                        position++;
                        if (position > position_p)
                        {
                            lock (locker) { position_p += position_p; }; d.Invoke(position, count, "Обчислено висоти для точок: ");
                        }
                        ;
                        if (position >= count)
                        {
                            d.Invoke(0, 1, "");
                        }
                        ;
                    }
                });
            }
            catch (OperationCanceledException)
            {
                return(new double[2][]);
            }
            return(new double[][] { heights, anomaly });
        }
Esempio n. 16
0
 /// <summary>
 /// Генерує об'єкт GravityModel з коефіцієнтами Нормальної Землі "rs"
 /// </summary>
 public static GravityModel getNormalModel(ReferenceSystem rs, int maxDegree = 8)
 {
     double[] m = generateNormalModel(rs, maxDegree);
     GravityModel gm = new GravityModel(maxDegree);
     gm.model_a = rs.a;
     gm.model_GM = rs.GM;
     for (int i = 0; i < m.Length; i ++)
     {
         gm.c_coef[i]=new double[i+1];
         gm.s_coef[i] = new double[i + 1];
         gm.c_coef[i][0] = m[i];
         i++;
         if (i < gm.c_coef.Length)
         {
             gm.c_coef[i] = new double[i + 1];
             gm.s_coef[i] = new double[i + 1];
         }}
     return gm;
 }
Esempio n. 17
0
 public static void writeModeVectorlToTxtFile(MathNet.Numerics.LinearAlgebra.Double.DenseVector dm, ReferenceSystem rs, string file)
 {
     System.IO.File.WriteAllText(file, matrixToString((MathNet.Numerics.LinearAlgebra.Double.DenseMatrix)dm.ToColumnMatrix(), rs), System.Text.Encoding.Default);
 }
Esempio n. 18
0
 private void обчисленняЗаВихідноюМоделлюToolStripMenuItem_Click(object sender, EventArgs e)
 {
     tabControl1.SelectedTab = tabControl1.TabPages[1];
     this.Refresh();
     var task = Task.Factory.StartNew(() => {
         addText("Обчислення розпочато...\r\n");
         string file = SphericalHarmonicAnalyze.Properties.Settings.Default.inGravityModel;
     GravityModel gm = new GravityModel(SphericalHarmonicAnalyze.Properties.Settings.Default.modelMaxOrder);
     gm.loadFromFile(SphericalHarmonicAnalyze.Properties.Settings.Default.inGravityModel, new setProgressDel(addVal));
     ReferenceSystem elipsoid = new ReferenceSystem(ReferenceSystem.Default.WGS84);
     elipsoid.gridParameters.cellSize = SphericalHarmonicAnalyze.Properties.Settings.Default.GridCellSize;
     elipsoid.gridParameters.coLatitudeBounds = SphericalHarmonicAnalyze.Properties.Settings.Default.minCoLatitude;
     elipsoid.maxDegree = SphericalHarmonicAnalyze.Properties.Settings.Default.modelMaxOrder;
     int greedColumnsCount, greedRowsCount;
     List<double[]> greed = MathFunc.generateGrid(elipsoid.gridParameters.cellSize, out greedColumnsCount, out greedRowsCount, elipsoid.gridParameters.coLatitudeBounds);
     double[] h = GravityModel.getGeoidHeight(elipsoid, gm, greed);
     double[] dg = GravityModel.getAnomaly(elipsoid, gm, greed);
     IOFunc.writeGeoidHeightsAndAnomalysToTxt(greed, h, dg, elipsoid, file + "B_L_N_dg.txt");
     addText("Готово...\r\nРезультати записано в файл: " + file + "B_L_N_dg.txt");
     });
 }
Esempio n. 19
0
        /// <summary>
        /// Обчислює масив з коефіцієнтами рядка в матриці
        /// </summary>
        /// <param name="rs">Еліпсоїд</param>
        /// <param name="n">Порядок розвинення</param>
        /// <param name="r">Радіус сфери, до якої віднесені виміри</param>
        /// <param name="coLatitude">Полярний кут tetha = 90deg-phi</param>
        /// <param name="longitude">Довгота</param>
        /// <param name="angType">Одиниці, в яких задано попередні кути</param>
        /// <returns></returns>
        public static double[] getCoefMatrixLine(ReferenceSystem rs, int n, int[][] t_nm, double r, double coLatitude, double longitude, MathFunc.AngleType angType = AngleType.Radians)
        {
            if (angType == AngleType.Degrees) { deg2rad(ref longitude); }
            double[] line = new double[(getArraySize(n) - 3) * 2-(rs.maxDegree-1)];
            double u_1 = rs.GM / (Math.Pow(rs.a, 3d));
            double[] legPol = null;
            getLegendre(n, coLatitude, out legPol, angType);
            double tmp_n = 0;
            double tmp_m = 0;
            int lineIndex = 0;
            for (int i = 0; i <= legPol.Length; i++)
            {
                if (i < 4) { continue; }
                tmp_n = t_nm[i-1][0];
                tmp_m = t_nm[i-1][1];
                double b = legPol[getArraySize(t_nm[i - 1][0] - 1) + t_nm[i - 1][0] - t_nm[i - 1][1]];
                double a = (tmp_n + 1D) * (tmp_n + 2D) * Math.Pow(rs.a / rs.satelliteSphere, (double)tmp_n + 3d)*u_1;
                double a1 = a * Math.Cos(tmp_m * longitude);
                line[lineIndex] = a1 * b;
                if (tmp_m > 0)
                {
                    double a2 = a * Math.Sin(tmp_m * longitude);
                    line[lineIndex + 1] = a2 * b;
                    lineIndex += 2;
                }
                else {
                    lineIndex++;
                }

            }
            return line;
        }
Esempio n. 20
0
 //Формування рядка матриці коефіцієнтів рівнянь поправок
 public static double[] getCoefMatrixLineKoop(ReferenceSystem rs, int n, int[][] t_nm, double r, double coLatitude, double longitude, MathFunc.AngleType angType = AngleType.Radians)
 {
     if (angType == AngleType.Degrees) { deg2rad(ref longitude); }
     List<double> line = new List<double>((getArraySize(n) - 3) * 2 - (rs.maxDegree - 1));
     double[][] legPol = getLegendreP_lm_cos_phi(n, Math.PI / 2d - coLatitude);
     double u_1 = rs.GM / Math.Pow(rs.a, 3d), u_2 = rs.a / rs.satelliteSphere;
     for (int l = 2; l <= rs.maxDegree; l++)
     {
         double u_3 = u_1 * Math.Pow(u_2, l + 3)*(l+1)*(l+2);
         for (int m = 0; m <= l; m++)
         {
                 line.Add(u_3 * legPol[l][m] * Math.Cos((double)m * longitude));
             if (m != 0) {
                 line.Add(u_3 * legPol[l][m] * Math.Sin((double)m * longitude));
             }
         }
     }
     return line.ToArray();
 }
Esempio n. 21
0
 public static double getGeocentrDistanceToPointOnElips(ReferenceSystem rs, double B)
 {
     return (rs.a * Math.Sqrt((1d - rs.firstExcentricity_2) / (1d - Math.Pow(Math.Sqrt(rs.firstExcentricity_2) * Math.Sin(B), 2d))));
 }
Esempio n. 22
0
        public static string matrixToString(MathNet.Numerics.LinearAlgebra.Double.DenseMatrix dm, ReferenceSystem rs)
        {
            StringBuilder sb    = new StringBuilder();
            int           index = 0;

            for (int i = 0; i < 21; i++)
            {
                sb.AppendLine();
            }
            for (int i = 2; i <= rs.maxDegree; i++)
            {
                for (int j = 0; j <= i; j++)
                {
                    if (j != 0)
                    {
                        sb.AppendLine(string.Format("{0}\t{1}\t{2:0.000000000000e+00}\t{3:0.000000000000e+00}", i, j, dm.Values[index], dm.Values[index + 1]));
                        index += 2;
                    }
                    else
                    {
                        sb.AppendLine(string.Format("{0}\t{1}\t{2:0.000000000000e+00}\t{3:0.000000000000e+00}", i, j, dm.Values[index], 0));
                        index += 1;
                    }
                }
            }
            return(sb.ToString());
        }
Esempio n. 23
0
 /// <summary>
 /// Визначає, до якої клітинки сітки відноситься кожен результат. Кожен елемент List() відповідає елементу Greed, і є масивом номерів точок з pointsData
 /// </summary>
 /// <param name="rs">Референсна система</param>
 /// <param name="pointsData">Масив точок типу: {radius,coLatitude,Longitude,Gradient}</param>
 /// <param name="greed">Масив з клітинками сітки типу: {{colat,long},{colat,long},{colat,long}...}</param>
 /// <param name="rowCount">Кількість рядків сітки</param>
 /// <param name="colsCount">Кількість стовпчиків сітки</param>
 /// <returns>Повертає масив з номерами точок з масиву pointsData</returns>
 public static List<int>[] getMappingOfPoints(ReferenceSystem rs, double[][] pointsData, double[][] greed, int rowCount, int colsCount, double avgRadius)
 {
     List<int>[] map = new List<int>[greed.Length];
     for (int i = 0; i < map.Length; i++)
     {
         map[i] = new List<int>();
     }
     double cellSize = MathFunc.deg2rad(rs.gridParameters.cellSize);
     double zero = greed[0][0] - cellSize / 2D;
     double l_zero = greed[0][1] - cellSize / 2d;
     Parallel.For(0, pointsData.Length, (i) =>
     {
         double fi,lambda,r;
         lock (pointsData)
         {
             fi = pointsData[i][1]; lambda = pointsData[i][2]; r = pointsData[i][0];
         }
         if (fi >= greed[0][0] && fi <= greed[greed.Length-1][0] && lambda >= greed[0][1] && lambda<=greed[greed.Length-1][1] && Math.Abs(r-avgRadius)<10000d)
         {
             fi = fi - (zero);
             lambda = lambda - l_zero;
                 int n = (int)Math.Floor(fi / cellSize);
                 int m = (int)Math.Floor(lambda / cellSize);
                 int index = (colsCount * n) + m;
                 lock (map)
                 {
                     var x1 =cellSize/2D-Math.Abs(greed[index][0]-zero - fi);
                     var x2 = cellSize / 2D - Math.Abs(greed[index][1]-l_zero - lambda);
                     if (x1 < 0 || x2 < 0) { System.Windows.Forms.MessageBox.Show("getMappingOfPoints: неправильна визначена клітинка точки "+ i.ToString()); }
                     else
                     {
                         map[index].Add(i);
                     }
                }
         };
     });
     return map;
 }
Esempio n. 24
0
 public static double convertThethaToB(double thetha, ReferenceSystem rs, MathFunc.AngleType angType = MathFunc.AngleType.Radians)
 {
     double phi = 0;
     if (angType == MathFunc.AngleType.Degrees) { phi = deg2rad(90d - thetha); } else { phi = Math.PI / 2d - thetha; };
     return (Math.Atan(Math.Tan(phi) / (1d - rs.firstExcentricity_2)));
 }
Esempio n. 25
0
 /// <summary>
 /// Обчислення градієнту V_zz для сітки "grid"
 /// </summary>
 public double[] getGradientForGrid(ReferenceSystem rs, List<double[]> grid)
 {
     GravityModel gm;
     if (this.model_a != rs.a || this.model_GM != rs.GM) { gm = this.rescaleModel(rs); } else { gm = this; };
     double[] Gradients = new double[grid.Count];
     int progress = 0;
     Parallel.For(0, grid.Count, (i) =>
     {
     lock (Gradients){
         Gradients[i] = getGradient(rs,gm, grid[i][0], grid[i][1]);
         progress++;
         }
     });
     return Gradients;
 }
Esempio n. 26
0
 //Запис висот геоїда і аномалій для сітки в текстовий файл
 public static void writeGeoidHeightsAndAnomalysToTxt(List <double[]> greed, double[] heights, double[] anomalies, ReferenceSystem rs, string file)
 {
     System.IO.TextWriter w = new System.IO.StreamWriter(file, false);
     for (int i = 0; i < greed.Count; i++)
     {
         w.WriteLine(string.Format("{0} {1} {2,10:0.0000} {3,10:0.0000}", MathFunc.rad2deg(MathFunc.convertThethaToB(greed[i][0], rs)), MathFunc.rad2deg(greed[i][1]), heights[i], anomalies[i]));
     }
     w.Close();
 }
Esempio n. 27
0
        //Обчислення висот геоїда для сітки (в метрах) формула обчислення нормальної сили ваги "gamma_0_formula" (за замовчуванням ф-ла Сомільяни)
        public static double[] getGeoidHeight(ReferenceSystem rs, GravityModel model, List<double[]> grid, NormalGammaFormula gamma_0_formula = NormalGammaFormula.Somigliana, MainForm.setProgressDel d = null)
        {
            GravityModel gm;
            if (model.model_a != rs.a || model.model_GM != rs.GM) { gm = new GravityModel(model.rescaleModel(rs), rs.a, rs.GM); } else { gm = new GravityModel(model, model.model_a, model.model_GM); };
            gm = getDisturbingModel(rs, gm);
            double[] heights = new double[grid.Count];
            int[][] t_nm = MathFunc.get_nm(gm.maxDegree);
            double[] legendrePolys_old = null; double point_old = double.MinValue; object locker = new object(), locker2 = new object();
            int position = 0;
            int count =grid.Count,position_p=(int)Math.Round(0.01d*count);

               Parallel.For(0, grid.Count, (pointIndex) => {
                double gamma_0 = 0, B = 0, r = 0;
                double[] legendrePolys = null;
                double[] point = grid[pointIndex];
                lock (locker2)
                        {
                            if (point_old != double.MinValue)
                            {
                                if (point[0] == point_old)
                                {
                                legendrePolys = new double[legendrePolys_old.Length];
                                legendrePolys_old.CopyTo(legendrePolys, 0);
                                }
                                MathFunc.getLegendre(gm.maxDegree, point[0], out legendrePolys);
                                legendrePolys_old = new double[legendrePolys.Length];
                                legendrePolys.CopyTo(legendrePolys_old, 0);
                                point_old = point[0];
                            }
                            else {
                                MathFunc.getLegendre(gm.maxDegree, point[0], out legendrePolys);
                                legendrePolys_old = new double[legendrePolys.Length];
                                legendrePolys.CopyTo(legendrePolys_old,0);
                                point_old = point[0];
                            }
                        }
                B = MathFunc.convertThethaToB(point[0], rs);
                r=MathFunc.getGeocentrDistanceToPointOnElips(rs,B);
                if (gamma_0_formula == NormalGammaFormula.Somigliana)
                {gamma_0 = rs.gamma_a * (1d + rs.k * Math.Pow(Math.Sin(B), 2d)) / Math.Sqrt(1d - rs.firstExcentricity_2 * Math.Pow(Math.Sin(B), 2d));}
                else { gamma_0 = 9.78030d * (1d + 0.005302 * Math.Pow(Math.Sin(B), 2d) - 0.000007 * Math.Pow(Math.Sin(2d * B), 2d)); }
                double a1, a2=0, a3,cosMlambda,sinMlambda;
                a1 = rs.GM / (r * gamma_0);
                for (int n = 0; n < gm.maxDegree; n++) {
                    a3 = 0;
                    for (int m = 0; m <= n; m++){
                        cosMlambda = Math.Cos(m * point[1]);
                        sinMlambda = Math.Sin(m * point[1]);
                        lock (gm)
                        {a3 += (gm.c_coef[n][m] * cosMlambda + gm.s_coef[n][m] * sinMlambda) * legendrePolys[MathFunc.getArraySize(n - 1) + (n - m)];}
                    }
                    a2 += Math.Pow(rs.a / r, n)*a3;
                }
                lock (heights)
                {heights[pointIndex] = a1 * a2;}
                if (d!=null)
                {
                    position++;
                    if (true || position > position_p) { lock (locker) { position_p += position_p;}; d.Invoke(position,count,"Обчислено висоти для точок: ");};
                    if (position >= count) { d.Invoke(0, 1, ""); };
                }
                });
            return heights;
        }
Esempio n. 28
0
 public static double getGeocentrDistanceToPointOnElips(ReferenceSystem rs, double B)
 {
     return(rs.a * Math.Sqrt((1d - rs.firstExcentricity_2) / (1d - Math.Pow(Math.Sqrt(rs.firstExcentricity_2) * Math.Sin(B), 2d))));
 }
Esempio n. 29
0
 private void button8_Click(object sender, EventArgs e)
 {
     ts2 = new CancellationTokenSource();
     ct2 = ts2.Token;
     ct_p = ts_p.Token;
     tabControl1.SelectedTab = tabControl1.TabPages[1];
     this.Refresh();
     ReferenceSystem.Default def = (ReferenceSystem.Default)listBox1.SelectedItem;
     відмінитиПоточнуОпераціюToolStripMenuItem.Enabled = true;
     var task = Task.Factory.StartNew(() =>
     {
         addText("Обчислення розпочато...\r\n");
         string file = SphericalHarmonicAnalyze.Properties.Settings.Default.inGravityModel;
         GravityModel gm = new GravityModel(SphericalHarmonicAnalyze.Properties.Settings.Default.modelMaxOrder);
         gm.loadFromFile(SphericalHarmonicAnalyze.Properties.Settings.Default.inGravityModel, new setProgressDel(addVal));
         ReferenceSystem elipsoid = new ReferenceSystem(def);
         elipsoid.gridParameters.cellSize = SphericalHarmonicAnalyze.Properties.Settings.Default.GridCellSize;
         elipsoid.gridParameters.coLatitudeBounds = SphericalHarmonicAnalyze.Properties.Settings.Default.minCoLatitude;
         elipsoid.maxDegree = SphericalHarmonicAnalyze.Properties.Settings.Default.modelMaxOrder;
         int greedColumnsCount, greedRowsCount;
         List<double[]> greed = MathFunc.generateGrid(elipsoid.gridParameters.cellSize, out greedColumnsCount, out greedRowsCount, SphericalHarmonicAnalyze.Properties.Settings.Default.minCoLatitude, SphericalHarmonicAnalyze.Properties.Settings.Default.maxCoLatitude, SphericalHarmonicAnalyze.Properties.Settings.Default.longW, SphericalHarmonicAnalyze.Properties.Settings.Default.longE);
         addText("Колонок: {0}\r\n",greed.Count);
         double[][] h_dg = GravityModel.getGeoidHeightAndAnomalys(elipsoid, gm, greed, d: new setProgressDel(addVal),ct: ct2,ct2:ct_p);
         if (ct2.IsCancellationRequested) { addText("Перервано...\r\n"); addVal(0,1,""); Thread.CurrentThread.Abort(); };
         addText("dg обчислено\r\n");
         IOFunc.writeGeoidHeightsAndAnomalysToTxt(greed, h_dg[0], h_dg[1], elipsoid, file + "B_L_N_dg.txt");
         addText("Готово...\r\nРезультати записано в файл: " + file + "NEW____________B_L_N_dg.txt\r\n");
     },ct2);
     var t3 = Task.Factory.StartNew(() => {
         label1:  if (task.IsCompleted)
         {
              if (checkBox1.Checked) { System.Diagnostics.Process.Start("rundll32.exe", "powrprof.dll,SetSuspendState 0,1,0"); };
         }
         else { task.Wait(); goto label1; }
     });
 }
Esempio n. 30
0
 /// <summary>
 /// Маштабування моделі для використання з Нормальною Землею "rs"
 /// </summary>
 public GravityModel rescaleModel(ReferenceSystem rs)
 {
     GravityModel output = new GravityModel(this, rs.a, rs.GM);
     double rescaleFctor = 1;
     for (int n = 0; n < this.c_coef.Length; n++)
     {
         rescaleFctor = (this.model_GM / rs.GM) * Math.Pow(this.model_a / rs.a, n);
         for (int m = 0; m < this.c_coef[n].Length; m++)
         {
             output.c_coef[n][m] = this.c_coef[n][m] * rescaleFctor;
             output.s_coef[n][m] = this.s_coef[n][m] * rescaleFctor;
         }
     }
     return output;
 }
Esempio n. 31
0
        private void button4_Click(object sender, EventArgs e)
        {
            Action fileProc = () =>
            {
                System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                MathNet.Numerics.Control.LinearAlgebraProvider = new MathNet.Numerics.Algorithms.LinearAlgebra.Mkl.MklLinearAlgebraProvider();
                MathNet.Numerics.Control.NumberOfParallelWorkerThreads = Environment.ProcessorCount;
                addText("Обробка файлу вимірювань...\r\n");
                double[][] SGG_data = null;
                if (System.IO.File.Exists("sgg_data.bin"))
                {
                    SGG_data = IOFunc.binLoad_SGG_data("sgg_data.bin");
                }
                else
                {
                    SGG_data = Data.IOFunc.read_SGG_data(SphericalHarmonicAnalyze.Properties.Settings.Default.SGG_measures, new setProgressDel(addVal));
                    IOFunc.binwrite_SGG_data("sgg_data.bin", SGG_data);
                }
                addText("Дані вимірювань оброблено: {0} шт.\r\n", SGG_data.Length); Thread.Sleep(500);
                ReferenceSystem elipsoid = new ReferenceSystem(ReferenceSystem.Default.TideFree);
                elipsoid.gridParameters.cellSize = SphericalHarmonicAnalyze.Properties.Settings.Default.GridCellSize;
                elipsoid.gridParameters.coLatitudeBounds = SphericalHarmonicAnalyze.Properties.Settings.Default.minCoLatitude;
                elipsoid.maxDegree = SphericalHarmonicAnalyze.Properties.Settings.Default.modelMaxOrder;
                int greedColumnsCount, greedRowsCount;
                List<double[]> greed = MathFunc.generateGrid(elipsoid.gridParameters.cellSize, out greedColumnsCount, out greedRowsCount, elipsoid.gridParameters.coLatitudeBounds,180 - elipsoid.gridParameters.coLatitudeBounds);
                addText("Сітку згенеровано: {0} комірок \r\n", greed.Count);
                double avgR = MathFunc.getAvgRadius(SGG_data);
                List<int>[] map = MathFunc.getMappingOfPoints(elipsoid, SGG_data, greed.ToArray(), greedRowsCount, greedColumnsCount, avgR); sw.Stop(); addText("Точки віднесено до комірок сітки за: {0}.\r\n", sw.Elapsed.ToString());
                addText("Кількість клітинок сітки всього: {0}\r\n", greed.Count);
                int res1 = 0; foreach (var item in map) { res1 += item.Count; } addText("Використано вимірів: {0}\r\nСер радіус: {1}\r\n", res1, avgR);
                test.checkMap(SGG_data, map, greed, elipsoid);
                List<int>[] newMap = null;
                MathFunc.checkGreed(ref greed, map, out newMap);
                addText("Кількість клітинок сітки, в яких присутні дані вимірювань: {0}\r\n", greed.Count);
                map = newMap; newMap = null;
                IOFunc.writeGreedToCsvFileWithMeasureCount(greed, map, "greed_new_map.txt");
                double[] avgRadius; sw.Restart();
                double[] regularisedValues = MathFunc.regularization(SGG_data, greed.ToArray(), map, out avgRadius); sw.Stop(); addText("Регуляризація (на основі сферичної відстані) виконана за: {0}.\r\n", sw.Elapsed.ToString());
                IOFunc.writeGreedToCsvFileWithMeasureS(greed,regularisedValues, "greed_regular_grad.txt");
                avgRadius[0] = Math.Round(avgRadius[0]);
                elipsoid.satelliteSphere = avgRadius[0];
                addText("Середній радіус: {0,10:0.000}.\r\nМінімальний радіус: {1,10:0.0000}\r\nМаксимальний радіус:{2,10:0.0000}\r\n", avgRadius[0], avgRadius[1], avgRadius[2]);
                SGG_data = null; map = null;
                int[][] t_nm = MathFunc.get_nm(elipsoid.maxDegree);
                sw.Restart();
                MathNet.Numerics.LinearAlgebra.Double.DenseMatrix dm = new MathNet.Numerics.LinearAlgebra.Double.DenseMatrix(greed.Count, (MathFunc.getArraySize(elipsoid.maxDegree) - 3) * 2 - (elipsoid.maxDegree-1));
                sw.Stop(); addText("Пам'ять для матриці коефіцієнтів виділено за: {0}.\r\n", sw.Elapsed.ToString());
                sw.Restart();
                int progress = 0;
                //Обчислення елементів матриці
                var p= Parallel.For(0, dm.RowCount, (i) =>
                {
                    double[] line = MathFunc.getCoefMatrixLineKoop(elipsoid, elipsoid.maxDegree, t_nm, elipsoid.satelliteSphere, greed[i][0], greed[i][1]);
                    lock (dm)
                    {
                         dm.SetRow(i,line);

                    }
                    progress++;
                    if (progress / 100D == Math.Round(progress / 100D)) {addVal(progress, dm.RowCount, "Визначено");}
                });

                if (!p.IsCompleted) { throw new Exception("Parallel.For"); };
                IOFunc.writeMatrixToMatLabFile(dm, @"matlab\A.mat","A");
                sw.Stop();
                richTextBox1.Invoke(new setProgressDel(addVal), new object[] { 0, dm.RowCount, "" });
                addText("Матриця {0} на {1} ({2}MB) згенерована за: {3,10}\r\n", dm.RowCount, dm.ColumnCount, dm.ColumnCount * dm.RowCount * 8 / 1000000,sw.Elapsed.ToString()/* + "\r\nЗапис у файл...\r\n"*/);
                if(true){
                GravityModel gm08 = new GravityModel(elipsoid.maxDegree);
                gm08.loadFromFile("GO_CONS_EGM_GCF_2.gfc", new setProgressDel(addVal));
                MathNet.Numerics.LinearAlgebra.Double.DenseVector dmL = new MathNet.Numerics.LinearAlgebra.Double.DenseVector(gm08.getGradientForGrid(elipsoid,greed));//regularisedValues);
                MathNet.Numerics.LinearAlgebra.Double.DenseVector dmL2;
                GravityModel gm = new GravityModel(elipsoid.maxDegree);
                    if (radioButton1.Checked) {
                    sw.Restart();
                    gm.loadFromFile(SphericalHarmonicAnalyze.Properties.Settings.Default.inGravityModel, new setProgressDel(addVal));
                    sw.Stop(); addText("Вихідна модель завантажена за: {0}.\r\n", sw.Elapsed.ToString());
                    sw.Restart();
                    dmL2 = new MathNet.Numerics.LinearAlgebra.Double.DenseVector(gm.getGradientForGrid(elipsoid,greed));
                    sw.Stop(); addText("Градієнти за вихідною моделлю обчислені для сітки за: {0}.\r\n", sw.Elapsed.ToString());
                }
                else
                {
                    sw.Restart();
                    gm = GravityModel.getNormalModel(elipsoid, elipsoid.maxDegree);
                    dmL2 = new MathNet.Numerics.LinearAlgebra.Double.DenseVector(gm.getGradientForGrid(elipsoid, greed));
                    sw.Stop(); addText("Нормальні градієнти обчислені для сітки за: {0}.\r\n", sw.Elapsed.ToString());
                }
                dmL = dmL - dmL2;
                dmL2 = null;
                IOFunc.writeMatrixToMatLabFile(dmL.ToColumnMatrix(), @"matlab\L.mat", "L");
                    sw.Restart();
                MathNet.Numerics.LinearAlgebra.Double.DenseVector dmLNormal = null;
                dmLNormal = (MathNet.Numerics.LinearAlgebra.Double.DenseVector)dm.TransposeThisAndMultiply(dmL);
                dmL = null;
                IOFunc.writeMatrixToMatLabFile(dmLNormal.ToColumnMatrix(), @"matlab\LNorm.mat", "LNorm");
                sw.Stop(); addText("Стовпчик вільних членів обчислений за: {0}.\r\n", sw.Elapsed.ToString());
                MathNet.Numerics.LinearAlgebra.Double.DenseMatrix dmANorm = null;
                sw.Restart();
                dmANorm = (MathNet.Numerics.LinearAlgebra.Double.DenseMatrix)dm.TransposeThisAndMultiply(dm); dm = null;
                sw.Stop(); addText("Нормальна матриця коефіціэнтів обчислена за: {0}.\r\n", sw.Elapsed.ToString());
                IOFunc.writeMatrixToMatLabFile(dmANorm, @"matlab\ANorm.mat", "ANorm");
                //dmLNormal = (MathNet.Numerics.LinearAlgebra.Double.DenseVector)dmLNormal.Multiply(5e-8);
                var x = dmANorm.Inverse();
                var res = (MathNet.Numerics.LinearAlgebra.Double.DenseVector)x.Multiply(dmLNormal);
                IOFunc.writeModeVectorlToTxtFile(res, elipsoid, @"matlab\_out.AL");
                addText(@"Результат за методом A\L знайдено...");
                x = null;
                GravityModel gm_R = new GravityModel(gm);
                gm_R.addDeltaCoef(res.ToArray()); res = null;
                double[] h = GravityModel.getGeoidHeight(elipsoid, gm_R, greed);
                double[] dg = GravityModel.getAnomaly(elipsoid, gm_R, greed);
                IOFunc.writeGeoidHeightsAndAnomalysToTxt(greed, h, dg, elipsoid, @"output\result_AL.txt");
                IOFunc.writeGravityModelToTxtFile(gm_R, @"output\model_AL.gcf");
                sw.Restart();
                addText(dmANorm.Rank().ToString() + "\r\n");
                dmANorm = null;
                dmLNormal = null;
                sw.Stop(); addText("Невідомі знайдено за: {0}.\r\n", sw.Elapsed.ToString());

            }
            };

            if (System.IO.File.Exists(SphericalHarmonicAnalyze.Properties.Settings.Default.inGravityModel)) {
            tabControl1.SelectedTab = tabControl1.TabPages[1];
            this.UseWaitCursor = true;
            ts = new CancellationTokenSource();
            ct = ts.Token;
            tsk = Task.Factory.StartNew(fileProc,ct);
            var setCur = Task.Factory.StartNew(() => { tsk.Wait(); this.UseWaitCursor = false; addText("Обчислення завершені!"); });
            richTextBox1.SaveFile(@"output\zvit.rtf");
            }
        }
Esempio n. 32
0
        public static double[][] getGeoidHeightAndAnomalys(ReferenceSystem rs, GravityModel model, List<double[]> grid, System.Threading.CancellationToken ct,System.Threading.CancellationToken ct2, NormalGammaFormula gamma_0_formula = NormalGammaFormula.Somigliana, MainForm.setProgressDel d = null)
        {
            GravityModel gm;
            if (model.model_a != rs.a || model.model_GM != rs.GM) { gm = new GravityModel(model.rescaleModel(rs), rs.a, rs.GM); } else { gm = new GravityModel(model, model.model_a, model.model_GM); };
            gm = getDisturbingModel(rs, gm);
            double[] heights = new double[grid.Count];
            double[] anomaly = new double[grid.Count];
            int[][] t_nm = MathFunc.get_nm(gm.maxDegree);
            double[] legendrePolys_old = null; double point_old = double.MinValue; object locker = new object(), locker2 = new object();
            int position = 0;
            int count = grid.Count, position_p = (rs.maxDegree<150)?(int)Math.Round(0.01d * count):5;
            ParallelOptions po = new ParallelOptions();
            po.MaxDegreeOfParallelism = Environment.ProcessorCount;
            po.CancellationToken = ct;
            try
                {
            Parallel.For(0, grid.Count,po, (pointIndex) =>
            {
            Label1: if (ct2.IsCancellationRequested) { System.Threading.Thread.Sleep(1000); } else { goto label2; }
            goto Label1;
                label2:    double gamma_0 = 0, B = 0, r = 0;
                double[] legendrePolys = null;
                double[] point = grid[pointIndex];
                lock (locker2)
                {
                    if (point_old != double.MinValue)
                    {
                        if (point[0] == point_old)
                        {
                            legendrePolys = new double[legendrePolys_old.Length];
                            legendrePolys_old.CopyTo(legendrePolys, 0);
                        }
                        MathFunc.getLegendre(rs.maxDegree, point[0], out legendrePolys);
                        legendrePolys_old = new double[legendrePolys.Length];
                        legendrePolys.CopyTo(legendrePolys_old, 0);
                        point_old = point[0];
                    }
                    else
                    {
                        MathFunc.getLegendre(rs.maxDegree, point[0], out legendrePolys);
                        legendrePolys_old = new double[legendrePolys.Length];
                        legendrePolys.CopyTo(legendrePolys_old, 0);
                        point_old = point[0];
                    }
                }
                B = MathFunc.convertThethaToB(point[0], rs);
                r = MathFunc.getGeocentrDistanceToPointOnElips(rs, B);
                if (gamma_0_formula == NormalGammaFormula.Somigliana)
                { gamma_0 = rs.gamma_a * (1d + rs.k * Math.Pow(Math.Sin(B), 2d)) / Math.Sqrt(1d - rs.firstExcentricity_2 * Math.Pow(Math.Sin(B), 2d)); }
                else { gamma_0 = 9.78030d * (1d + 0.005302 * Math.Pow(Math.Sin(B), 2d) - 0.000007 * Math.Pow(Math.Sin(2d * B), 2d)); }
                double a1, a2_x = rs.a / r, a2_t, a3, cosMlambda, sinMlambda, a1_a, a2_a = 0, a2 = 0, a2_x_m = a2_x;
                a1 = rs.GM / (r * gamma_0);
                a1_a = rs.GM / (r * r);
                int az = 0;
                for (int n = 0; n < rs.maxDegree; n++)
                {
                    int x = (n == 0) ? 0 : -1;
                    a3 = 0;
                    az += (n - 1) + 1;
                    for (int m = 0; m <= n; m++)
                    {
                        cosMlambda = Math.Cos(m * point[1]);
                        sinMlambda = Math.Sin(m * point[1]);
                        a3 += (gm.c_coef[n][m] * cosMlambda + gm.s_coef[n][m] * sinMlambda) * legendrePolys[az + (n - m)];
                    }
                    if (n > 1) { a2_x *= a2_x_m; a2_t = a2_x; } else { a2_t = Math.Pow(a2_x, n); };
                    a2 += a2_t * a3;
                    a2_a += a2_t * (n - 1) * a3;
                }

                double tmp_h = a1 * a2, tmp_a = a1_a * a2_a*1e5;
                lock (heights)
                { heights[pointIndex] =tmp_h; }
                lock (anomaly)
                { anomaly[pointIndex] = tmp_a; }
                if (d != null)
                {
                    position++;
                    if  (position > position_p) { lock (locker) { position_p += position_p; }; d.Invoke(position, count, "Обчислено висоти для точок: "); };
                    if (position >= count) { d.Invoke(0, 1, ""); };
                }
            });
                }
            catch (OperationCanceledException)
            {
                return new double[2][];
            }
            return new double[][] { heights, anomaly };
        }
Esempio n. 33
0
 private void toolStripButton2_Click(object sender, EventArgs e)
 {
     ReferenceSystem elipsoid = new ReferenceSystem(ReferenceSystem.Default.WGS84);
     elipsoid.gridParameters.cellSize = 30d;
     elipsoid.gridParameters.coLatitudeBounds = 15D;
     elipsoid.maxDegree = 100;
     double[] gmN = GravityModel.generateNormalModel(elipsoid, 10);
     GravityModel gm = new GravityModel(100);
     gm.loadFromFile(SphericalHarmonicAnalyze.Properties.Settings.Default.inGravityModel, new setProgressDel(addVal));
     int greedColumnsCount, greedRowsCount;
     GravityModel gm2 = new GravityModel(gm);
     List<double[]> greed = MathFunc.generateGrid(elipsoid.gridParameters.cellSize, out greedColumnsCount, out greedRowsCount, elipsoid.gridParameters.coLatitudeBounds);
     double[] h = GravityModel.getGeoidHeight(elipsoid,gm2,greed);
     double[] dg = GravityModel.getAnomaly(elipsoid, gm, greed);
     IOFunc.writeGeoidHeightsAndAnomalysToTxt(greed, h, dg, elipsoid, "result.txt");
 }
Esempio n. 34
0
 //Обчислення коефіцієнтів збурюючого потенціалу відностно Нормальної Землі "rs"
 public static GravityModel getDisturbingModel(ReferenceSystem rs, GravityModel model)
 {
     GravityModel result = new GravityModel(model, model.model_a, model.model_GM);
     double[] normalModel = generateNormalModel(rs,8);
     for (int i = 0; i < normalModel.Length; i+=2)
     {result.c_coef[i][0] = result.c_coef[i][0] - normalModel[i];}
     return result;
 }
Esempio n. 35
0
 //Запис висот геоїда і аномалій для сітки в текстовий файл
 public static void writeGeoidHeightsAndAnomalysToTxt(List<double[]> greed, double[] heights, double[] anomalies,ReferenceSystem rs, string file)
 {
     System.IO.TextWriter w = new System.IO.StreamWriter(file, false);
     for (int i = 0; i < greed.Count; i++)
     {
     w.WriteLine(string.Format("{0} {1} {2,10:0.0000} {3,10:0.0000}",MathFunc.rad2deg(MathFunc.convertThethaToB(greed[i][0], rs)),MathFunc.rad2deg(greed[i][1]), heights[i], anomalies[i]));
     }
     w.Close();
 }
Esempio n. 36
0
        //Обчислення аномалій сили ваги для сітки (в мГал)
        public static double[] getAnomaly(ReferenceSystem rs, GravityModel model, List <double[]> grid, MainForm.setProgressDel d = null)
        {
            GravityModel gm;

            if (model.model_a != rs.a || model.model_GM != rs.GM)
            {
                gm = new GravityModel(model.rescaleModel(rs), rs.a, rs.GM);
            }
            else
            {
                gm = new GravityModel(model, model.model_a, model.model_GM);
            };
            gm = getDisturbingModel(rs, gm);
            double[] heights = new double[grid.Count];
            int[][]  t_nm = MathFunc.get_nm(gm.maxDegree);
            double[] legendrePolys_old = null; double point_old = double.MinValue; object locker = new object(), locker2 = new object();
            int      position = 0;
            int      count = grid.Count, position_p = (int)Math.Round(0.01d * count);

            Parallel.For(0, grid.Count, (pointIndex) =>
            {
                double B = 0, r = 0;
                double[] legendrePolys = null;
                double[] point         = grid[pointIndex];
                lock (locker2)
                {
                    if (point_old != double.MinValue)
                    {
                        if (point[0] == point_old)
                        {
                            legendrePolys = new double[legendrePolys_old.Length];
                            legendrePolys_old.CopyTo(legendrePolys, 0);
                        }
                        MathFunc.getLegendre(gm.maxDegree, point[0], out legendrePolys);
                        legendrePolys_old = new double[legendrePolys.Length];
                        legendrePolys.CopyTo(legendrePolys_old, 0);
                        point_old = point[0];
                    }
                    else
                    {
                        MathFunc.getLegendre(gm.maxDegree, point[0], out legendrePolys);
                        legendrePolys_old = new double[legendrePolys.Length];
                        legendrePolys.CopyTo(legendrePolys_old, 0);
                        point_old = point[0];
                    }
                }
                B             = MathFunc.convertThethaToB(point[0], rs);
                r             = MathFunc.getGeocentrDistanceToPointOnElips(rs, B);
                double a1, a2 = 0, a3, cosMlambda, sinMlambda;
                a1            = rs.GM / (r * r);
                for (int n = 0; n < gm.maxDegree; n++)
                {
                    a3 = 0;
                    for (int m = 0; m <= n; m++)
                    {
                        cosMlambda = Math.Cos(m * point[1]);
                        sinMlambda = Math.Sin(m * point[1]);
                        lock (gm)
                        { a3 += (gm.c_coef[n][m] * cosMlambda + gm.s_coef[n][m] * sinMlambda) * legendrePolys[MathFunc.getArraySize(n - 1) + (n - m)]; }
                    }
                    a2 += Math.Pow(rs.a / r, n) * (n - 1) * a3;
                }
                lock (heights)
                { heights[pointIndex] = a1 * a2; }
                if (d != null)
                {
                    position++;
                    if (position > position_p)
                    {
                        lock (locker) { position_p += position_p; }; d.Invoke(position, count, "Обчислено висоти для точок: ");
                    }
                    ;
                    if (position >= count)
                    {
                        d.Invoke(0, 1, "");
                    }
                    ;
                }
            });
            return(heights);
        }
Esempio n. 37
0
 //Метод генерує масив з коефіцієнтами моделі нормального потенціалу [1,0,c_20,0,c_40,0,c_80...c_maxDegree0]
 public static double[] generateNormalModel(ReferenceSystem rs, int maxDegree = 8)
 {
     double[] normalModel = new double[maxDegree + 1];
     normalModel[0] = 1D; double C_2k = 0, k = 0, tmp = 1d - 2d / 15d * (rs.m_gamma * Math.Sqrt(rs.secondExcentricity_2)) / rs.q0;
     for (int i = 2; i <= maxDegree; i += 2)
     {
         k = i / 2;
         C_2k = Math.Pow(-1d, k) * 3d * Math.Pow(rs.firstExcentricity_2, k) / ((2d * k + 1d) * (2d * k + 3d)) * (1d - k + 5d * k / 3d * tmp) / Math.Sqrt(2d * i + 1d);
         normalModel[i - 1] = 0D;
         normalModel[i] = C_2k;
     }
     return normalModel;
 }
Esempio n. 38
0
 /// <summary>
 /// Обчислення градієнту V_zz для заданих координат по моделі "in_model"
 /// </summary>
 public static double getGradient(ReferenceSystem rs,GravityModel in_model, double coLat, double longit, MathFunc.AngleType angType = MathFunc.AngleType.Radians)
 {
     GravityModel gm;
     if (in_model.model_a != rs.a || in_model.model_GM != rs.GM) { gm = in_model.rescaleModel(rs); } else { gm = new GravityModel(in_model); };
     if (angType == MathFunc.AngleType.Degrees) { MathFunc.deg2rad(ref longit); }
     double grad = 0;
     double tmp = 0, sum_tmp = 0, sum_tmp_2 = 0;
     double[] legendrePolynoms = null;
     MathFunc.getLegendre(rs.maxDegree, coLat, out legendrePolynoms, angType);
     for (int i = 0; i <= rs.maxDegree; i++)
     {
         int n = MathFunc.getArraySize(i - 1) - 1;
         sum_tmp_2 = 0;
         sum_tmp = (i + 1) * (i + 2) * Math.Pow(rs.a / rs.satelliteSphere, i + 3);
         for (int m = 0; m < gm.c_coef[i].Length; m++)
         {
             double a1 = legendrePolynoms[n + m + 1], a2 = gm.c_coef[i][m] * Math.Cos(m * longit), a3 = gm.s_coef[i][m] * Math.Sin(m * longit);
             double x = a1 * (a2 + a3);
             sum_tmp_2 += x;
         }
         tmp += sum_tmp * sum_tmp_2;
     }
     grad = rs.GM / Math.Pow(rs.a, 3D) * tmp;
     return grad;
 }