예제 #1
0
        public void Init(MultigridOperator op)
        {
            int D = op.GridData.SpatialDimension;

            CodName = new string[] { "momX", "momY", "div", "constitutiveXX", "constitutiveXY", "constitutiveYY" };
            Params  = new string[] { "VelocityX_GradientX", "VelocityX_GradientY", "VelocityY_GradientX", "VelocityY_GradientY" };
            DomName = new string[] { "VelocityX", "VelocityY", "Pressure", "StressXX", "StressXY", "StressYY" };

            LocalOp = new SpatialOperator(DomName, Params, CodName, (A, B, C) => 4);

            LocalOp.EquationComponents["constitutiveXX"].Add(new LocalJacobiFlux()
            {
                m_component = 0, We = m_We
            });
            LocalOp.EquationComponents["constitutiveXY"].Add(new LocalJacobiFlux()
            {
                m_component = 1, We = m_We
            });
            LocalOp.EquationComponents["constitutiveYY"].Add(new LocalJacobiFlux()
            {
                m_component = 2, We = m_We
            });

            LocalOp.Commit();

            var   U0      = ((BoSSS.Foundation.CoordinateMapping)op.Mapping.ProblemMapping).Fields.GetSubVector(0, 2);
            Basis U0Basis = new Basis(op.Mapping.GridData, 0);

            VectorField <SinglePhaseField> VelocityXGradient = new VectorField <SinglePhaseField>(D, U0Basis, "VelocityX_Gradient", SinglePhaseField.Factory);
            VectorField <SinglePhaseField> VelocityYGradient = new VectorField <SinglePhaseField>(D, U0Basis, "VelocityY_Gradient", SinglePhaseField.Factory);

            VelocityXGradient.Clear();
            VelocityXGradient.GradientByFlux(1.0, U0[0]);
            VelocityYGradient.Clear();
            VelocityYGradient.GradientByFlux(1.0, U0[1]);

            var Parameters = ArrayTools.Cat <DGField>(VelocityXGradient, VelocityYGradient);

            LocalMatrix = LocalOp.ComputeMatrix(op.BaseGridProblemMapping, Parameters, op.BaseGridProblemMapping);

            ConstEqIdx = op.Mapping.ProblemMapping.GetSubvectorIndices(true, 3, 4, 5);

            P = (BlockMsrMatrix)op.MassMatrix.Clone();

            for (int i = ConstEqIdx[0]; i <= ConstEqIdx.Length; i++)
            {
                for (int j = ConstEqIdx[0]; j <= ConstEqIdx.Length; j++)
                {
                    if (LocalMatrix[i, j] != 0)
                    {
                        P[i, j] = LocalMatrix[i, j];
                    }
                }
            }

            LocalMatrix.SaveToTextFileSparse("LocalMatrix");
            op.MassMatrix.SaveToTextFileSparse("MassMatrix");
            P.SaveToTextFileSparse("PrecondMatrix");
        }
예제 #2
0
파일: DirectSolver.cs 프로젝트: xyuan/BoSSS
        /// <summary>
        /// %
        /// </summary>
        public void Solve <U, V>(U X, V B)
            where U : IList <double>
            where V : IList <double> //
        {
            using (var tr = new FuncTrace()) {
                double[] Residual = this.TestSolution ? B.ToArray() : null;

                string SolverName = "NotSet";
                using (var solver = GetSolver(m_Mtx)) {
                    SolverName = solver.GetType().FullName;
                    //Console.Write("Direct solver run {0}, using {1} ... ", IterCnt, solver.GetType().Name);
                    IterCnt++;
                    solver.Solve(X, B);
                    //Console.WriteLine("done.");
                }


                m_ThisLevelIterations++;

                if (Residual != null)
                {
                    //Console.Write("Checking residual (run {0}) ... ", IterCnt - 1);
                    double RhsNorm       = Residual.L2NormPow2().MPISum().Sqrt();
                    double MatrixInfNorm = m_Mtx.InfNorm();
                    m_Mtx.SpMV(-1.0, X, 1.0, Residual);

                    double ResidualNorm    = Residual.L2NormPow2().MPISum().Sqrt();
                    double SolutionNorm    = X.L2NormPow2().MPISum().Sqrt();
                    double Denom           = Math.Max(MatrixInfNorm, Math.Max(RhsNorm, Math.Max(SolutionNorm, Math.Sqrt(double.Epsilon))));
                    double RelResidualNorm = ResidualNorm / Denom;

                    //Console.WriteLine("done: Abs.: {0}, Rel.: {1}", ResidualNorm, RelResidualNorm);

                    if (RelResidualNorm > 1.0e-10)
                    {
                        //Console.WriteLine("High residual from direct solver: abs {0}, rel {1}", ResidualNorm , ResidualNorm / SolutionNorm);

                        m_Mtx.SaveToTextFileSparse("Mtx.txt");
                        X.SaveToTextFile("X.txt");
                        B.SaveToTextFile("B.txt");

                        string ErrMsg;
                        using (var stw = new StringWriter()) {
                            stw.WriteLine("High residual from direct solver (using {0}).", SolverName);
                            stw.WriteLine("    L2 Norm of RHS:         " + RhsNorm);
                            stw.WriteLine("    L2 Norm of Solution:    " + SolutionNorm);
                            stw.WriteLine("    L2 Norm of Residual:    " + ResidualNorm);
                            stw.WriteLine("    Relative Residual norm: " + RelResidualNorm);
                            stw.WriteLine("    Matrix Inf norm:        " + MatrixInfNorm);
                            stw.WriteLine("Dumping text versions of Matrix, Solution and RHS.");
                            ErrMsg = stw.ToString();
                        }
                        Console.WriteLine(ErrMsg);
                    }
                }

                if (this.IterationCallback != null)
                {
                    double[] _xl = X.ToArray();
                    double[] _bl = B.ToArray();
                    m_Mtx.SpMV(-1.0, _xl, 1.0, _bl);
                    this.IterationCallback(1, _xl, _bl, this.m_MultigridOp);
                }
            }
        }