public void Init(MultigridOperator op) { var M = op.OperatorMatrix; var MgMap = op.Mapping; this.m_mgop = op; if (!M.RowPartitioning.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Row partitioning mismatch."); } if (!M.ColPartition.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Column partitioning mismatch."); } Mtx = M; int L = M.RowPartitioning.LocalLength; diag = new double[L]; int i0 = Mtx.RowPartitioning.i0; for (int i = 0; i < L; i++) { diag[i] = Mtx[i0 + i, i0 + i]; } }
/// <summary> /// defines the problem matrix /// </summary> public void Init(MultigridOperator op) { // init & check // ============ this.m_MgOperator = op; //OpMatrix = op.OperatorMatrix; OpMatrix = new ilPSP.LinSolvers.monkey.CPU.RefMatrix(op.OperatorMatrix.ToMsrMatrix()); var MgMap = op.Mapping; if (!OpMatrix.RowPartitioning.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Row partitioning mismatch."); } if (!OpMatrix.ColPartition.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Column partitioning mismatch."); } // init solver chain // ================= if (SolverChain == null || SolverChain.Length <= 0) { throw new NotSupportedException("Illegal configuration."); } for (int i = 0; i < SolverChain.Length; i++) { SolverChain[i].Init(op); } }
/// <summary> /// Updating the <see cref="CurrentLin"/> -- operator; /// </summary> /// <param name="CurrentState">linearization point</param> /// <param name="HomotopyValue"> /// <see cref="ISpatialOperator.CurrentHomotopyValue"/> /// </param> protected void UpdateLinearization(IEnumerable <DGField> CurrentState, double HomotopyValue) { if (!(this.ProblemMapping.BasisS.Count == CurrentState.Count())) { throw new ArgumentException("mismatch in number of fields."); } SetHomotopyValue(HomotopyValue); // the real call: this.m_AssembleMatrix(out BlockMsrMatrix OpMtxRaw, out double[] OpAffineRaw, out BlockMsrMatrix MassMtxRaw, CurrentState.ToArray(), true, out ISpatialOperator abstractOperator); AbstractOperator = abstractOperator; // blabla: CurrentLin = new MultigridOperator(this.m_AggBasisSeq, this.ProblemMapping, OpMtxRaw.CloneAs(), MassMtxRaw, this.m_MultigridOperatorConfig, AbstractOperator.DomainVar.Select(varName => AbstractOperator.FreeMeanValue[varName]).ToArray()); OpAffineRaw = OpAffineRaw.CloneAs(); if (this.RHSRaw != null) { OpAffineRaw.AccV(-1.0, this.RHSRaw); } if (LinearizationRHS == null || LinearizationRHS.Length != this.CurrentLin.Mapping.LocalLength) { LinearizationRHS = new double[this.CurrentLin.Mapping.LocalLength]; } else { LinearizationRHS.ClearEntries(); } CurrentLin.TransformRhsInto(OpAffineRaw, this.LinearizationRHS, true); this.LinearizationRHS.ScaleV(-1.0); }
/// <summary> /// Performs a mode decay analysis (<see cref="Waterfall(bool, int)"/>) on this solver. /// </summary> public static Plot2Ddata WaterfallAnalysis(ISolverWithCallback linearSolver, MultigridOperator mgOperator, BlockMsrMatrix MassMatrix) { int L = mgOperator.BaseGridProblemMapping.LocalLength; var RHS = new double[L]; var exSol = new double[L]; ConvergenceObserver co = new ConvergenceObserver(mgOperator, MassMatrix, exSol); var bkup = linearSolver.IterationCallback; linearSolver.IterationCallback = co.IterationCallback; // use a random init for intial guess. Random rnd = new Random(); double[] x0 = new double[L]; for (int l = 0; l < L; l++) { x0[l] = rnd.NextDouble(); } // execute solver linearSolver.Init(mgOperator); mgOperator.UseSolver(linearSolver, x0, RHS); // reset and return linearSolver.IterationCallback = bkup; //var p = co.PlotIterationTrend(true, false, true, true); var p = co.Waterfall(true, 100); return(p); }
public void ResItCallbackAtDownstep(int iter, double[] xI, double[] rI, MultigridOperator mgOp) { if (IsDownstep(mgOp.LevelIndex) || IsUpstep(mgOp.LevelIndex)) { var Ptr_mgOp = mgOp; int iLevel = mgOp.LevelIndex; double[] vec_i = rI; CoordinateVector DecompVec = this.InitProblemDGFields("Res"); for (int k = iLevel; k > 0; k--) { double[] vec_i1 = new double[Ptr_mgOp.FinerLevel.Mapping.LocalLength]; Ptr_mgOp.Prolongate(1.0, vec_i1, 0.0, vec_i); vec_i = vec_i1; Ptr_mgOp = Ptr_mgOp.FinerLevel; } Ptr_mgOp.TransformSolFrom(DecompVec, vec_i); //DecompVec.AccV(1, vec_i); string plotName = TecplotOut + "Res-decomp" + "." + Iterationcounter[3] + "." + ItWithinMGCycle(); Tecplot.Tecplot.PlotFields(DecompVec.Mapping.Fields, plotName, 0.0, 3); } }
/// <summary> /// Updating the <see cref="CurrentLin"/> -- operator; /// </summary> /// <param name="CurrentState">linearization point</param> protected void UpdateLinearization(IEnumerable <DGField> CurrentState) { if (!(this.ProblemMapping.BasisS.Count == CurrentState.Count())) { throw new ArgumentException("mismatch in number of fields."); } BlockMsrMatrix OpMtxRaw, MassMtxRaw; double[] OpAffineRaw; this.m_AssembleMatrix(out OpMtxRaw, out OpAffineRaw, out MassMtxRaw, CurrentState.ToArray(), true); CurrentLin = new MultigridOperator(this.m_AggBasisSeq, this.ProblemMapping, OpMtxRaw.CloneAs(), MassMtxRaw, this.m_MultigridOperatorConfig); OpAffineRaw = OpAffineRaw.CloneAs(); if (this.RHSRaw != null) { OpAffineRaw.AccV(-1.0, this.RHSRaw); } if (LinearizationRHS == null || LinearizationRHS.Length != this.CurrentLin.Mapping.LocalLength) { LinearizationRHS = new double[this.CurrentLin.Mapping.LocalLength]; } else { LinearizationRHS.ClearEntries(); } CurrentLin.TransformRhsInto(OpAffineRaw, this.LinearizationRHS); this.LinearizationRHS.ScaleV(-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"); }
ilPSP.LinSolvers.monkey.CPU.RefMatrix m_Matrix; // im Moment schneller, ca 5X //BlockMsrMatrix m_Matrix; public void Init(MultigridOperator op) { using (new FuncTrace()) { var M = op.OperatorMatrix; var MgMap = op.Mapping; this.m_MgOp = op; if (!M.RowPartitioning.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Row partitioning mismatch."); } if (!M.ColPartition.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Column partitioning mismatch."); } //this.m_Matrix = M; this.m_Matrix = new ilPSP.LinSolvers.monkey.CPU.RefMatrix(M.ToMsrMatrix()); /* * int n = m_Matrix.RowPartitioning.LocalLength; * if(n > 50000) { * var _Matrix = new ilPSP.LinSolvers.monkey.CPU.RefMatrix(M.ToMsrMatrix()); * * double[] xTest = new double[n]; * double[] bTest = new double[n]; * Random r = new Random(123); * for(int i = 0; i < n; i++) { * xTest[i] = r.NextDouble(); * bTest[i] = r.NextDouble(); * } * * * double[] b1 = bTest.CloneAs(); * double[] x1 = bTest.CloneAs(); * Stopwatch monkey = new Stopwatch(); * monkey.Start(); * for (int i = 0; i < 100; i++) * _Matrix.SpMV(1.0, x1, -0.1, b1); * monkey.Stop(); * * double[] b2 = bTest.CloneAs(); * double[] x2 = bTest.CloneAs(); * Stopwatch block = new Stopwatch(); * block.Start(); * for (int i = 0; i < 100; i++) * m_Matrix.SpMV(1.0, x1, -0.1, b1); * block.Stop(); * * Console.WriteLine("SPMV monkey: " + monkey.Elapsed.TotalSeconds); * Console.WriteLine("SPMV block MSR: " + block.Elapsed.TotalSeconds); * } */ if (Precond != null) { Precond.Init(op); } } }
public IList <double[]> OrthonormalMultigridDecomposition(double[] Vec, bool decompose = true) { // vector length on level 0 int L0 = DecompositionOperator.Mapping.LocalLength; if (Vec.Length != L0) { throw new ArgumentException("Mismatch in vector length.", "Vec"); } List <double[]> OrthoVecs = new List <double[]>(); OrthoVecs.Add(Vec.CloneAs()); double l2pow2_Vec = OrthoVecs[0].L2NormPow2().MPISum(); MultigridOperator coarsest = null; for (var mgop = this.DecompositionOperator.CoarserLevel; mgop != null; mgop = mgop.CoarserLevel) { int L = mgop.Mapping.LocalLength; int iLevel = mgop.LevelIndex; OrthoVecs.Add(new double[L]); mgop.Restrict(OrthoVecs[iLevel - 1], OrthoVecs[iLevel]); coarsest = mgop; } double Check_l2pow2_OrthoVecsTotal = 0.0; for (var mgop = this.DecompositionOperator.CoarserLevel; mgop != null; mgop = mgop.CoarserLevel) { int iLevel = mgop.LevelIndex; if (decompose) { mgop.Prolongate(-1.0, OrthoVecs[iLevel - 1], 1.0, OrthoVecs[iLevel]); } coarsest = mgop; } foreach (double[] OrthoVec in OrthoVecs) { Check_l2pow2_OrthoVecsTotal += OrthoVec.L2NormPow2().MPISum(); } // if the vectors are really orthonormal, their squared L2-norms must be additive! if (decompose && this.DecompositionOperator_IsOrthonormal) { Debug.Assert((Math.Abs(Check_l2pow2_OrthoVecsTotal - l2pow2_Vec) / l2pow2_Vec < 1.0e-8), "something wrong with orthonormal decomposition"); } return(OrthoVecs); }
private void Setup(MultigridOperator muop, BlockMsrMatrix MassMatrix, double[] __ExactSolution) { if (__ExactSolution != null) { if (__ExactSolution.Length != muop.BaseGridProblemMapping.LocalLength) { throw new ArgumentException(); } } this.SolverOperator = muop; List <AggregationGridBasis[]> aggBasisSeq = new List <AggregationGridBasis[]>(); for (var mo = muop; mo != null; mo = mo.CoarserLevel) { aggBasisSeq.Add(mo.Mapping.AggBasis); } this.ExactSolution = __ExactSolution; int[] Degrees = muop.BaseGridProblemMapping.BasisS.Select(b => b.Degree).ToArray(); BlockMsrMatrix DummyOpMatrix = new BlockMsrMatrix(muop.BaseGridProblemMapping, muop.BaseGridProblemMapping); DummyOpMatrix.AccEyeSp(123); MultigridOperator.ChangeOfBasisConfig[][] config = new MultigridOperator.ChangeOfBasisConfig[1][]; config[0] = new MultigridOperator.ChangeOfBasisConfig[muop.BaseGridProblemMapping.BasisS.Count]; for (int iVar = 0; iVar < config[0].Length; iVar++) { config[0][iVar] = new MultigridOperator.ChangeOfBasisConfig() { Degree = Degrees[iVar], mode = MultigridOperator.Mode.IdMass_DropIndefinite, VarIndex = new int[] { iVar } }; } //this.DecompositionOperator = muop; this.DecompositionOperator_IsOrthonormal = false; this.DecompositionOperator = new MultigridOperator(aggBasisSeq, muop.BaseGridProblemMapping, DummyOpMatrix, MassMatrix, config); this.DecompositionOperator_IsOrthonormal = true; ResNormTrend = new Dictionary <Tuple <int, int, int>, List <double> >(); ErrNormTrend = new Dictionary <Tuple <int, int, int>, List <double> >(); for (var mgop = this.DecompositionOperator; mgop != null; mgop = mgop.CoarserLevel) { int[] _Degrees = mgop.Mapping.DgDegree; for (int iVar = 0; iVar < _Degrees.Length; iVar++) { for (int p = 0; p <= _Degrees[iVar]; p++) { ResNormTrend.Add(new Tuple <int, int, int>(mgop.LevelIndex, iVar, p), new List <double>()); ErrNormTrend.Add(new Tuple <int, int, int>(mgop.LevelIndex, iVar, p), new List <double>()); } } } }
/// <summary> /// extract the Fields from the solution, Resample them equally spaced and ready to use in an fft /// </summary> private void Resample(int iterIndex, double[] currentSol, MultigridOperator Mgop, string component) { if (Mgop.GridData.SpatialDimension == 2 && Mgop.LevelIndex == 0) { MultidimensionalArray SamplePoints; GridData GD = (GridData)Mgop.Mapping.AggGrid.AncestorGrid; BoundingBox BB = GD.GlobalBoundingBox; double xDist = BB.Max[0] - BB.Min[0]; double yDist = BB.Max[1] - BB.Min[1]; double aspectRatio = xDist / yDist; MGViz viz = new MGViz(Mgop); DGField[] Fields = viz.ProlongateToDg(currentSol, "Error"); for (int p = 0; p < Fields.Length; p++) { var field = Fields[p]; int DOF = field.DOFLocal; double N = Math.Sqrt(DOF); int Nx = (int)Math.Round(Math.Sqrt(aspectRatio) * N); int Ny = (int)Math.Round(1 / Math.Sqrt(aspectRatio) * N); SamplePoints = MultidimensionalArray.Create(Ny, Nx); for (int i = 0; i < Nx; i++) { MultidimensionalArray points = MultidimensionalArray.Create(Ny, 2); for (int k = 0; k < Ny; k++) { points[k, 0] = BB.Min[0] + (i + 1) * xDist / (Nx + 1); points[k, 1] = BB.Min[1] + (k + 1) * yDist / (Ny + 1); } List <DGField> fields = new List <DGField>(); fields.Add(field); FieldEvaluation FE = new FieldEvaluation(GD); MultidimensionalArray Result = MultidimensionalArray.Create(Ny, 1); FE.Evaluate(1.0, fields, points, 1.0, Result); SamplePoints.ExtractSubArrayShallow(-1, i).Acc(1.0, Result.ExtractSubArrayShallow(-1, 0)); } SamplePoints.SaveToTextFile("ResampleFFT_lvl" + Mgop.LevelIndex + "_" + iterIndex + "_" + component + "_" + field.Identification + ".txt"); } } }
public void Init(MultigridOperator op) { this.m_OpThisLevel = op; if (op.CoarserLevel == null) { throw new NotSupportedException("Multigrid algorithm cannot be used as a solver on the finest level."); } this.CoarserLevelSolver.Init(op.CoarserLevel); }
/// <summary> /// defines the problem matrix /// </summary> public void Init(MultigridOperator op) { this.m_MgOperator = op; var Mtx = op.OperatorMatrix; var MgMap = op.Mapping; viz = new MGViz(op); if (!Mtx.RowPartitioning.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Row partitioning mismatch."); } if (!Mtx.ColPartition.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Column partitioning mismatch."); } MxxHistory.Clear(); SolHistory.Clear(); double Dim = MgMap.ProblemMapping.GridDat.SpatialDimension; // set operator // ============ if (op.CoarserLevel == null) { throw new NotSupportedException("Multigrid algorithm cannot be used as a solver on the finest level."); } this.OpMatrix = Mtx; // initiate coarser level // ====================== if (this.CoarserLevelSolver == null) { throw new NotSupportedException("Missing coarse level solver."); } this.CoarserLevelSolver.Init(op.CoarserLevel); // init smoother // ============= if (PreSmoother != null) { PreSmoother.Init(op); } if (PostSmoother != null && !object.ReferenceEquals(PreSmoother, PostSmoother)) { PostSmoother.Init(op); } }
private void AssignXdgBlocksModification(SubBlockSelector sbs, MultigridOperator op, bool IsLowSelector) { var Filter = sbs.ModeFilter; Func <int, int, int, int, bool> Modification = delegate(int iCell, int iVar, int iSpec, int pDeg) { int NoOfSpec = op.Mapping.AggBasis[0].GetNoOfSpecies(iCell); if (NoOfSpec >= 2) { return(IsLowSelector); } else { return(Filter(iCell, iVar, iSpec, pDeg)); } }; sbs.ModeSelector(Modification); }
public void Init(MultigridOperator op) { var Mtx = op.OperatorMatrix; var MgMap = op.Mapping; m_MultigridOp = op; if (!Mtx.RowPartitioning.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Row partitioning mismatch."); } if (!Mtx.ColPartition.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Column partitioning mismatch."); } m_Mtx = Mtx; }
static public ISolverSmootherTemplate InitMultigridChain(MultigridOperator MgOp, Func <int, ISolverSmootherTemplate> PreSmootherFactory, Func <int, ISolverSmootherTemplate> PostSmootherFactory, Action <int, ClassicMultigrid> ParamsSeter, Func <ISolverSmootherTemplate> CoarsestSolverFactory) // { if (MgOp.CoarserLevel == null) { return(CoarsestSolverFactory()); } else { var MgTop = new ClassicMultigrid(); ParamsSeter(MgOp.LevelIndex, MgTop); MgTop.PreSmoother = PreSmootherFactory(MgOp.LevelIndex); MgTop.PostSmoother = PostSmootherFactory(MgOp.LevelIndex); MgTop.CoarserLevelSolver = InitMultigridChain(MgOp.CoarserLevel, PreSmootherFactory, PostSmootherFactory, ParamsSeter, CoarsestSolverFactory); return(MgTop); } }
public void Init(MultigridOperator op) { var M = op.OperatorMatrix; var MgMap = op.Mapping; this.m_mgop = op; if (!M.RowPartitioning.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Row partitioning mismatch."); } if (!M.ColPartition.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Column partitioning mismatch."); } foreach (var pc in PrecondS) { pc.Init(m_mgop); } }
public void Init(MultigridOperator op) { var Mtx = op.OperatorMatrix; var MgMap = op.Mapping; this.m_mgop = op; if (!Mtx.RowPartitioning.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Row partitioning mismatch."); } if (!Mtx.ColPartition.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Column partitioning mismatch."); } this.Matrix = Mtx; if (Precond != null) { Precond.Init(op); } }
static public ISolverSmootherTemplate InitMultigridChain(MultigridOperator MgOp, Action <int, SoftPCG> ParamsSeter, Func <ISolverSmootherTemplate> CoarsestSolverFactory) { // if (MgOp.CoarserLevel == null) { return(CoarsestSolverFactory()); } else { var MgTop = new SoftPCG(); ParamsSeter(MgOp.LevelIndex, MgTop); var R = new GenericRestriction(); MgTop.Precond = R; R.CoarserLevelSolver = InitMultigridChain(MgOp.CoarserLevel, ParamsSeter, CoarsestSolverFactory); return(MgTop); } }
/// <summary> /// Decomposition of some solution vector <paramref name="Solvec"/> into the different multigrid levels. /// </summary> public void PlotDecomposition <V>(V vec, string plotName) where V : IList <double> // { int L0 = this.DecompositionOperator.Mapping.LocalLength; double[] vec0 = new double[L0]; this.DecompositionOperator.TransformSolInto(vec, vec0); var Decomp = this.OrthonormalMultigridDecomposition(vec0, false); List <DGField> DecompFields = new List <DGField>(); MultigridOperator op = this.DecompositionOperator; for (int iLevel = 0; iLevel < Decomp.Count; iLevel++) { double[] vec_i = Decomp[iLevel]; var DecompVec = this.InitProblemDGFields("Level" + iLevel); MultigridOperator opi = op; for (int k = iLevel; k > 0; k--) { int Lk1 = Decomp[k - 1].Length; double[] vec_i1 = new double[Lk1]; opi.Prolongate(1.0, vec_i1, 0.0, vec_i); vec_i = vec_i1; opi = opi.FinerLevel; } this.DecompositionOperator.TransformSolFrom(DecompVec, vec_i); DecompFields.AddRange(DecompVec.Mapping.Fields); op = op.CoarserLevel; } Tecplot.Tecplot.PlotFields(DecompFields, plotName, 0.0, 3); }
public double[] ProlongateToTop(double[] V) { int iLv = FindLevel(V.Length); MultigridOperator op_iLv = m_op.FinestLevel; for (int i = 0; i < iLv; i++) { op_iLv = op_iLv.CoarserLevel; } Debug.Assert(op_iLv.LevelIndex == iLv); Debug.Assert(V.Length == op_iLv.Mapping.LocalLength); double[] Curr = V; for (var Op4Level = op_iLv; Op4Level.FinerLevel != null; Op4Level = Op4Level.FinerLevel) { double[] Next = new double[Op4Level.FinerLevel.Mapping.LocalLength]; Op4Level.Prolongate(1.0, Next, 0.0, Curr); Curr = Next; } return(Curr); }
/// <summary> /// Initialization of each multi-grid level /// </summary> public void Init(MultigridOperator op) { using (new FuncTrace()) { // checks // ====== var M = op.OperatorMatrix; var MgMap = op.Mapping; this.m_mgop = op; int MpiSize = M._RowPartitioning.MpiSize; if (!M.RowPartitioning.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Row partitioning mismatch."); } if (!M.ColPartition.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Column partitioning mismatch."); } // determine which levels to use // ============================= { var tempOp4Level = new List <MultigridOperator>(); var Op = op; do { tempOp4Level.Add(Op); Op = Op.CoarserLevel; if (Op == null) { break; } } while (tempOp4Level.Last().Mapping.TotalLength > LowestLevelDOFthreshold); Op4Level = tempOp4Level.ToArray(); Mtx4Level = new BlockMsrMatrix[Op4Level.Length]; for (int i = 0; i < Mtx4Level.Length; i++) { Mtx4Level[i] = Op4Level[i].OperatorMatrix; } } // define preconditioner's // ======================= { PrecondS = new ISolverSmootherTemplate[Op4Level.Length]; // all levels except the coarsest one for (int i = 0; i < PrecondS.Length - 1; i++) { int NoOfBlocks = (int)Math.Ceiling((double)(Op4Level[i].Mapping.LocalLength) / (double)LowestLevelDOFthreshold); // we want at least two blocks - otherwise we could use the direct solver directly. if (MpiSize > 1) { // more than one MPI core -> at least one block per core -> globally at least 2 cores NoOfBlocks = Math.Max(1, NoOfBlocks); } else { // singe MPI core -> at least two blocks NoOfBlocks = Math.Max(2, NoOfBlocks); } PrecondS[i] = new Schwarz() { FixedNoOfIterations = 1, CoarseSolver = null, m_BlockingStrategy = new Schwarz.METISBlockingStrategy() { NoOfPartsPerProcess = NoOfBlocks }, Overlap = 1 }; } // coarsest level PrecondS[PrecondS.Length - 1] = new DirectSolver() { WhichSolver = DirectSolver._whichSolver.PARDISO, TestSolution = false }; // init each level for (int i = 0; i < PrecondS.Length; i++) { PrecondS[i].Init(Op4Level[i]); } } } }
/// <summary> /// defines the problem matrix /// </summary> public void Init(MultigridOperator op) { using (var tr = new FuncTrace()) { this.m_MgOperator = op; var Mtx = op.OperatorMatrix; var MgMap = op.Mapping; //if(op.LevelIndex == 0) // viz = new MGViz(op); if (!Mtx.RowPartitioning.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Row partitioning mismatch."); } if (!Mtx.ColPartition.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Column partitioning mismatch."); } MxxHistory.Clear(); SolHistory.Clear(); // set operator // ============ this.OpMatrix = Mtx; // initiate coarser level // ====================== if (this.CoarserLevelSolver == null) { //throw new NotSupportedException("Missing coarse level solver."); Console.WriteLine("OrthonormalizationMultigrid: running without coarse solver."); } else { if (op.CoarserLevel != null) { this.CoarserLevelSolver.Init(op.CoarserLevel); CoarseOnLovwerLevel = true; } else { Console.WriteLine("OrthonormalizationMultigrid: running coarse solver on same level."); this.CoarserLevelSolver.Init(op); CoarseOnLovwerLevel = false; } } // init smoother // ============= if (PreSmoother != null) { PreSmoother.Init(op); } if (PostSmoother != null && !object.ReferenceEquals(PreSmoother, PostSmoother)) { PostSmoother.Init(op); } } }
/// <summary> /// Triggers <see cref="IterationCallback"/>. /// </summary> protected void OnIterationCallback(int iterIndex, double[] currentSol, double[] currentRes, MultigridOperator Mgop) { if (IterationCallback != null) { IterationCallback(iterIndex, currentSol, currentRes, Mgop); } }
public void Init(MultigridOperator op) { int D = op.GridData.SpatialDimension; CodName = (new string[] { "mom0", "mom1" }); Params = ArrayTools.Cat( VariableNames.Velocity0Vector(D)); DomName = ArrayTools.Cat(VariableNames.VelocityVector(D)); LocalOp = new SpatialOperator(DomName, Params, CodName, (A, B, C) => 4); for (int d = 0; d < D; d++) { LocalOp.EquationComponents["mom" + d].Add(new LocalDiffusiveFlux() { m_component = d, dt = m_dt, muA = m_muA }); } LocalOp.Commit(); //LocalMatrix = op.MassMatrix.CloneAs().ToMsrMatrix(); //LocalMatrix.Clear(); //var U0 = new VectorField<SinglePhaseField>(op.BaseGridProblemMapping Take(D).Select(F => (SinglePhaseField)F).ToArray()); UnsetteledCoordinateMapping test = new UnsetteledCoordinateMapping(op.BaseGridProblemMapping.BasisS.GetSubVector(0, D)); var U0 = ((BoSSS.Foundation.CoordinateMapping)op.Mapping.ProblemMapping).Fields.GetSubVector(0, 2); var empty = new SinglePhaseField[D]; LocalMatrix = LocalOp.ComputeMatrix(test, empty, test, time: m_dt); Uidx = op.Mapping.ProblemMapping.GetSubvectorIndices(true, D.ForLoop(i => i)); Pidx = op.Mapping.ProblemMapping.GetSubvectorIndices(true, D); int Upart = Uidx.Length; int Ppart = Pidx.Length; ConvDiff = null; // new BlockMsrMatrix(Upart, Upart, 1, 1); pGrad = null; // new BlockMsrMatrix(Upart, Ppart, 1, 1); divVel = null; // new BlockMsrMatrix(Ppart, Upart, 1, 1); BlockMsrMatrix VelocityMass = null; // new BlockMsrMatrix(Upart, Upart, 1, 1); BlockMsrMatrix leftChangeBasesVel = null; // new BlockMsrMatrix(Upart, Upart, 1, 1); BlockMsrMatrix rightChangeBasesVel = null; // new BlockMsrMatrix(Upart, Upart, 1, 1); op.MassMatrix.AccSubMatrixTo(1.0, VelocityMass, Uidx, default(int[]), Uidx, default(int[]), default(int[]), default(int[])); op.LeftChangeOfBasis.AccSubMatrixTo(1.0, leftChangeBasesVel, Uidx, default(int[]), Uidx, default(int[]), default(int[]), default(int[])); op.RightChangeOfBasis.AccSubMatrixTo(1.0, rightChangeBasesVel, Uidx, default(int[]), Uidx, default(int[]), default(int[]), default(int[])); var temp = BlockMsrMatrix.Multiply(leftChangeBasesVel, LocalMatrix); LocalMatrix = BlockMsrMatrix.Multiply(temp, rightChangeBasesVel); var M = op.OperatorMatrix; M.AccSubMatrixTo(1.0, ConvDiff, Uidx, default(int[]), Uidx, default(int[]), default(int[]), default(int[])); M.AccSubMatrixTo(1.0, pGrad, Uidx, default(int[]), Pidx, default(int[]), default(int[]), default(int[])); M.AccSubMatrixTo(1.0, divVel, Pidx, default(int[]), Uidx, default(int[]), default(int[]), default(int[])); //LocalMatrix.SaveToTextFileSparse("LocalConvDiffMatrix"); //ConvDiff.SaveToTextFileSparse("ConvDiff"); //op.MassMatrix.SaveToTextFileSparse("MassMatrix"); //VelocityMass.SaveToTextFileSparse("VelocityMass"); }
public void Init(MultigridOperator op) { int D = op.Mapping.GridData.SpatialDimension; var M = op.OperatorMatrix; //M.SaveToTextFileSparse("OpMatrix2"); var MgMap = op.Mapping; this.m_mgop = op; if (!M.RowPartitioning.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Row partitioning mismatch."); } if (!M.ColPartition.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Column partitioning mismatch."); } Uidx = MgMap.ProblemMapping.GetSubvectorIndices(true, D.ForLoop(i => i)); Pidx = MgMap.ProblemMapping.GetSubvectorIndices(true, D); int Upart = Uidx.Length; int Ppart = Pidx.Length; ConvDiff = new MsrMatrix(Upart, Upart, 1, 1); pGrad = new MsrMatrix(Upart, Ppart, 1, 1); divVel = new MsrMatrix(Ppart, Upart, 1, 1); var PxP = new MsrMatrix(Ppart, Ppart, 1, 1); M.AccSubMatrixTo(1.0, ConvDiff, Uidx, default(int[]), Uidx, default(int[])); //, default(int[]), default(int[])); M.AccSubMatrixTo(1.0, pGrad, Uidx, default(int[]), Pidx, default(int[])); //, default(int[]), default(int[])); M.AccSubMatrixTo(1.0, divVel, Pidx, default(int[]), Uidx, default(int[])); //, default(int[]), default(int[])); M.AccSubMatrixTo(1.0, PxP, Pidx, default(int[]), Pidx, default(int[])); //, default(int[]), default(int[])); Mtx = M; int L = M.RowPartitioning.LocalLength; int i0 = Mtx.RowPartitioning.i0; P = new MsrMatrix(Mtx); P.Clear(); // Debugging output //pGrad.SaveToTextFileSparse("pGrad"); //PxP.SaveToTextFileSparse("PxP"); velMassMatrix = new MsrMatrix(Upart, Upart, 1, 1); op.MassMatrix.AccSubMatrixTo(1.0, velMassMatrix, Uidx, default(int[]), Uidx, default(int[]), default(int[]), default(int[])); switch (SchurOpt) { case SchurOptions.exact: { // Building complete Schur and Approximate Schur MultidimensionalArray Poisson = MultidimensionalArray.Create(Pidx.Length, Pidx.Length); MultidimensionalArray SchurConvPart = MultidimensionalArray.Create(Pidx.Length, Pidx.Length); MultidimensionalArray Schur = MultidimensionalArray.Create(Pidx.Length, Pidx.Length); using (BatchmodeConnector bmc = new BatchmodeConnector()) { bmc.PutSparseMatrix(ConvDiff, "ConvDiff"); bmc.PutSparseMatrix(velMassMatrix, "MassMatrix"); bmc.PutSparseMatrix(divVel, "divVel"); bmc.PutSparseMatrix(pGrad, "pGrad"); bmc.Cmd("Qdiag = diag(diag(MassMatrix))"); bmc.Cmd("invT= inv(Qdiag)"); bmc.Cmd("Poisson = full(invT)*pGrad"); bmc.Cmd("ConvPart = ConvDiff*Poisson"); bmc.Cmd("ConvPart= full(invT)*ConvPart"); bmc.Cmd("ConvPart= divVel*ConvPart"); bmc.Cmd("Poisson = divVel*Poisson"); bmc.Cmd("ConvDiffInv = inv(full(ConvDiff))"); bmc.Cmd("Schur = divVel*ConvDiffInv"); bmc.Cmd("Schur = Schur*pGrad"); bmc.GetMatrix(Poisson, "Poisson"); bmc.GetMatrix(SchurConvPart, "ConvPart"); bmc.GetMatrix(Schur, "-Schur"); bmc.Execute(false); } PoissonMtx_T = Poisson.ToMsrMatrix(); PoissonMtx_H = Poisson.ToMsrMatrix(); SchurConvMtx = SchurConvPart.ToMsrMatrix(); SchurMtx = Schur.ToMsrMatrix(); SchurMtx.Acc(PxP, 1); ConvDiff.AccSubMatrixTo(1.0, P, default(int[]), Uidx, default(int[]), Uidx); pGrad.AccSubMatrixTo(1.0, P, default(int[]), Uidx, default(int[]), Pidx); SchurMtx.AccSubMatrixTo(1.0, P, default(int[]), Pidx, default(int[]), Pidx); return; } case SchurOptions.decoupledApprox: { // Do assembly for approximate Schur inverse invVelMassMatrix = velMassMatrix.CloneAs(); invVelMassMatrix.Clear(); invVelMassMatrixSqrt = invVelMassMatrix.CloneAs(); for (int i = velMassMatrix.RowPartitioning.i0; i < velMassMatrix.RowPartitioning.iE; i++) { if (ApproxScaling) { invVelMassMatrix.SetDiagonalElement(i, 1 / (velMassMatrix[i, i])); invVelMassMatrixSqrt.SetDiagonalElement(i, 1 / (Math.Sqrt(velMassMatrix[i, i]))); } else { invVelMassMatrix.SetDiagonalElement(i, 1); invVelMassMatrixSqrt.SetDiagonalElement(i, 1); } } //invVelMassMatrix.SaveToTextFileSparse("invVelMassMatrix"); //velMassMatrix.SaveToTextFileSparse("velMassMatrix"); //ConvDiffPoissonMtx = MsrMatrix.Multiply(ConvDiff, pGrad); //ConvDiffPoissonMtx = MsrMatrix.Multiply(divVel, ConvDiffPoissonMtx); // Inverse of mass matrix in Matlab //MultidimensionalArray temp = MultidimensionalArray.Create(Uidx.Length, Uidx.Length); //using (BatchmodeConnector bmc = new BatchmodeConnector()) //{ // bmc.PutSparseMatrix(velMassMatrix, "velMassMatrix"); // bmc.Cmd("invVelMassMatrix = inv(full(velMassMatrix))"); // bmc.GetMatrix(temp, "invVelMassMatrix"); // bmc.Execute(false); //} //invVelMassMatrix = temp.ToMsrMatrix(); //ConvDiffPoissonMtx = MsrMatrix.Multiply(ConvDiffPoissonMtx, PoissonMtx); //ConvDiffPoissonMtx = MsrMatrix.Multiply(PoissonMtx, ConvDiffPoissonMtx); //ConvDiff.AccSubMatrixTo(1.0, P, default(int[]), Uidx, default(int[]), Uidx); //pGrad.AccSubMatrixTo(1.0, P, default(int[]), Uidx, default(int[]), Pidx); //ConvDiffPoissonMtx.AccSubMatrixTo(1.0, P, default(int[]), Pidx, default(int[]), Pidx); //op.MassMatrix.SaveToTextFileSparse("MassMatrix"); //velMassMatrix.SaveToTextFileSparse("velMassMatrix2"); // Possion scaled by inverse of the velocity mass matrix PoissonMtx_T = MsrMatrix.Multiply(invVelMassMatrix, pGrad); PoissonMtx_T = MsrMatrix.Multiply(divVel, PoissonMtx_T); //PoissonMtx_T.Acc(PxP, 1); // p.379 // Poisson scaled by sqrt of inverse of velocity mass matrix PoissonMtx_H = MsrMatrix.Multiply(invVelMassMatrixSqrt, pGrad); PoissonMtx_H = MsrMatrix.Multiply(divVel, PoissonMtx_H); //PoissonMtx_H.Acc(PxP, 1); // p.379 return; } case SchurOptions.SIMPLE: { var invdiag_ConvDiff = ConvDiff.CloneAs(); invdiag_ConvDiff.Clear(); for (int i = ConvDiff.RowPartitioning.i0; i < ConvDiff.RowPartitioning.iE; i++) { invdiag_ConvDiff[i, i] = 1 / ConvDiff[i, i]; } simpleSchur = MsrMatrix.Multiply(invdiag_ConvDiff, pGrad); simpleSchur = MsrMatrix.Multiply(divVel, simpleSchur); return; } default: throw new NotImplementedException("SchurOption"); } //var ConvDiffInvMtx = ConvDiffInv.ToMsrMatrix(); //// x= inv(P)*b !!!!! To be done with approximate Inverse // P.SpMV(1, B, 0, X); }
public MGViz(MultigridOperator op) { m_op = op; }
public ConvergenceObserver(MultigridOperator muop, BlockMsrMatrix MassMatrix, double[] __ExactSolution, SolverFactory SF) { m_SF = SF; Setup(muop, MassMatrix, __ExactSolution); }
public ConvergenceObserver(MultigridOperator muop, BlockMsrMatrix MassMatrix, double[] __ExactSolution) { Setup(muop, MassMatrix, __ExactSolution); }
/// <summary> /// Callback routine, see <see cref="ISolverWithCallback.IterationCallback"/> or <see cref="NonlinearSolver.IterationCallback"/>. /// </summary> public void IterationCallback(int iter, double[] xI, double[] rI, MultigridOperator mgOp) { if (xI.Length != SolverOperator.Mapping.LocalLength) { throw new ArgumentException(); } if (rI.Length != SolverOperator.Mapping.LocalLength) { throw new ArgumentException(); } int Lorg = SolverOperator.BaseGridProblemMapping.LocalLength; // transform residual and solution back onto the orignal grid // ========================================================== double[] Res_Org = new double[Lorg]; double[] Sol_Org = new double[Lorg]; SolverOperator.TransformRhsFrom(Res_Org, rI); SolverOperator.TransformSolFrom(Sol_Org, xI); double[] Err_Org = Sol_Org.CloneAs(); Err_Org.AccV(-1.0, this.ExactSolution); if (TecplotOut != null) { var ErrVec = InitProblemDGFields("Err"); var ResVec = InitProblemDGFields("Res"); var SolVec = InitProblemDGFields("Sol"); ErrVec.SetV(Err_Org); ResVec.SetV(Res_Org); SolVec.SetV(Sol_Org); List <DGField> ErrResSol = new List <DGField>(); ErrResSol.AddRange(ErrVec.Mapping.Fields); ErrResSol.AddRange(ResVec.Mapping.Fields); ErrResSol.AddRange(SolVec.Mapping.Fields); Tecplot.Tecplot.PlotFields(ErrResSol, TecplotOut + "." + iter, iter, 4); PlotDecomposition(xI, TecplotOut + "-sol-decomp." + iter); PlotDecomposition(rI, TecplotOut + "-res-decomp." + iter); } // Console out // =========== double l2_RES = rI.L2NormPow2().MPISum().Sqrt(); double l2_ERR = Err_Org.L2NormPow2().MPISum().Sqrt(); Console.WriteLine("Iter: {0}\tRes: {1:0.##E-00}\tErr: {2:0.##E-00}", iter, l2_RES, l2_ERR); // decompose error and residual into orthonormal vectors // ===================================================== int L0 = DecompositionOperator.Mapping.LocalLength; double[] Err_0 = new double[L0], Res_0 = new double[L0]; DecompositionOperator.TransformSolInto(Err_Org, Err_0); DecompositionOperator.TransformRhsInto(Res_Org, Res_0); IList <double[]> Err_OrthoLevels = OrthonormalMultigridDecomposition(Err_0); IList <double[]> Res_OrthoLevels = OrthonormalMultigridDecomposition(Res_0); // compute L2 norms on each level // ============================== for (var mgop = this.DecompositionOperator; mgop != null; mgop = mgop.CoarserLevel) { int[] _Degrees = mgop.Mapping.DgDegree; double[] Resi = Res_OrthoLevels[mgop.LevelIndex]; double[] Errr = Err_OrthoLevels[mgop.LevelIndex]; int JAGG = mgop.Mapping.AggGrid.iLogicalCells.NoOfLocalUpdatedCells; for (int iVar = 0; iVar < _Degrees.Length; iVar++) { for (int p = 0; p <= _Degrees[iVar]; p++) { List <double> ResNorm = this.ResNormTrend[new Tuple <int, int, int>(mgop.LevelIndex, iVar, p)]; List <double> ErrNorm = this.ErrNormTrend[new Tuple <int, int, int>(mgop.LevelIndex, iVar, p)]; double ResNormAcc = 0.0; double ErrNormAcc = 0.0; for (int jagg = 0; jagg < JAGG; jagg++) { int[] NN = mgop.Mapping.AggBasis[iVar].ModeIndexForDegree(jagg, p, _Degrees[iVar]); foreach (int n in NN) { int idx = mgop.Mapping.LocalUniqueIndex(iVar, jagg, n); ResNormAcc += Resi[idx].Pow2(); ErrNormAcc += Errr[idx].Pow2(); } } ResNorm.Add(ResNormAcc.Sqrt()); ErrNorm.Add(ErrNormAcc.Sqrt()); } } } }