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"); }
/// <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); } } }