public static void XDG_MatrixPolynomialRestAndPrlgTest( [Values(0, 1, 2, 3)] int p, [Values(0.0, 0.3)] double AggregationThreshold, [Values(0, 1)] int TrackerWidth) { XQuadFactoryHelper.MomentFittingVariants variant = XQuadFactoryHelper.MomentFittingVariants.OneStepGaussAndStokes; var xt = new XDGTestSetup(p, AggregationThreshold, TrackerWidth, MultigridOperator.Mode.Eye, variant); // test matrix version of the restriction operator // ----------------------------------------------- List <MultigridMapping> MultigridMaps = new List <MultigridMapping>(); for (var mgop = xt.XdgMultigridOp; mgop != null; mgop = mgop.CoarserLevel) { MultigridMaps.Add(mgop.Mapping); } for (int iLevel = 0; iLevel < MgSeq.Length; iLevel++) { MultigridMapping mgMap = MultigridMaps[iLevel]; var XAggBasis = mgMap.AggBasis[0]; // set the test field: XDGField Test = new XDGField(xt.XB, "Test"); Random rand = new Random(); for (int i = 0; i < Test.CoordinateVector.Count; i++) { Test.CoordinateVector[i] = rand.NextDouble(); } xt.agg.ClearAgglomerated(Test.CoordinateVector, Test.Mapping); // do restriction/prolongation (Reference) double[] RestVecRef = new double[XAggBasis.LocalDim]; XAggBasis.RestictFromFullGrid(Test.CoordinateVector, RestVecRef); // and now with the matrix: BlockMsrMatrix RestMtx = new BlockMsrMatrix(mgMap, mgMap.ProblemMapping); XAggBasis.GetRestrictionMatrix(RestMtx, mgMap, 0); double[] RestVec = new double[mgMap.LocalLength]; RestMtx.SpMV(1.0, Test.CoordinateVector, 0.0, RestVec); double[] X1 = new double[xt.XdgMultigridOp.Mapping.LocalLength]; XDGField X2 = new XDGField(Test.Basis); xt.XdgMultigridOp.TransformSolInto(Test.CoordinateVector, X1); xt.XdgMultigridOp.TransformSolFrom(X2.CoordinateVector, X1); //xt.agg.Extrapolate(X2.CoordinatesAsVector, X2.Mapping); var ERR2 = Test.CloneAs(); ERR2.Acc(-1.0, X2); double ERR2Norm = ERR2.L2Norm(); //Console.WriteLine("MultigridOperator TranformInto/FransformFrom mismatch: " + ERR2Norm); Assert.LessOrEqual(ERR2Norm, 1.0e-8); // compare double ERR = 0.0; int Nmax = XAggBasis.MaximalLength; for (int jAgg = 0; jAgg < mgMap.AggGrid.iLogicalCells.NoOfLocalUpdatedCells; jAgg++) { int i0Ref = jAgg * Nmax; int i0Tst = mgMap.LocalUniqueIndex(0, jAgg, 0); int N = mgMap.GetLength(jAgg); for (int n = 0; n < N; n++) { double dist = RestVecRef[i0Ref + n] - RestVec[i0Tst + n]; ERR += dist.Pow2(); } } Console.WriteLine("Restriction matrix test (iLevel = {0}): {1}", iLevel, ERR); Assert.LessOrEqual(ERR, 1.0e-8); // double[] PrlgVecA = new double[XAggBasis.LocalDim]; double[] PrlgVecB = new double[mgMap.LocalLength]; for (int jAgg = 0; jAgg < mgMap.AggGrid.iLogicalCells.NoOfLocalUpdatedCells; jAgg++) { int i0Ref = jAgg * Nmax; int i0Tst = mgMap.LocalUniqueIndex(0, jAgg, 0); int N = mgMap.GetLength(jAgg); for (int n = 0; n < N; n++) { double rndVal = rand.NextDouble(); PrlgVecA[i0Ref + n] = rndVal; PrlgVecB[i0Tst + n] = rndVal; } } XDGField QA = new XDGField(Test.Basis); XDGField QB = new XDGField(Test.Basis); XAggBasis.ProlongateToFullGrid(QA.CoordinateVector, PrlgVecA); var PrlgMtx = RestMtx.Transpose(); PrlgMtx.SpMV(1.0, PrlgVecB, 0.0, QB.CoordinateVector); XDGField ERR5 = QA.CloneAs(); ERR5.Acc(-1.0, QB); double ERR5_Norm = ERR5.L2Norm(); Console.WriteLine("Prolongation matrix test (iLevel = {0}): {1}", iLevel, ERR5_Norm); Assert.LessOrEqual(ERR5_Norm, 1.0e-8); } }