Пример #1
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 });
        }
Пример #2
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 };
        }
Пример #3
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);
        }
Пример #4
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;
        }