void TestAgglomeration_Extraploation(MultiphaseCellAgglomerator Agg) { _2D SomePolynomial; if (this.u.Basis.Degree == 0) { SomePolynomial = (x, y) => 3.2; } else if (this.u.Basis.Degree == 1) { SomePolynomial = (x, y) => 3.2 + x - 2.4 * y; } else { SomePolynomial = (x, y) => x * x + y * y; } // ======================================================== // extrapolate polynomial function for species B of a XDG-field // ======================================================== var Bmask = LsTrk.Regions.GetSpeciesMask("B"); XDGField xt = new XDGField(new XDGBasis(this.LsTrk, this.u.Basis.Degree), "XDG-test"); xt.GetSpeciesShadowField("B").ProjectField(1.0, SomePolynomial.Vectorize(), new CellQuadratureScheme(true, Bmask)); double[] bkupVec = xt.CoordinateVector.ToArray(); Agg.ClearAgglomerated(xt.Mapping); Agg.Extrapolate(xt.Mapping); double Err = GenericBlas.L2DistPow2(bkupVec, xt.CoordinateVector).MPISum().Sqrt(); Console.WriteLine("Agglom: extrapolation error: " + Err); Assert.LessOrEqual(Err, 1.0e-10); // ======================================================== // extrapolate polynomial function for a single-phase-field // ======================================================== SinglePhaseField xt2 = new SinglePhaseField(this.u.Basis, "DG-test"); xt2.ProjectField(SomePolynomial); double[] bkupVec2 = xt2.CoordinateVector.ToArray(); Agg.ClearAgglomerated(xt2.Mapping); Agg.Extrapolate(xt2.Mapping); double Err2 = GenericBlas.L2DistPow2(bkupVec, xt.CoordinateVector).MPISum().Sqrt(); Console.WriteLine("Agglom: extrapolation error: " + Err2); Assert.LessOrEqual(Err2, 1.0e-10); }
void TestAgglomeration_Projection(int quadOrder, MultiphaseCellAgglomerator Agg) { var Bmask = LsTrk.Regions.GetSpeciesMask("B"); var BbitMask = Bmask.GetBitMask(); var XDGmetrics = LsTrk.GetXDGSpaceMetrics(new SpeciesId[] { LsTrk.GetSpeciesId("B") }, quadOrder, 1); int degree = Math.Max(0, this.u.Basis.Degree - 1); _2D SomePolynomial; if (degree == 0) { SomePolynomial = (x, y) => 3.2; } else if (degree == 1) { SomePolynomial = (x, y) => 3.2 + x - 2.4 * y; } else { SomePolynomial = (x, y) => x * x + y * y; } // ------------------------------------------------ // project the polynomial onto a single-phase field // ------------------------------------------------ SinglePhaseField NonAgglom = new SinglePhaseField(new Basis(this.GridData, degree), "NonAgglom"); NonAgglom.ProjectField(1.0, SomePolynomial.Vectorize(), new CellQuadratureScheme(true, Bmask)); // ------------------------------------------------ // project the polynomial onto the aggomerated XDG-field // ------------------------------------------------ var qsh = XDGmetrics.XQuadSchemeHelper; // Compute the inner product of 'SomePolynomial' with the cut-cell-basis, ... SinglePhaseField xt = new SinglePhaseField(NonAgglom.Basis, "test"); xt.ProjectField(1.0, SomePolynomial.Vectorize(), qsh.GetVolumeQuadScheme(this.LsTrk.GetSpeciesId("B")).Compile(this.GridData, Agg.CutCellQuadratureOrder)); CoordinateMapping map = xt.Mapping; // ... change to the cut-cell-basis, ... double[] xVec = xt.CoordinateVector.ToArray(); Agg.ManipulateMatrixAndRHS(default(MsrMatrix), xVec, map, null); { double[] xVec2 = xVec.CloneAs(); Agg.ClearAgglomerated(xVec2, map); // clearing should have no effect now. double Err3 = GenericBlas.L2DistPow2(xVec, xVec2).MPISum().Sqrt(); Assert.LessOrEqual(Err3, 0.0); } // ... multiply with the inverse mass-matrix, ... var Mfact = XDGmetrics.MassMatrixFactory; BlockMsrMatrix MassMtx = Mfact.GetMassMatrix(map, false); Agg.ManipulateMatrixAndRHS(MassMtx, default(double[]), map, map); var InvMassMtx = MassMtx.InvertBlocks(OnlyDiagonal: true, Subblocks: true, ignoreEmptyBlocks: true, SymmetricalInversion: true); double[] xAggVec = new double[xVec.Length]; InvMassMtx.SpMV(1.0, xVec, 0.0, xAggVec); // ... and extrapolate. // Since we projected a polynomial, the projection is exact and after extrapolation, must be equal // to the polynomial. xt.CoordinateVector.SetV(xAggVec); Agg.Extrapolate(xt.Mapping); // ------------------------------------------------ // check the error // ------------------------------------------------ //double Err2 = xt.L2Error(SomePolynomial.Vectorize(), new CellQuadratureScheme(domain: Bmask)); double Err2 = NonAgglom.L2Error(xt); Console.WriteLine("Agglom: projection and extrapolation error: " + Err2); Assert.LessOrEqual(Err2, 1.0e-10); }