示例#1
0
        public void StartMapping(double regPar, double lambdaPole, string pathNNLSDir)
        {
            this.sizePar = lambdaPole;
            double aveFlux   = curves[0].value.Average();
            int    allPhases = 0;

            for (int p = 0; p < this.curves.Length; p++)
            {
                allPhases += this.curves[p].phases.Length;
            }

            int observablePatchesNumber  = this.magSrf.GetNumberOfObservablePatches();
            int observableLatBeltsNumber = this.magSrf.GetNumberOfObservableLatBelts();

            double[][] a = new double[allPhases][];
            for (int i = 0; i < a.Length; i++)
            {
                a[i] = new double[observablePatchesNumber];
            }

            {
                int s = 0;
                for (int q = 0; q < this.curves.Length; q++)
                {
                    for (int p = 0; p < this.curves[q].phases.Length; p++)
                    {
                        int k = 0;

                        double muPole         = this.magSrf.MuOfThePole(this.curves[q].phases[p]);
                        double sinGammaCenter = Math.Sqrt(1 - muPole * muPole);
                        if (sinGammaCenter > 1.0)
                        {
                            sinGammaCenter = 1.0;
                        }
                        if (sinGammaCenter < -1.0)
                        {
                            sinGammaCenter = -1.0;
                        }

                        double cosKhi = this.magSrf.GetCosOmega(this.curves[q].phases[p], muPole);
                        double sinKhi = 0;
                        double eps    = this.magSrf.PhiOfThePole(this.curves[q].phases[p])
                                        - 2 * Math.PI * Math.Floor(this.magSrf.PhiOfThePole(this.curves[q].phases[p]) / (2 * Math.PI));

                        if (eps < Math.PI / 2.0 || eps > 1.5 * Math.PI)
                        {
                            sinKhi = -Math.Sqrt(1 - cosKhi * cosKhi);
                        }
                        else
                        {
                            sinKhi = Math.Sqrt(1 - cosKhi * cosKhi);
                        }

                        for (int i = 0; i < observableLatBeltsNumber; i++)
                        {
                            for (int j = 0; j < this.magSrf.Patches[i].Length; j++)
                            {
                                double mu = magSrf.MuOfThePatchCenter(i, j, muPole, sinGammaCenter, cosKhi, sinKhi);

                                if (mu > 0)
                                {
                                    double area = (this.magSrf.Patches[i][j].Phi20 - this.magSrf.Patches[i][j].Phi10) *
                                                  (Math.Cos(this.magSrf.Patches[i][j].Theta1) - Math.Cos(this.magSrf.Patches[i][j].Theta2));
                                    double cosAlpha = this.magSrf.GetCosAlpha2(i, j, this.curves[q].phases[p]);
                                    double alpha    = Math.Acos(cosAlpha);
                                    double prArea   = area * mu;

                                    double koeff_i, koeff_q, koeff_v, koeff_u;
                                    if (this.curves[q].type == "I")
                                    {
                                        if (alpha > 0.5 * Math.PI)
                                        {
                                            koeff_i = this.stokes_func("I", this.curves[q].filter,
                                                                       this.magSrf.MagneticStrength(i, j) * 1e-6,
                                                                       Math.PI - alpha,
                                                                       this.magSrf.Lambda(i, j, lambdaPole));
                                        }
                                        else
                                        {
                                            koeff_i = this.stokes_func("I", this.curves[q].filter,
                                                                       this.magSrf.MagneticStrength(i, j) * 1e-6,
                                                                       alpha,
                                                                       this.magSrf.Lambda(i, j, lambdaPole));
                                        }
                                        a[s][k] = prArea * koeff_i;
                                    }
                                    if (this.curves[q].type == "V")
                                    {
                                        if (alpha <= Math.PI * 0.5)
                                        {
                                            a[s][k] = prArea * this.stokes_func("V", this.curves[q].filter,
                                                                                this.magSrf.MagneticStrength(i, j) * 1e-6,
                                                                                alpha,
                                                                                this.magSrf.Lambda(i, j, lambdaPole));
                                        }
                                        else
                                        {
                                            a[s][k] = -prArea *this.stokes_func("V", this.curves[q].filter,
                                                                                this.magSrf.MagneticStrength(i, j) * 1e-6,
                                                                                Math.PI - alpha,
                                                                                this.magSrf.Lambda(i, j, lambdaPole));
                                        }
                                    }
                                    if (this.curves[q].type == "Q")
                                    {
                                        double ro     = this.magSrf.GetRo(i, j, this.curves[q].phases[p]);
                                        double alpha1 = alpha;
                                        if (alpha > 0.5 * Math.PI)
                                        {
                                            alpha1 = Math.PI - alpha;
                                        }
                                        a[s][k] = area * Math.Cos(2 * ro) * this.stokes_func("Q", this.curves[q].filter,
                                                                                             this.magSrf.MagneticStrength(i, j),
                                                                                             alpha1,
                                                                                             this.magSrf.Lambda(i, j, lambdaPole));
                                    }
                                    if (this.curves[q].type == "U")
                                    {
                                        double ro     = this.magSrf.GetRo(i, j, this.curves[q].phases[p]);
                                        double alpha1 = alpha;
                                        if (alpha > 0.5 * Math.PI)
                                        {
                                            alpha1 = Math.PI - alpha;
                                        }
                                        a[s][k] = -area *Math.Sin(2 *ro) * this.stokes_func("Q", this.curves[q].filter,
                                                                                            this.magSrf.MagneticStrength(i, j),
                                                                                            alpha1,
                                                                                            this.magSrf.Lambda(i, j, lambdaPole));
                                    }
                                }
                                k++;
                            }
                        }
                        s++;
                    }
                }
            }

            // scaling
            scale_koeff = aveFlux / (Math.PI * this.stokes_func("I", "V",
                                                                this.magSrf.MagneticStrength(0, 0) * 1e-6,
                                                                0.0, lambdaPole));
            for (int i = 0; i < a.Length; i++)
            {
                for (int j = 0; j < a[i].Length; j++)
                {
                    a[i][j] *= scale_koeff;
                }
            }

            double[] f = new double[allPhases];

            {
                int k = 0;
                for (int q = 0; q < this.curves.Length; q++)
                {
                    for (int p = 0; p < this.curves[q].phases.Length; p++)
                    {
                        f[k] = this.curves[q].value[p];
                        k++;
                    }
                }
            }

            double[][] aTa = new double[observablePatchesNumber][];
            for (int i = 0; i < aTa.Length; i++)
            {
                aTa[i] = new double[observablePatchesNumber];
            }

            double[] aTf = new double[observablePatchesNumber];

            double[] x = new double[observablePatchesNumber];

            double[][] aT = new double[observablePatchesNumber][];
            for (int i = 0; i < aT.Length; i++)
            {
                aT[i] = new double[allPhases];
            }

            for (int i = 0; i < aT.Length; i++)
            {
                for (int j = 0; j < aT[i].Length; j++)
                {
                    aT[i][j] = a[j][i];
                }
            }

            MathLib.Basic.ATrA(ref a, ref aTa);

            for (int i = 0; i < aTa.Length; i++)
            {
                aTa[i][i] += regPar;
            }

            MathLib.Basic.AMultB(ref aT, ref f, ref aTf);

            // Preparing input files for NNLS;
            StreamWriter sw = new StreamWriter(pathNNLSDir + "\\nnls_a.dat");

            sw.WriteLine("{0} {1}", a.Length + observablePatchesNumber, observablePatchesNumber);
            for (int i = 0; i < a.Length; i++)
            {
                for (int j = 0; j < a[i].Length; j++)
                {
                    sw.Write(string.Format("{0:0.000000000000000E000} ", a[i][j]).Replace(",", "."));
                }
                sw.Write("\r\n");
            }
            for (int i = 0; i < observablePatchesNumber; i++)
            {
                for (int j = 0; j < observablePatchesNumber; j++)
                {
                    if (i == j)
                    {
                        sw.Write(string.Format("{0:0.000E000} ", Math.Sqrt(regPar)).Replace(",", "."));
                    }
                    else
                    {
                        sw.Write(string.Format("{0:0.000E000} ", 0.0).Replace(",", "."));
                    }
                }
                sw.Write("\r\n");
            }
            sw.Close();

            sw = new StreamWriter(pathNNLSDir + "\\nnls_b.dat");
            sw.WriteLine("{0} {1}", f.Length + observablePatchesNumber, 1);
            for (int i = 0; i < a.Length; i++)
            {
                sw.Write(string.Format("{0:0.000000000000000E000}\r\n", f[i]).Replace(",", "."));
            }
            for (int i = 0; i < observablePatchesNumber; i++)
            {
                sw.Write(string.Format("{0:0.00000E000}\r\n", 0).Replace(",", "."));
            }
            sw.Close();

            // Run NNLS;
            Process pro = new Process();

            pro.StartInfo.FileName         = pathNNLSDir + "\\NNLS.exe";
            pro.StartInfo.WorkingDirectory = pathNNLSDir;
            pro.StartInfo.Arguments        = "d nnls_a.dat nnls_b.dat 5000";
            pro.Start();
            pro.WaitForExit();
            //

            StreamReader sr = new StreamReader(pathNNLSDir + "\\nnls_solution.dat");

            for (int i = 0; i < x.Length; i++)
            {
                x[i] = double.Parse(sr.ReadLine().Replace(".", ","));
            }
            sr.Close();

            //x = MathLib.LES_Solver.SolveWithGaussMethod(aTa, aTf);

            //MathLib.LES_Solver.ConvGradMethodPL(ref aTa, ref aTf, ref x, 1e-20);

            {
                int k = 0;
                for (int i = 0; i < observableLatBeltsNumber; i++)
                {
                    for (int j = 0; j < this.magSrfRes.Patches[i].Length; j++)
                    {
                        this.magSrfRes.SetDensity(i, j, x[k]);
                        k++;
                    }
                }
            }
        }
示例#2
0
        public void StartStokesCurvesModelling(double[] phases, double scale, double poleOptDepth)
        {
            this.stokesI = new double[phases.Length];
            this.stokesQ = new double[phases.Length];
            this.stokesV = new double[phases.Length];
            this.stokesU = new double[phases.Length];

            this.phasesI = phases;
            this.phasesQ = phases;
            this.phasesV = phases;
            this.phasesU = phases;

            //Parallel.For(0, phases.Length, p =>
            for (int p = 0; p < phases.Length; p++)
            {
                double muPole;
                double sinGammaCenter;
                double sinKhi, cosKhi;

                double sumI = 0;
                double sumV = 0;
                double sumQ = 0;
                double sumU = 0;

                muPole = this.magSrf.MuOfThePole(phases[p]);
                sinGammaCenter = Math.Sqrt(1 - muPole * muPole);
                if (sinGammaCenter > 1.0) sinGammaCenter = 1.0;
                if (sinGammaCenter < -1.0) sinGammaCenter = -1.0;

                cosKhi = this.magSrf.GetCosOmega(phases[p], muPole);

                double eps = this.magSrf.PhiOfThePole(phases[p])
                    - 2 * Math.PI * Math.Floor(this.magSrf.PhiOfThePole(phases[p]) / (2 * Math.PI));

                if (eps < 0.5*Math.PI  || eps > 1.5 * Math.PI)
                {
                    sinKhi = -Math.Sqrt(1 - cosKhi * cosKhi);
                }
                else
                {
                    sinKhi = Math.Sqrt(1 - cosKhi * cosKhi);
                }

                for (int i = 0; i < this.magSrf.Patches.Length; i++)
                {
                    // areas of patches in the same belt are equil
                    double area = (this.magSrf.Patches[i][0].Phi20 - this.magSrf.Patches[i][0].Phi10) *
                                (Math.Cos(this.magSrf.Patches[i][0].Theta1) - Math.Cos(this.magSrf.Patches[i][0].Theta2));
                    for (int j = 0; j < this.magSrf.Patches[i].Length; j++)
                    {
                        if (this.magSrf.BrightnessDensity[i][j] != 0)
                        {
                            double mu = magSrf.MuOfThePatchCenter(i, j, muPole, sinGammaCenter, cosKhi, sinKhi);
                            if (mu >= 0)
                            {
                                //double cosAlpha = magSrf.GetCosAlpha(i, j, muPole, sinGammaCenter, cosKhi, sinKhi);
                                double cosAlpha = magSrf.GetCosAlpha2(i, j, phases[p]);
                                double alpha = Math.Acos(cosAlpha);

                                double scale1 = this.magSrf.BrightnessDensity[i][j] * area;
                                //mu = 1; // !!!!!!!!!!!!!!!
                                double ro;

                                ro = this.magSrf.GetRo(i, j, phases[p]);

                                double koeff_i = 0, koeff_v = 0, koeff_q = 0, koeff_u = 0;

                                // Stokes I integration;
                                if (alpha > 0.5 * Math.PI)
                                {
                                    koeff_i = this.stokesI_b_theta_lambda(
                                        this.magSrf.MagneticStrength(i, j) * 1e-6,
                                        Math.PI - alpha,
                                        this.magSrf.Lambda(i, j, poleOptDepth));
                                }
                                else
                                {
                                    koeff_i = this.stokesI_b_theta_lambda(
                                        this.magSrf.MagneticStrength(i, j) * 1e-6,
                                        alpha,
                                        this.magSrf.Lambda(i, j, poleOptDepth));
                                }
                                if (koeff_i < 0)
                                {
                                    koeff_i = 0;
                                }
                                sumI += koeff_i * scale1 * mu;


                                // Stokes V integration;
                                if (alpha > 0.5 * Math.PI)
                                {
                                    koeff_v =  -this.stokesV_b_theta_lambda(
                                         this.magSrf.MagneticStrength(i, j) * 1e-6,
                                         Math.PI - alpha,
                                         this.magSrf.Lambda(i, j, poleOptDepth));
                                }
                                else
                                {
                                    koeff_v = this.stokesV_b_theta_lambda(
                                        this.magSrf.MagneticStrength(i, j) * 1e-6,
                                         alpha,
                                        this.magSrf.Lambda(i, j, poleOptDepth));
                                }
                                sumV += koeff_v * scale1 * mu;

                                // Stokes Q integration;
                                if (alpha > 0.5 * Math.PI)
                                {
                                    koeff_q = this.stokesQ_b_theta_lambda(
                                        this.magSrf.MagneticStrength(i, j) * 1e-6,
                                        Math.PI - alpha,
                                        this.magSrf.Lambda(i, j, poleOptDepth));
                                }
                                else
                                {
                                    koeff_q = this.stokesQ_b_theta_lambda(
                                        this.magSrf.MagneticStrength(i, j) * 1e-6,
                                        alpha,
                                        this.magSrf.Lambda(i, j, poleOptDepth));
                                }
                                //if (koeff_q < 0) koeff_q = 0;
                                sumQ += Math.Cos(2 * ro) * koeff_q * scale1 * mu;

                                // Stokes U integration;
                                if (alpha > 0.5 * Math.PI)
                                {
                                    koeff_u = this.stokesQ_b_theta_lambda(
                                        this.magSrf.MagneticStrength(i, j) * 1e-6,
                                        Math.PI - alpha,
                                        this.magSrf.Lambda(i, j, poleOptDepth));
                                }
                                else
                                {
                                    koeff_u = this.stokesQ_b_theta_lambda(
                                        this.magSrf.MagneticStrength(i, j) * 1e-6,
                                        alpha,
                                        this.magSrf.Lambda(i, j, poleOptDepth));
                                }
                                //if (koeff_i < 0) koeff_i = 0;
                                sumU += -Math.Sin(2 * ro) * koeff_u * scale1 * mu;
                            }
                        }
                    }
                }

                //this.prAreaArray[p] = 1;

                this.stokesI[p] = sumI;
                this.stokesV[p] = sumV;
                this.stokesQ[p] = sumQ;
                this.stokesU[p] = sumU;

                this.stokesI[p] = stokesI[p] * scale;
                this.stokesV[p] = stokesV[p] * scale;
                this.stokesQ[p] = stokesQ[p] * scale;
                this.stokesU[p] = stokesU[p] * scale;
            }//);
        }
示例#3
0
        public void StartMapping(double regPar)
        {
            int allPhases = 0;

            for (int p = 0; p < this.curves.Length; p++)
            {
                allPhases += this.curves[p].phases.Length;
            }

            int observablePatchesNumber  = this.magSrf.GetNumberOfObservablePatches();
            int observableLatBeltsNumber = this.magSrf.GetNumberOfObservableLatBelts();

            double[][] a = new double[allPhases][];
            for (int i = 0; i < a.Length; i++)
            {
                a[i] = new double[observablePatchesNumber];
            }

            {
                int s = 0;
                for (int q = 0; q < this.curves.Length; q++)
                {
                    for (int p = 0; p < this.curves[q].phases.Length; p++)
                    {
                        int k = 0;

                        double muPole         = this.magSrf.MuOfThePole(this.curves[q].phases[p]);
                        double sinGammaCenter = Math.Sqrt(1 - muPole * muPole);
                        if (sinGammaCenter > 1.0)
                        {
                            sinGammaCenter = 1.0;
                        }
                        if (sinGammaCenter < -1.0)
                        {
                            sinGammaCenter = -1.0;
                        }

                        double cosKhi = this.magSrf.GetCosOmega(this.curves[q].phases[p], muPole);
                        double sinKhi = 0;
                        double eps    = this.magSrf.PhiOfThePole(this.curves[q].phases[p])
                                        - 2 * Math.PI * Math.Floor(this.magSrf.PhiOfThePole(this.curves[q].phases[p]) / (2 * Math.PI));

                        if (eps < Math.PI / 2.0 || eps > 1.5 * Math.PI)
                        {
                            sinKhi = -Math.Sqrt(1 - cosKhi * cosKhi);
                        }
                        else
                        {
                            sinKhi = Math.Sqrt(1 - cosKhi * cosKhi);
                        }

                        for (int i = 0; i < observableLatBeltsNumber; i++)
                        {
                            for (int j = 0; j < this.magSrf.Patches[i].Length; j++)
                            {
                                double mu = magSrf.MuOfThePatchCenter(i, j, muPole, sinGammaCenter, cosKhi, sinKhi);

                                if (mu > 0)
                                {
                                    double area = (this.magSrf.Patches[i][j].Phi20 - this.magSrf.Patches[i][j].Phi10) *
                                                  (Math.Cos(this.magSrf.Patches[i][j].Theta1) - Math.Cos(this.magSrf.Patches[i][j].Theta2));
                                    double cosAlpha = this.magSrf.GetCosAlpha2(i, j, this.curves[q].phases[p]);
                                    double alpha    = Math.Acos(cosAlpha);
                                    double prArea   = area * mu;

                                    double koeff_i, koeff_q, koeff_v, koeff_u;
                                    if (this.curves[q].type == "I")
                                    {
                                        if (alpha > 0.5 * Math.PI)
                                        {
                                            koeff_i = this.stokes_func("I", this.curves[q].filter,
                                                                       this.magSrf.MagneticStrength(i, j) * 1e-6,
                                                                       Math.PI - alpha,
                                                                       this.magSrf.Lambda(i, j, 1e7));
                                        }
                                        else
                                        {
                                            koeff_i = this.stokes_func("I", this.curves[q].filter,
                                                                       this.magSrf.MagneticStrength(i, j) * 1e-6,
                                                                       alpha,
                                                                       this.magSrf.Lambda(i, j, 1e7));
                                        }
                                        a[s][k] = prArea * koeff_i;
                                    }
                                    if (this.curves[q].type == "V")
                                    {
                                        if (alpha <= Math.PI * 0.5)
                                        {
                                            a[s][k] = prArea * this.stokes_func("V", this.curves[q].filter,
                                                                                this.magSrf.MagneticStrength(i, j) * 1e-6,
                                                                                alpha,
                                                                                this.magSrf.Lambda(i, j, 1e7));
                                        }
                                        else
                                        {
                                            a[s][k] = -prArea *this.stokes_func("V", this.curves[q].filter,
                                                                                this.magSrf.MagneticStrength(i, j) * 1e-6,
                                                                                Math.PI - alpha,
                                                                                this.magSrf.Lambda(i, j, 1e7));
                                        }
                                    }
                                    if (this.curves[q].type == "Q")
                                    {
                                        double ro     = this.magSrf.GetRo(i, j, this.curves[q].phases[p]);
                                        double alpha1 = alpha;
                                        if (alpha > 0.5 * Math.PI)
                                        {
                                            alpha1 = Math.PI - alpha;
                                        }
                                        a[s][k] = area * Math.Cos(2 * ro) * this.stokes_func("Q", this.curves[q].filter,
                                                                                             this.magSrf.MagneticStrength(i, j),
                                                                                             alpha1,
                                                                                             this.magSrf.Lambda(i, j, 1e7));
                                    }
                                    if (this.curves[q].type == "U")
                                    {
                                        double ro     = this.magSrf.GetRo(i, j, this.curves[q].phases[p]);
                                        double alpha1 = alpha;
                                        if (alpha > 0.5 * Math.PI)
                                        {
                                            alpha1 = Math.PI - alpha;
                                        }
                                        a[s][k] = -area *Math.Sin(2 *ro) * this.stokes_func("Q", this.curves[q].filter,
                                                                                            this.magSrf.MagneticStrength(i, j),
                                                                                            alpha1,
                                                                                            this.magSrf.Lambda(i, j, 1e7));
                                    }
                                }
                                k++;
                            }
                        }
                        s++;
                    }
                }
            }



            double[] f = new double[allPhases];

            {
                int k = 0;
                for (int q = 0; q < this.curves.Length; q++)
                {
                    for (int p = 0; p < this.curves[q].phases.Length; p++)
                    {
                        f[k] = this.curves[q].value[p];
                        k++;
                    }
                }
            }

            double[][] aTa = new double[observablePatchesNumber][];
            for (int i = 0; i < aTa.Length; i++)
            {
                aTa[i] = new double[observablePatchesNumber];
            }

            double[] aTf = new double[observablePatchesNumber];

            double[] x = new double[observablePatchesNumber];

            double[][] aT = new double[observablePatchesNumber][];
            for (int i = 0; i < aT.Length; i++)
            {
                aT[i] = new double[allPhases];
            }

            for (int i = 0; i < aT.Length; i++)
            {
                for (int j = 0; j < aT[i].Length; j++)
                {
                    aT[i][j] = a[j][i];
                }
            }

            MathLib.Basic.ATrA(ref a, ref aTa);

            for (int i = 0; i < aTa.Length; i++)
            {
                aTa[i][i] += regPar;
            }

            MathLib.Basic.AMultB(ref aT, ref f, ref aTf);


            x = MathLib.LES_Solver.SolveWithGaussMethod(aTa, aTf);

            //MathLib.LES_Solver.ConvGradMethodPL(ref aTa, ref aTf, ref x, 1e+10);

            {
                int k = 0;
                for (int i = 0; i < observableLatBeltsNumber; i++)
                {
                    for (int j = 0; j < this.magSrfRes.Patches[i].Length; j++)
                    {
                        this.magSrfRes.SetDensity(i, j, x[k]);
                        k++;
                    }
                }
            }
        }