/// <summary> /// Setting initial value. /// </summary> protected override void SetInitial() { TestData.ProjectField(TestDataFunc); DelUpdateLevelset(new DGField[] { uX }, 0.0, 0.0, 1.0, false); uX.ProjectField((x, y) => 1.0); // check error double L2err = TestData.L2Error(TestDataFunc); Console.WriteLine("Projection error from old to new grid: " + L2err); Assert.LessOrEqual(L2err, 1.0e-8, "Projection error of test field to high."); }
protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt) { using (new FuncTrace()) { // Elo Console.WriteLine(" Timestep # " + TimestepNo + ", phystime = " + phystime + " ... "); // timestepping params base.NoOfTimesteps = 100; dt = Math.PI * 2 / base.NoOfTimesteps; base.NoOfTimesteps = 20; //UpdateBaseGrid(phystime + dt); //UpdateRefinedGrid(phystime + dt, TimestepNo); DelUpdateLevelset(new DGField[] { uX }, phystime, dt, 1.0, false); // check error double L2err = TestData.L2Error(TestDataFunc); Console.WriteLine("Projection error from old to new grid: " + L2err); Assert.LessOrEqual(L2err, 1.0e-8, "Projection error from old to new grid to high."); // return //base.TerminationKey = true; return(dt); } }
/// <summary> /// Calculate A Level-Set field from the Explicit description /// </summary> /// <param name="LevelSet">Target Field</param> /// <param name="LsTrk"></param> public void ProjectToDGLevelSet(SinglePhaseField LevelSet, LevelSetTracker LsTrk = null) { CellMask VolMask; if (LsTrk == null) { VolMask = CellMask.GetFullMask(LevelSet.Basis.GridDat); } else { // set values in positive and negative FAR region to +1 and -1 CellMask Near = LsTrk.Regions.GetNearMask4LevSet(0, 1); CellMask PosFar = LsTrk.Regions.GetLevelSetWing(0, +1).VolumeMask.Except(Near); CellMask NegFar = LsTrk.Regions.GetLevelSetWing(0, -1).VolumeMask.Except(Near); LevelSet.Clear(PosFar); LevelSet.AccConstant(1, PosFar); LevelSet.Clear(NegFar); LevelSet.AccConstant(-1, NegFar); // project Fourier levelSet to DGfield on near field VolMask = Near; } LevelSet.Clear(VolMask); // scalar function is already vectorized for parallel execution // nodes in global coordinates LevelSet.ProjectField(1.0, PhiEvaluation(mode), new Foundation.Quadrature.CellQuadratureScheme(true, VolMask)); // check the projection error projErr_phiDG = LevelSet.L2Error( PhiEvaluation(mode), new Foundation.Quadrature.CellQuadratureScheme(true, VolMask)); //if (projErr_phiDG >= 1e-5) // Console.WriteLine("WARNING: LevelSet projection error onto PhiDG = {0}", projErr_phiDG); // project on higher degree field and take the difference //SinglePhaseField higherLevSet = new SinglePhaseField(new Basis(LevelSet.GridDat, LevelSet.Basis.Degree * 2), "higherLevSet"); //higherLevSet.ProjectField(1.0, PhiEvaluator(), new Foundation.Quadrature.CellQuadratureScheme(true, VolMask)); //double higherProjErr = higherLevSet.L2Error( // PhiEvaluator(), // new Foundation.Quadrature.CellQuadratureScheme(true, VolMask)); //Console.WriteLine("LevelSet projection error onto higherPhiDG = {0}", higherProjErr.ToString()); // check the projection from current sample points on the DGfield //MultidimensionalArray interP = MultidimensionalArray.Create(current_interfaceP.Lengths); //if (this is PolarFourierLevSet) { // interP = ((PolarFourierLevSet)this).interfaceP_cartesian; //} else { // interP = current_interfaceP; //} //projErr_interface = InterfaceProjectionError(LevelSet, current_interfaceP); //if (projErr_interface >= 1e-3) // Console.WriteLine("WARNING: Interface projection Error onto PhiDG = {0}", projErr_interface); }
void ComputeL2Error(double PhysTime) { Console.WriteLine("Phystime = " + PhysTime); if ((this.Control.CircleRadius != null) != (this.Control.CutCellQuadratureType == XQuadFactoryHelper.MomentFittingVariants.ExactCircle)) { throw new ApplicationException("Illegal HMF configuration."); } if (this.Control.CircleRadius != null) { ExactCircleLevelSetIntegration.RADIUS = new double[] { this.Control.CircleRadius(PhysTime) }; } int order = Math.Max(this.u.Basis.Degree * 3, 3); XQuadSchemeHelper schH = LsTrk.GetXDGSpaceMetrics(this.LsTrk.SpeciesIdS.ToArray(), order).XQuadSchemeHelper; var uNum_A = this.u.GetSpeciesShadowField("A"); var uNum_B = this.u.GetSpeciesShadowField("B"); double uA_Err = uNum_A.L2Error(this.Control.uA_Ex.Vectorize(PhysTime), order, schH.GetVolumeQuadScheme(this.LsTrk.GetSpeciesId("A"))); double uB_Err = uNum_B.L2Error(this.Control.uB_Ex.Vectorize(PhysTime), order, schH.GetVolumeQuadScheme(this.LsTrk.GetSpeciesId("B"))); Func <double[], double, double> uJmp_Ex = ((X, t) => this.Control.uA_Ex(X, t) - this.Control.uB_Ex(X, t)); SinglePhaseField uNumJump = new SinglePhaseField(uNum_A.Basis, "Jump"); var CC = LsTrk.Regions.GetCutCellMask(); uNumJump.Acc(+1.0, uNum_A, CC); uNumJump.Acc(-1.0, uNum_B, CC); double JmpL2Err = uNumJump.L2Error(uJmp_Ex.Vectorize(PhysTime), order, schH.GetLevelSetquadScheme(0, CC)); base.QueryHandler.ValueQuery("uA_Err", uA_Err); base.QueryHandler.ValueQuery("uB_Err", uB_Err); base.QueryHandler.ValueQuery("uJmp_Err", JmpL2Err); Console.WriteLine("L2-err at t = {0}, bulk: {1}", PhysTime, Math.Sqrt(uA_Err.Pow2() + uB_Err.Pow2())); Console.WriteLine("L2-err at t = {0}, species A: {1}", PhysTime, uA_Err); Console.WriteLine("L2-err at t = {0}, species B: {1}", PhysTime, uB_Err); Console.WriteLine("L2-err at t = {0}, Jump: {1}", PhysTime, JmpL2Err); double uA_min, uA_max, uB_min, uB_max; int dummy1, dummy2; uNum_A.GetExtremalValues(out uA_min, out uA_max, out dummy1, out dummy2, this.LsTrk.Regions.GetSpeciesMask("A")); uNum_B.GetExtremalValues(out uB_min, out uB_max, out dummy1, out dummy2, this.LsTrk.Regions.GetSpeciesMask("B")); base.QueryHandler.ValueQuery("uA_Min", uA_min); base.QueryHandler.ValueQuery("uA_Max", uA_max); base.QueryHandler.ValueQuery("uB_Min", uB_min); base.QueryHandler.ValueQuery("uB_Max", uB_max); }
/// <summary> /// calculate the curvature corresponding to the Level-Set /// </summary> /// <param name="Curvature"></param> /// <param name="LevSetGradient"></param> /// <param name="VolMask"></param> public void ProjectToDGCurvature(SinglePhaseField Curvature, out VectorField <SinglePhaseField> LevSetGradient, CellMask VolMask = null) { if (VolMask == null) { VolMask = CellMask.GetFullMask(Curvature.Basis.GridDat); } Curvature.Clear(); Curvature.ProjectField(1.0, CurvEvaluation(mode), new Foundation.Quadrature.CellQuadratureScheme(true, VolMask)); // check the projection error projErr_curv = Curvature.L2Error( CurvEvaluation(mode), new Foundation.Quadrature.CellQuadratureScheme(true, VolMask)); //if (projErr_curv >= 1e-5) // Console.WriteLine("WARNING: Curvature projection error onto PhiDG = {0}", projErr_curv); LevSetGradient = null; }
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); }