コード例 #1
0
ファイル: LinearFluxBuilder.cs プロジェクト: xyuan/BoSSS
        /// <summary>
        /// This method can be used to test if the construction of the linear affine flux
        /// was correct
        /// </summary>
        /// <returns>if the given nonlinear flux is representable as an affine linear function,
        /// this should return 0 or a very small value</returns>
        public double Test()
        {
            Vector2D X;
            Vector2D n;

            int L = m_Flux.ArgumentOrdering.Length;
            int I = 20 * L;

            Random rand = new Random();

            double[] Uin  = new double[L];
            double[] Uout = new double[L];

            Vector2D o;

            Vector2D[] m1 = new Vector2D[L];
            Vector2D[] m2 = new Vector2D[L];

            double oSc;

            double[] m1Sc = new double[L];
            double[] m2Sc = new double[L];

            double errsum = 0.0;

            for (int i = 0; i < I; i++)
            {
                // populate Arguments with random values
                // -------------------------------------
                X.x = rand.NextDouble() * 10.0 - 5.0;
                X.y = rand.NextDouble() * 10.0 - 5.0;

                for (int l = L - 1; l >= 0; l--)
                {
                    Uin[l]  = rand.NextDouble() * 2.0 - 1.0;
                    Uout[l] = rand.NextDouble() * 2.0 - 1.0;
                }

                n.x = rand.NextDouble() * 2.0 - 1.0;
                n.y = rand.NextDouble() * 2.0 - 1.0;
                n.Normalize();



                // test "BorderEdgeFlux"
                // ---------------------
                {
                    // "nonlinear" version
                    double nbe = m_Flux.BorderEdgeFlux(0.0, X, n, Uin);

                    // linear version
                    this.BorderEdgeFlux(0.0, X, n, m1Sc, out oSc);

                    double lbe = 0.0;
                    lbe += oSc;

                    for (int l = L - 1; l >= 0; l--)
                    {
                        lbe += m1Sc[l] * Uin[l];
                    }

                    nbe    -= lbe; // now, "nbe" should be equal to "lbe"
                    errsum += Math.Abs(nbe);
                }

                // test "Flux"
                // -----------
                {
                    // "nonlinear" version
                    Vector2D nf = m_Flux.Flux(0.0, X, Uin);

                    // linear version
                    this.Flux(0.0, X, m1, out o);

                    Vector2D lf = new Vector2D();
                    lf.Acc(o);

                    for (int l = L - 1; l >= 0; l--)
                    {
                        lf.Acc(m1[l], Uin[l]);
                    }

                    nf.Sub(lf); // now, "nf" should be equal to "lf"
                    errsum += nf.Abs();
                }

                // test "Flux"
                // -----------
                {
                    // "nonlinear" version
                    double nif = m_Flux.InnerEdgeFlux(0.0, X, n, Uin, Uout);

                    // linear version
                    this.InnerEdgeFlux(0.0, X, n, m1Sc, m2Sc, out oSc);

                    double lif = 0.0;
                    lif += oSc;

                    for (int l = L - 1; l >= 0; l--)
                    {
                        lif += m1Sc[l] * Uin[l];
                    }
                    for (int l = L - 1; l >= 0; l--)
                    {
                        lif += m2Sc[l] * Uout[l];
                    }

                    nif    -= lif; // now, "nif" should be equal to "lif"
                    errsum += Math.Abs(nif);
                }
            }

            return(errsum);
        }