public static void Init() { //GridCommons grd = Grid2D.Cartesian2DGrid(RandomSpacing(), RandomSpacing()); //grid = new GridData(Grid2D.Cartesian2DGrid(GenericBlas.Linspace(-7, 7, 8), GenericBlas.Linspace(-1, 1, 2))); //grid = new GridData(Grid2D.Cartesian2DGrid(new double[] { -6, -4, -2, 2, 4, 6 }, GenericBlas.Linspace(-1, 1, 2))); //if (curved) //{ // grid = Grid2D.CurvedSquareGrid(GenericBlas.Linspace(1, 2, 5), GenericBlas.Linspace(0, 1, 17), CellType.Square_9, true).GridData; //} //else //{ // grid = (Grid2D.Cartesian2DGrid(GenericBlas.Linspace(-1.5, 1.5, 17), GenericBlas.Linspace(-1.5, 1.5, 17))).GridData; //} grid = (Grid2D.Cartesian2DGrid(GenericBlas.Linspace(-1.5, 1.5, 17), GenericBlas.Linspace(-1.5, 1.5, 17))).GridData; MgSeq = CoarseningAlgorithms.CreateSequence(grid); for (int p = 0; p <= 3; p++) // loop over polynomial degrees... { var uMapping = new UnsetteledCoordinateMapping(new Basis(grid, p)); var MgMapSeq = new MultigridMapping[MgSeq.Length]; var BasisSeq = AggregationGridBasis.CreateSequence(MgSeq, uMapping.BasisS); for (int iLevel = 0; iLevel < MgSeq.Length; iLevel++) { MgMapSeq[iLevel] = new MultigridMapping(uMapping, BasisSeq[iLevel], new int[] { p }); } MultigrigMap.Add(p, MgMapSeq); } }
public static void Init() { bool dummy; ilPSP.Environment.Bootstrap( new string[0], BoSSS.Solution.Application.GetBoSSSInstallDir(), out dummy); //GridCommons grd = Grid2D.Cartesian2DGrid(RandomSpacing(), RandomSpacing()); //grid = new GridData(Grid2D.Cartesian2DGrid(GenericBlas.Linspace(-7, 7, 8), GenericBlas.Linspace(-1, 1, 2))); //grid = new GridData(Grid2D.Cartesian2DGrid(new double[] { -6, -4, -2, 2, 4, 6 }, GenericBlas.Linspace(-1, 1, 2))); grid = new GridData(Grid2D.Cartesian2DGrid(GenericBlas.Linspace(-1.5, 1.5, 17), GenericBlas.Linspace(-1.5, 1.5, 17))); MgSeq = CoarseningAlgorithms.CreateSequence(grid); for (int p = 0; p <= 3; p++) // loop over polynomial degrees... { var uMapping = new UnsetteledCoordinateMapping(new Basis(grid, p)); var MgMapSeq = new MultigridMapping[MgSeq.Length]; var BasisSeq = AggregationGridBasis.CreateSequence(MgSeq, uMapping.BasisS); for (int iLevel = 0; iLevel < MgSeq.Length; iLevel++) { MgMapSeq[iLevel] = new MultigridMapping(uMapping, BasisSeq[iLevel], new int[] { p }); } MultigrigMap.Add(p, MgMapSeq); } }
/// <summary> /// Constructor for XDG solvers /// </summary> public OpAnalysisBase(LevelSetTracker LsTrk, BlockMsrMatrix Mtx, double[] RHS, UnsetteledCoordinateMapping Mapping, MultiphaseCellAgglomerator CurrentAgglomeration, BlockMsrMatrix _mass, IEnumerable <MultigridOperator.ChangeOfBasisConfig[]> OpConfig, ISpatialOperator abstractOperator) { int RHSlen = Mapping.TotalLength; m_map = Mapping; // mapping VarGroup = Mapping.BasisS.Count.ForLoop(i => i); //default: all dependent variables are included in operator matrix m_LsTrk = LsTrk; m_OpMtx = Mtx.CloneAs(); localRHS = RHS.CloneAs(); // create the Dummy XDG aggregation basis var baseGrid = Mapping.GridDat; var mgSeq = Foundation.Grid.Aggregation.CoarseningAlgorithms.CreateSequence(baseGrid, 1); AggregationGridBasis[][] XAggB = AggregationGridBasis.CreateSequence(mgSeq, Mapping.BasisS); // XAggB.UpdateXdgAggregationBasis(CurrentAgglomeration); // create multigrid operator m_MultigridOp = new MultigridOperator(XAggB, Mapping, m_OpMtx, _mass, OpConfig, abstractOperator.DomainVar.Select(varName => abstractOperator.FreeMeanValue[varName]).ToArray()); }
private void OperatorAnalysis() { AggregationGridBasis[][] XAggB = AggregationGridBasis.CreateSequence(base.MultigridSequence, u.Mapping.BasisS); XAggB.UpdateXdgAggregationBasis(this.Op_Agglomeration); var MultigridOp = new MultigridOperator(XAggB, this.u.Mapping, this.Op_Matrix, this.Op_mass.GetMassMatrix(new UnsetteledCoordinateMapping(this.u.Basis), false), OpConfig); var PcOpMatrix = MultigridOp.OperatorMatrix; //PcOpMatrix.SaveToTextFileSparse("C:\\temp\\Xpoisson.txt"); MultidimensionalArray ret = MultidimensionalArray.Create(1, 4); using (BatchmodeConnector bmc = new BatchmodeConnector()) { bmc.PutSparseMatrix(PcOpMatrix, "OpMtx"); bmc.Cmd("OpMtxSym = 0.5*(OpMtx + OpMtx');"); bmc.Cmd("condNo = condest(OpMtxSym);"); bmc.Cmd("eigMaxi = eigs(OpMtxSym,1,'lm')"); bmc.Cmd("eigMini = eigs(OpMtxSym,1,'sm')"); bmc.Cmd("lasterr"); bmc.Cmd("[V,r]=chol(OpMtxSym);"); bmc.Cmd("ret = [condNo, eigMaxi, eigMini, r]"); bmc.GetMatrix(ret, "ret"); bmc.Execute(false); } double condNo = ret[0, 0]; double eigMaxi = ret[0, 1]; double eigMini = ret[0, 2]; double posDef = ret[0, 3] == 0 ? 1 : 0; Console.WriteLine("Condition number: {0:0.####E-00}", condNo); if (posDef == 0.0) { Console.WriteLine("WARNING: Operator matrix is not positive definite."); } base.QueryHandler.ValueQuery("condNo", condNo, false); base.QueryHandler.ValueQuery("eigMaxi", eigMaxi, false); base.QueryHandler.ValueQuery("eigMini", eigMini, false); base.QueryHandler.ValueQuery("posDef", posDef, false); }
/// <summary> /// Initialization of the solver/preconditioner. /// </summary> protected void InitMultigrid(DGField[] Fields, bool useX) { Basis[] bs; if (useX) { bs = new Basis[Fields.Length]; for (int i = 0; i < bs.Length; i++) { bs[i] = new XDGBasis(m_LsTrk, Fields[i].Basis.Degree); } } else { bs = Fields.Select(f => f.Basis).ToArray(); } this.MultigridBasis = AggregationGridBasis.CreateSequence(this.MultigridSequence, bs); }
public static void Init() { grid = Grid2D.CurvedSquareGrid(GenericBlas.Linspace(1, 2, 17), GenericBlas.Linspace(0, 1, 17), CellType.Square_9, true).GridData; MgSeq = CoarseningAlgorithms.CreateSequence(grid); for (int p = 0; p <= 3; p++) { // loop over polynomial degrees... var uMapping = new UnsetteledCoordinateMapping(new Basis(grid, p)); var MgMapSeq = new MultigridMapping[MgSeq.Length]; var BasisSeq = AggregationGridBasis.CreateSequence(MgSeq, uMapping.BasisS); for (int iLevel = 0; iLevel < MgSeq.Length; iLevel++) { MgMapSeq[iLevel] = new MultigridMapping(uMapping, BasisSeq[iLevel], new int[] { p }); } MultigrigMap.Add(p, MgMapSeq); } }
private void Setup() { MgSeq = CoarseningAlgorithms.CreateSequence(m_grid.iGridData); int p = m_DGorder; var uMapping = new UnsetteledCoordinateMapping(u1.Basis, u2.Basis); //var uMapping = new UnsetteledCoordinateMapping(u1.Basis); //var uMapping = new UnsetteledCoordinateMapping(new Basis(m_grid.iGridData, p)); XAggB = AggregationGridBasis.CreateSequence(MgSeq, uMapping.BasisS); var bla = LsTrk.SpeciesIdS.ToArray(); var agg = LsTrk.GetAgglomerator(bla, m_quadOrder, THRESHOLD, AgglomerateNewborn: false, AgglomerateDecased: false, ExceptionOnFailedAgglomeration: true); XAggB.UpdateXdgAggregationBasis(agg); var VarDegrees = uMapping.BasisS.Count.ForLoop(i => uMapping.BasisS[i].Degree); MG_Mapping = new MultigridMapping(uMapping, XAggB[0], VarDegrees); map = uMapping; }
public static void RestrictionOfSystemOpTest() { Basis B1 = new Basis(grid, 0), B2 = new Basis(grid, 2); var Map = new UnsetteledCoordinateMapping(B1, B2); AggregationGridBasis[][] aB = AggregationGridBasis.CreateSequence(TestProgram.MgSeq.Take(2), new Basis[] { B1, B2 }); var Lev0 = new MultigridMapping(Map, aB[0], new int[] { B1.Degree, B2.Degree }); var Lev1 = new MultigridMapping(Map, aB[1], new int[] { B1.Degree, B2.Degree }); int[] I0col = Lev0.GetSubvectorIndices(new int[] { 0 }); int[] I1col = Lev0.GetSubvectorIndices(new int[] { 1 }); int[] I0row = Lev1.GetSubvectorIndices(new int[] { 0 }); int[] I1row = Lev1.GetSubvectorIndices(new int[] { 1 }); var RestMtx = Lev1.FromOtherLevelMatrix(Lev0); MsrMatrix Rest00 = new MsrMatrix(I0row.Length, I0col.Length, 1, 1); RestMtx.WriteSubMatrixTo(Rest00, I0row, default(int[]), I0col, default(int[])); MsrMatrix Rest01 = new MsrMatrix(I0row.Length, I1col.Length, 1, 1); RestMtx.WriteSubMatrixTo(Rest01, I0row, default(int[]), I1col, default(int[])); MsrMatrix Rest10 = new MsrMatrix(I1row.Length, I0col.Length, 1, 1); RestMtx.WriteSubMatrixTo(Rest10, I1row, default(int[]), I0col, default(int[])); MsrMatrix Rest11 = new MsrMatrix(I1row.Length, I1col.Length, 1, 1); RestMtx.WriteSubMatrixTo(Rest11, I1row, default(int[]), I1col, default(int[])); Assert.IsTrue(Rest10.InfNorm() == 0.0); Assert.IsTrue(Rest01.InfNorm() == 0.0); Assert.IsTrue(Rest00.InfNorm() != 0.0); Assert.IsTrue(Rest11.InfNorm() != 0.0); }
public XDGTestSetup( int p, double AggregationThreshold, int TrackerWidth, MultigridOperator.Mode mumo, XQuadFactoryHelper.MomentFittingVariants momentFittingVariant, ScalarFunction LevSetFunc = null) { // Level set, tracker and XDG basis // ================================ if (LevSetFunc == null) { LevSetFunc = ((_2D)((x, y) => 0.8 * 0.8 - x * x - y * y)).Vectorize(); } LevSet = new LevelSet(new Basis(grid, 2), "LevelSet"); LevSet.Clear(); LevSet.ProjectField(LevSetFunc); LsTrk = new LevelSetTracker(grid, XQuadFactoryHelper.MomentFittingVariants.Classic, TrackerWidth, new string[] { "A", "B" }, LevSet); LsTrk.UpdateTracker(); XB = new XDGBasis(LsTrk, p); XSpatialOperator Dummy = new XSpatialOperator(1, 0, 1, QuadOrderFunc.SumOfMaxDegrees(RoundUp: true), "C1", "u"); //Dummy.EquationComponents["c1"].Add(new Dummy.Commit(); //Tecplot.PlotFields(new DGField[] { LevSet }, "agglo", 0.0, 3); // operator // ======== Debug.Assert(p <= 4); XDGBasis opXB = new XDGBasis(LsTrk, 4); // we want to have a very precise quad rule var map = new UnsetteledCoordinateMapping(opXB); int quadOrder = Dummy.QuadOrderFunction(map.BasisS.Select(bs => bs.Degree).ToArray(), new int[0], map.BasisS.Select(bs => bs.Degree).ToArray()); //agg = new MultiphaseCellAgglomerator(new CutCellMetrics(momentFittingVariant, quadOrder, LsTrk, LsTrk.SpeciesIdS.ToArray()), AggregationThreshold, false); agg = LsTrk.GetAgglomerator(LsTrk.SpeciesIdS.ToArray(), quadOrder, __AgglomerationTreshold: AggregationThreshold); foreach (var S in LsTrk.SpeciesIdS) { Console.WriteLine("Species {0}, no. of agglomerated cells {1} ", LsTrk.GetSpeciesName(S), agg.GetAgglomerator(S).AggInfo.SourceCells.Count()); } // mass matrix factory // =================== // Basis maxB = map.BasisS.ElementAtMax(b => b.Degree); //MassFact = new MassMatrixFactory(maxB, agg); MassFact = LsTrk.GetXDGSpaceMetrics(LsTrk.SpeciesIdS.ToArray(), quadOrder, 1).MassMatrixFactory; // Test field // ========== // set the test field: this is a polynomial function, // but different for each species; On this field, restriction followed by prolongation should be the identity this.Xdg_uTest = new XDGField(this.XB, "uTest"); Dictionary <SpeciesId, double> dumia = new Dictionary <SpeciesId, double>(); int i = 2; foreach (var Spc in LsTrk.SpeciesIdS) { dumia.Add(Spc, i); i -= 1; } SetTestValue(Xdg_uTest, dumia); // dummy operator matrix which fits polynomial degree p // ==================================================== Xdg_opMtx = new BlockMsrMatrix(Xdg_uTest.Mapping, Xdg_uTest.Mapping); Xdg_opMtx.AccEyeSp(120.0); // XDG Aggregation BasiseS // ======================= //XAggB = MgSeq.Select(agGrd => new XdgAggregationBasis[] { new XdgAggregationBasis(uTest.Basis, agGrd) }).ToArray(); XAggB = new XdgAggregationBasis[MgSeq.Length][]; var _XAggB = AggregationGridBasis.CreateSequence(MgSeq, Xdg_uTest.Mapping.BasisS); for (int iLevel = 0; iLevel < XAggB.Length; iLevel++) { XAggB[iLevel] = new[] { (XdgAggregationBasis)(_XAggB[iLevel][0]) }; XAggB[iLevel][0].Update(agg); } // Multigrid Operator // ================== Xdg_opMtx = new BlockMsrMatrix(Xdg_uTest.Mapping, Xdg_uTest.Mapping); Xdg_opMtx.AccEyeSp(120.0); XdgMultigridOp = new MultigridOperator(XAggB, Xdg_uTest.Mapping, Xdg_opMtx, MassFact.GetMassMatrix(Xdg_uTest.Mapping, false), new MultigridOperator.ChangeOfBasisConfig[][] { new MultigridOperator.ChangeOfBasisConfig[] { new MultigridOperator.ChangeOfBasisConfig() { VarIndex = new int[] { 0 }, mode = mumo, Degree = p } } }); }
private void ConsistencyTest() { // consistency test on the original matrix // ----------------------------------------------------- this.residual.Clear(); double[] RHSvec = this.GetRHS(); this.residual.CoordinateVector.SetV(RHSvec, 1.0); this.Op_Matrix.SpMV(-1.0, this.u.CoordinateVector, 1.0, residual.CoordinateVector); double residual_L2Norm = this.residual.L2Norm(); Console.WriteLine("Residual norm: " + residual_L2Norm); Assert.LessOrEqual(residual_L2Norm, 1.0e-8); // consistency test on the multigrid // -------------------------------------------------------------------- AggregationGridBasis[][] XAggB = AggregationGridBasis.CreateSequence(base.MultigridSequence, u.Mapping.BasisS); XAggB.UpdateXdgAggregationBasis(this.Op_Agglomeration); int p = this.u.Basis.Degree; var MultigridOp = new MultigridOperator(XAggB, this.u.Mapping, this.Op_Matrix, this.Op_mass.GetMassMatrix(new UnsetteledCoordinateMapping(this.u.Basis), false), new MultigridOperator.ChangeOfBasisConfig[][] { new MultigridOperator.ChangeOfBasisConfig[] { new MultigridOperator.ChangeOfBasisConfig() { VarIndex = new int[] { 0 }, mode = MultigridOperator.Mode.Eye, Degree = u.Basis.Degree } } }); double[] mgSolVec = new double[MultigridOp.Mapping.LocalLength]; double[] mgRhsVec = new double[MultigridOp.Mapping.LocalLength]; MultigridOp.TransformSolInto(this.u.CoordinateVector, mgSolVec); MultigridOp.TransformRhsInto(RHSvec, mgRhsVec); MgConsistencyTestRec(MultigridOp, mgSolVec, mgRhsVec); // /* * { * int Jagg1 = MgSeq[1].NoOfAggregateCells; * MultigridOperator MgOp0 = MultigridOp; * MultigridOperator MgOp1 = MultigridOp.CoarserLevel; * MultigridMapping Map0 = MgOp0.Mapping; * MultigridMapping Map1 = MgOp1.Mapping; * * * double[] V0 = new double[MgOp0.Mapping.LocalLength]; * double[] V1 = new double[MgOp1.Mapping.LocalLength]; * * for(int j = 0; j < Jagg1; j++) { * int idx = Map1.LocalUniqueIndex(0, j, 0); * V1[idx] = j; * } * * MgOp1.Prolongate(1.0, V0, 0.0, V1); * * XDGField Marker = new XDGField(this.u.Basis, "Tracker"); * * MgOp0.TransformSolFrom(Marker.CoordinatesAsVector, V0); * this.Op_Agglomeration.Extrapolate(Marker.CoordinatesAsVector, Marker.Mapping); * * Tecplot.PlotFields(new DGField[] { Marker }, "Tracker", "Tracker", 0.0, 5); * * } */ }
private void ExperimentalSolver(out double mintime, out double maxtime, out bool Converged, out int NoOfIter, out int DOFs) { using (var tr = new FuncTrace()) { mintime = double.MaxValue; maxtime = 0; Converged = false; NoOfIter = int.MaxValue; DOFs = 0; AggregationGridBasis[][] XAggB; using (new BlockTrace("Aggregation_basis_init", tr)) { XAggB = AggregationGridBasis.CreateSequence(base.MultigridSequence, u.Mapping.BasisS); } XAggB.UpdateXdgAggregationBasis(this.Op_Agglomeration); var MassMatrix = this.Op_mass.GetMassMatrix(this.u.Mapping, new double[] { 1.0 }, false, this.LsTrk.SpeciesIdS.ToArray()); double[] _RHSvec = this.GetRHS(); Stopwatch stw = new Stopwatch(); stw.Reset(); stw.Start(); Console.WriteLine("Setting up multigrid operator..."); int p = this.u.Basis.Degree; var MultigridOp = new MultigridOperator(XAggB, this.u.Mapping, this.Op_Matrix, this.Op_mass.GetMassMatrix(new UnsetteledCoordinateMapping(this.u.Basis), false), OpConfig); Assert.True(MultigridOp != null); int L = MultigridOp.Mapping.LocalLength; DOFs = MultigridOp.Mapping.TotalLength; double[] RHSvec = new double[L]; MultigridOp.TransformRhsInto(_RHSvec, RHSvec); ISolverSmootherTemplate exsolver; SolverFactory SF = new SolverFactory(this.Control.NonLinearSolver, this.Control.LinearSolver); List <Action <int, double[], double[], MultigridOperator> > Callbacks = new List <Action <int, double[], double[], MultigridOperator> >(); Callbacks.Add(CustomItCallback); SF.GenerateLinear(out exsolver, MultigridSequence, OpConfig, Callbacks); using (new BlockTrace("Solver_Init", tr)) { exsolver.Init(MultigridOp); } /* * string filename = "XdgPoisson" + this.Grid.SpatialDimension + "p" + this.u.Basis.Degree + "R" + this.Grid.CellPartitioning.TotalLength; * MultigridOp.OperatorMatrix.SaveToTextFileSparse(filename + ".txt"); * RHSvec.SaveToTextFile(filename + "_rhs.txt"); * * var uEx = this.u.CloneAs(); * Op_Agglomeration.ClearAgglomerated(uEx.Mapping); * var CO = new ConvergenceObserver(MultigridOp, MassMatrix, uEx.CoordinateVector.ToArray()); * uEx = null; * CO.TecplotOut = "PoissonConvergence"; * //CO.PlotDecomposition(this.u.CoordinateVector.ToArray()); * * if (exsolver is ISolverWithCallback) { * ((ISolverWithCallback)exsolver).IterationCallback = CO.IterationCallback; * } * //*/ XDGField u2 = u.CloneAs(); using (new BlockTrace("Solver_Run", tr)) { // use solver (on XDG-field 'u2'). u2.Clear(); MultigridOp.UseSolver(exsolver, u2.CoordinateVector, _RHSvec); Console.WriteLine("Solver: {0}, converged? {1}, {2} iterations.", exsolver.GetType().Name, exsolver.Converged, exsolver.ThisLevelIterations); this.Op_Agglomeration.Extrapolate(u2.Mapping); Assert.IsTrue(exsolver.Converged, "Iterative solver did not converge."); } stw.Stop(); mintime = Math.Min(stw.Elapsed.TotalSeconds, mintime); maxtime = Math.Max(stw.Elapsed.TotalSeconds, maxtime); Converged = exsolver.Converged; NoOfIter = exsolver.ThisLevelIterations; // compute error between reference solution and multigrid solver XDGField ErrField = u2.CloneAs(); ErrField.Acc(-1.0, u); double ERR = ErrField.L2Norm(); double RelERR = ERR / u.L2Norm(); Assert.LessOrEqual(RelERR, 1.0e-6, "Result from iterative solver above threshold."); } }
/// <summary> /// Spatial operator matrix analysis method /// </summary> public void SpatialOperatorMatrixAnalysis(bool CheckAssertions, int AnalysisLevel) { using (var solver = new Rheology()) { int D = solver.Grid.SpatialDimension; if (AnalysisLevel < 0 || AnalysisLevel > 2) { throw new ArgumentException(); } BlockMsrMatrix OpMatrix; double[] OpAffine; solver.AssembleMatrix(out OpMatrix, out OpAffine, solver.CurrentSolution.Mapping.ToArray(), true); // ============================= // AnalysisLevel 0 // ============================= { var OpMatrixT = OpMatrix.Transpose(); CoordinateVector TestVec = new CoordinateVector(solver.CurrentSolution.Mapping.Fields.Select(f => f.CloneAs()).ToArray()); double testsumPos = 0.0; double testsumNeg = 0.0; for (int rnd_seed = 0; rnd_seed < 20; rnd_seed++) { // fill the pressure components of the test vector TestVec.Clear(); Random rnd = new Random(rnd_seed); DGField Pressack = TestVec.Mapping.Fields[D] as DGField; int J = solver.GridData.iLogicalCells.NoOfLocalUpdatedCells; for (int j = 0; j < J; j++) { int N = Pressack.Basis.GetLength(j); for (int n = 0; n < N; n++) { Pressack.Coordinates[j, n] = rnd.NextDouble(); } } // Gradient times P: double[] R1 = new double[TestVec.Count]; OpMatrix.SpMV(1.0, TestVec, 0.0, R1); // R1 = Grad * P //Console.WriteLine("L2 of 'Grad * P': " + R1.L2Norm()); // transpose of Divergence times P: double[] R2 = new double[TestVec.Count]; OpMatrix.SpMV(1.0, TestVec, 0.0, R2); // R2 = divT * P //Console.WriteLine("L2 of 'divT * P': " + R2.L2Norm()); TestVec.Clear(); TestVec.Acc(1.0, R1); TestVec.Acc(1.0, R2); // analyze! testsumNeg += GenericBlas.L2Dist(R1, R2); R2.ScaleV(-1.0); testsumPos += GenericBlas.L2Dist(R1, R2); } Console.WriteLine("Pressure/Divergence Symmetry error in all tests (+): " + testsumPos); Console.WriteLine("Pressure/Divergence Symmetry error in all tests (-): " + testsumNeg); if (CheckAssertions) { Assert.LessOrEqual(Math.Abs(testsumNeg), testsumPos * 1.0e-13); } } // ============================= // AnalysisLevel 1 and 2 // ============================= if (AnalysisLevel > 0) { AggregationGridBasis[][] MgBasis = AggregationGridBasis.CreateSequence(solver.MultigridSequence, solver.CurrentSolution.Mapping.BasisS); MultigridOperator mgOp = new MultigridOperator(MgBasis, solver.CurrentSolution.Mapping, OpMatrix, null, solver.MultigridOperatorConfig); // extract //////////// MsrMatrix FullMatrix = mgOp.OperatorMatrix.ToMsrMatrix(); MsrMatrix DiffMatrix; { int[] VelVarIdx = D.ForLoop(d => d); int[] USubMatrixIdx_Row = mgOp.Mapping.GetSubvectorIndices(VelVarIdx); int[] USubMatrixIdx_Col = mgOp.Mapping.GetSubvectorIndices(VelVarIdx); int L = USubMatrixIdx_Row.Length; DiffMatrix = new MsrMatrix(L, L, 1, 1); FullMatrix.WriteSubMatrixTo(DiffMatrix, USubMatrixIdx_Row, default(int[]), USubMatrixIdx_Col, default(int[])); double DiffMatrix_sd = DiffMatrix.SymmetryDeviation(); Console.WriteLine("Diffusion assymetry:" + DiffMatrix_sd); } MsrMatrix SaddlePointMatrix; { int[] VelPVarIdx = new int[] { 0, 1, 2 }; int[] VelPSubMatrixIdx_Row = mgOp.Mapping.GetSubvectorIndices(VelPVarIdx); int[] VelPSubMatrixIdx_Col = mgOp.Mapping.GetSubvectorIndices(VelPVarIdx); int L = VelPSubMatrixIdx_Row.Length; SaddlePointMatrix = new MsrMatrix(L, L, 1, 1); FullMatrix.WriteSubMatrixTo(SaddlePointMatrix, VelPSubMatrixIdx_Row, default(int[]), VelPSubMatrixIdx_Col, default(int[])); } //SaddlePointMatrix.SaveToTextFileSparse("C:\\Users\\kikker\\Documents\\MATLAB\\spm.txt"); MsrMatrix ConstitutiveMatrix; { int[] StressVarIdx = new int[] { 3, 4, 5 }; int[] StressSubMatrixIdx_Row = mgOp.Mapping.GetSubvectorIndices(StressVarIdx); int[] StressSubMatrixIdx_Col = mgOp.Mapping.GetSubvectorIndices(StressVarIdx); int L = StressSubMatrixIdx_Row.Length; ConstitutiveMatrix = new MsrMatrix(L, L, 1, 1); FullMatrix.WriteSubMatrixTo(ConstitutiveMatrix, StressSubMatrixIdx_Row, default(int[]), StressSubMatrixIdx_Col, default(int[])); } // operator analysis ////////////////////// bool posDef; if (AnalysisLevel > 1) { // +++++++++++++++++++++++++++++++ // check condition number, etc // +++++++++++++++++++++++++++++++ MultidimensionalArray ret = MultidimensionalArray.Create(1, 5); Console.WriteLine("Calling MATLAB/Octave..."); using (BatchmodeConnector bmc = new BatchmodeConnector()) { bmc.PutSparseMatrix(FullMatrix, "FullMatrix"); bmc.PutSparseMatrix(SaddlePointMatrix, "SaddlePointMatrix"); bmc.PutSparseMatrix(ConstitutiveMatrix, "ConstitutiveMatrix"); bmc.PutSparseMatrix(DiffMatrix, "DiffMatrix"); bmc.Cmd("DiffMatrix = 0.5*(DiffMatrix + DiffMatrix');"); bmc.Cmd("condNoFullMatrix = condest(FullMatrix);"); bmc.Cmd("condNoSaddlePointMatrix = condest(SaddlePointMatrix);"); bmc.Cmd("condNoConstitutiveMatrix = condest(ConstitutiveMatrix);"); bmc.Cmd("condNoDiffMatrix = condest(DiffMatrix);"); //bmc.Cmd("eigiMaxiSaddle = 1.0; % eigs(SaddlePointMatrix,1,'lm')"); //bmc.Cmd("eigiMiniSaddle = 1.0; % eigs(SaddlePointMatrix,1,'sm')"); //bmc.Cmd("eigiMaxiConst = 1.0; % eigs(ConstitutiveMatrix,1,'lm')"); //bmc.Cmd("eigiMiniConst = 1.0; % eigs(ConstitutiveMatrix,1,'sm')"); //bmc.Cmd("eigiMaxiDiff = 1.0; % eigs(DiffMatrix,1,'lm')"); //bmc.Cmd("eigiMiniDiff = 1.0; % eigs(DiffMatrix,1,'sm')"); bmc.Cmd("lasterr"); bmc.Cmd("[V,r]=chol(SaddlePointMatrix);"); bmc.Cmd("[V,r]=chol(ConstitutiveMatrix);"); bmc.Cmd("ret = [condNoFullMatrix, condNoSaddlePointMatrix, condNoConstitutiveMatrix, condNoDiffMatrix, r]"); //eigiMaxiSaddle, eigiMiniSaddle, eigiMaxiConst, eigiMiniConst, eigiMaxiDiff, eigiMiniDiff, bmc.GetMatrix(ret, "ret"); bmc.Execute(false); } double condNoFullMatrix = ret[0, 0]; double condNoSaddlePMatrix = ret[0, 1]; double condNoConstitutiveMatrix = ret[0, 2]; double condNoDiffMatrix = ret[0, 3]; //double eigiMaxiSaddle = ret[0, 4]; //double eigiMiniSaddle = ret[0, 5]; //double eigiMaxiConst = ret[0, 6]; //double eigiMiniConst = ret[0, 7]; //double eigiMaxiDiff = ret[0, 8]; //double eigiMiniDiff = ret[0, 9]; posDef = ret[0, 4] == 0; //Console.WriteLine("Eigenvalue range of saddle point matrix: {0} to {1}", eigiMiniSaddle, eigiMaxiSaddle); //Console.WriteLine("Eigenvalue range of constitutive matrix: {0} to {1}", eigiMiniConst, eigiMaxiConst); //Console.WriteLine("Eigenvalue range of diffusion matrix: {0} to {1}", eigiMiniDiff, eigiMaxiDiff); Console.WriteLine("Condition number full operator: {0:0.####E-00}", condNoFullMatrix); Console.WriteLine("Condition number saddle point operator: {0:0.####E-00}", condNoSaddlePMatrix); Console.WriteLine("Condition number constitutive operator: {0:0.####E-00}", condNoConstitutiveMatrix); Console.WriteLine("Condition number diffusion operator: {0:0.####E-00}", condNoDiffMatrix); //base.QueryHandler.ValueQuery("ConditionNumber", condNoFullMatrix); } else { // +++++++++++++++++++++++++++++++++++++++ // test only for positive definiteness // +++++++++++++++++++++++++++++++++++++++ var SaddlePMatrixFull = SaddlePointMatrix.ToFullMatrixOnProc0(); var ConstMatrixFull = ConstitutiveMatrix.ToFullMatrixOnProc0(); posDef = true; try { SaddlePMatrixFull.Cholesky(); } catch (ArithmeticException) { posDef = false; } posDef = true; try { ConstMatrixFull.Cholesky(); } catch (ArithmeticException) { posDef = false; } } double SaddlePSymm = SaddlePointMatrix.SymmetryDeviation(); Console.WriteLine("Symmetry deviation of saddle point matrix: " + SaddlePSymm); if (posDef) { Console.WriteLine("Good news: Saddle point operator matrix seems to be positive definite."); } else { Console.WriteLine("WARNING: Saddle point operator matrix is not positive definite."); } double ConstSymm = ConstitutiveMatrix.SymmetryDeviation(); Console.WriteLine("Symmetry deviation of constitutive matrix: " + ConstSymm); if (posDef) { Console.WriteLine("Good news: constitutive operator matrix seems to be positive definite."); } else { Console.WriteLine("WARNING: constitutive operator matrix is not positive definite."); } //if (CheckAssertions) { // if (Control.AdvancedDiscretizationOptions.ViscosityMode == ViscosityMode.FullySymmetric && Control.PhysicalParameters.IncludeConvection == false) { // Assert.IsTrue(posDef, "Positive definiteness test failed."); // double compVal = DiffMatrix.InfNorm() * 1e-13; // Assert.LessOrEqual(DiffSymm, compVal, "Diffusion matrix seems to be non-symmetric."); // } //} } } }
/// <summary> /// Solution of the system /// <see cref="LaplaceMtx"/>*<see cref="T"/> + <see cref="LaplaceAffine"/> = <see cref="RHS"/> /// using the modular solver framework. /// </summary> private void ExperimentalSolve(out double mintime, out double maxtime, out bool Converged, out int NoOfIter) { using (var tr = new FuncTrace()) { int p = this.T.Basis.Degree; var MgSeq = this.MultigridSequence; mintime = double.MaxValue; maxtime = 0; Converged = false; NoOfIter = int.MaxValue; Console.WriteLine("Construction of Multigrid basis..."); Stopwatch mgBasis = new Stopwatch(); mgBasis.Start(); AggregationGridBasis[][] AggBasis; using (new BlockTrace("Aggregation_basis_init", tr)) { AggBasis = AggregationGridBasis.CreateSequence(MgSeq, new Basis[] { this.T.Basis }); } mgBasis.Stop(); Console.WriteLine("done. (" + mgBasis.Elapsed.TotalSeconds + " sec)"); //foreach (int sz in new int[] { 1000, 2000, 5000, 10000, 20000 }) { // base.Control.TargetBlockSize = sz; for (int irun = 0; irun < base.Control.NoOfSolverRuns; irun++) { Stopwatch stw = new Stopwatch(); stw.Reset(); stw.Start(); Console.WriteLine("Setting up multigrid operator..."); var mgsetup = new Stopwatch(); mgsetup.Start(); var MultigridOp = new MultigridOperator(AggBasis, this.T.Mapping, this.LaplaceMtx, null, MgConfig); mgsetup.Stop(); Console.WriteLine("done. (" + mgsetup.Elapsed.TotalSeconds + " sec)"); Console.WriteLine("Setting up solver..."); var solverSetup = new Stopwatch(); solverSetup.Start(); ISolverSmootherTemplate solver; switch (base.Control.solver_name) { case SolverCodes.exp_direct: solver = new DirectSolver() { WhichSolver = DirectSolver._whichSolver.PARDISO }; break; case SolverCodes.exp_direct_lapack: solver = new DirectSolver() { WhichSolver = DirectSolver._whichSolver.Lapack }; break; case SolverCodes.exp_softpcg_schwarz_directcoarse: { double LL = this.LaplaceMtx._RowPartitioning.LocalLength; int NoOfBlocks = (int)Math.Max(1, Math.Round(LL / (double)this.Control.TargetBlockSize)); Console.WriteLine("Additive Schwarz w. direct coarse, No of blocks: " + NoOfBlocks.MPISum()); solver = new SoftPCG() { m_MaxIterations = 50000, m_Tolerance = 1.0e-10, Precond = new Schwarz() { m_MaxIterations = 1, //CoarseSolver = new GenericRestriction() { // CoarserLevelSolver = new GenericRestriction() { CoarseSolver = new DirectSolver() { WhichSolver = DirectSolver._whichSolver.PARDISO // } //} }, m_BlockingStrategy = new Schwarz.METISBlockingStrategy() { NoOfPartsPerProcess = NoOfBlocks }, Overlap = 1, } }; break; } case SolverCodes.exp_softpcg_schwarz: { double LL = this.LaplaceMtx._RowPartitioning.LocalLength; int NoOfBlocks = (int)Math.Max(1, Math.Round(LL / (double)this.Control.TargetBlockSize)); Console.WriteLine("Additive Schwarz, No of blocks: " + NoOfBlocks.MPISum()); solver = new SoftPCG() { m_MaxIterations = 50000, m_Tolerance = 1.0e-10, Precond = new Schwarz() { m_MaxIterations = 1, CoarseSolver = null, m_BlockingStrategy = new Schwarz.METISBlockingStrategy { NoOfPartsPerProcess = NoOfBlocks }, Overlap = 1 } }; break; } case SolverCodes.exp_softpcg_mg: solver = MultilevelSchwarz(MultigridOp); break; case SolverCodes.exp_Kcycle_schwarz: solver = KcycleMultiSchwarz(MultigridOp); break; default: throw new ApplicationException("unknown solver: " + this.Control.solver_name); } T.Clear(); T.AccLaidBack(1.0, Tex); ConvergenceObserver CO = null; //CO = new ConvergenceObserver(MultigridOp, null, T.CoordinateVector.ToArray()); //CO.TecplotOut = "oasch"; if (solver is ISolverWithCallback) { if (CO == null) { ((ISolverWithCallback)solver).IterationCallback = delegate (int iter, double[] xI, double[] rI, MultigridOperator mgOp) { double l2_RES = rI.L2NormPow2().MPISum().Sqrt(); double[] xRef = new double[xI.Length]; MultigridOp.TransformSolInto(T.CoordinateVector, xRef); double l2_ERR = GenericBlas.L2DistPow2(xI, xRef).MPISum().Sqrt(); Console.WriteLine("Iter: {0}\tRes: {1:0.##E-00}\tErr: {2:0.##E-00}\tRunt: {3:0.##E-00}", iter, l2_RES, l2_ERR, stw.Elapsed.TotalSeconds); //Tjac.CoordinatesAsVector.SetV(xI); //Residual.CoordinatesAsVector.SetV(rI); //PlotCurrentState(iter, new TimestepNumber(iter), 3); }; } else { ((ISolverWithCallback)solver).IterationCallback = CO.IterationCallback; } } using (new BlockTrace("Solver_Init", tr)) { solver.Init(MultigridOp); } solverSetup.Stop(); Console.WriteLine("done. (" + solverSetup.Elapsed.TotalSeconds + " sec)"); Console.WriteLine("Running solver..."); var solverIteration = new Stopwatch(); solverIteration.Start(); double[] T2 = this.T.CoordinateVector.ToArray(); using (new BlockTrace("Solver_Run", tr)) { solver.ResetStat(); T2.Clear(); var RHSvec = RHS.CoordinateVector.ToArray(); BLAS.daxpy(RHSvec.Length, -1.0, this.LaplaceAffine, 1, RHSvec, 1); MultigridOp.UseSolver(solver, T2, RHSvec); T.CoordinateVector.SetV(T2); } solverIteration.Stop(); Console.WriteLine("done. (" + solverIteration.Elapsed.TotalSeconds + " sec)"); Console.WriteLine("Pardiso phase 11: " + ilPSP.LinSolvers.PARDISO.PARDISOSolver.Phase_11.Elapsed.TotalSeconds); Console.WriteLine("Pardiso phase 22: " + ilPSP.LinSolvers.PARDISO.PARDISOSolver.Phase_22.Elapsed.TotalSeconds); Console.WriteLine("Pardiso phase 33: " + ilPSP.LinSolvers.PARDISO.PARDISOSolver.Phase_33.Elapsed.TotalSeconds); // time measurement, statistics stw.Stop(); mintime = Math.Min(stw.Elapsed.TotalSeconds, mintime); maxtime = Math.Max(stw.Elapsed.TotalSeconds, maxtime); Converged = solver.Converged; NoOfIter = solver.ThisLevelIterations; if (CO != null) CO.PlotTrend(true, true, true); } } }