/// <summary> /// Sets level-set and solution at time (<paramref name="time"/> + <paramref name="dt"/>). /// </summary> double DelUpdateLevelset(DGField[] CurrentState, double time, double dt, double UnderRelax, bool _incremental) { // new time double t = time + dt; // project new level-set double s = 1.0; LevSet.ProjectField((x, y) => - (x - s * t).Pow2() - y.Pow2() + (2.4).Pow2()); LsTrk.UpdateTracker(incremental: _incremental); // exact solution for new timestep uEx.GetSpeciesShadowField("A").ProjectField((x, y) => x + alpha_A * t); uEx.GetSpeciesShadowField("B").ProjectField((x, y) => x + alpha_B * t); u.Clear(); u.Acc(1.0, uEx); // markieren, wo ueberhaupt A und B sind Amarker.Clear(); Bmarker.Clear(); Amarker.AccConstant(+1.0, LsTrk.Regions.GetSpeciesSubGrid("A").VolumeMask); Bmarker.AccConstant(1.0, LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask); // MPI rank MPICellRank.Clear(); MPICellRank.AccConstant(base.MPIRank); // return level-set residual return(0.0); }
private double SetUpConfiguration() { testCase.UpdateLevelSet(levelSet); levelSetTracker.UpdateTracker(__NearRegionWith: 0, incremental: false, __LevSetAllowedMovement: 2); XDGField.Clear(); XDGField.GetSpeciesShadowField("A").ProjectField( 1.0, testCase.JumpingFieldSpeciesAInitialValue, default(CellQuadratureScheme)); XDGField.GetSpeciesShadowField("B").ProjectField( 1.0, testCase.JumpingFieldSpeciesBInitialValue, default(CellQuadratureScheme)); SinglePhaseField.Clear(); SinglePhaseField.ProjectField(testCase.ContinuousFieldInitialValue); double referenceValue = testCase.Solution; if (testCase is IVolumeTestCase) { QuadRule standardRule = Grid.RefElements[0].GetQuadratureRule(2 * XDGField.Basis.Degree + 1); ScalarFieldQuadrature uncutQuadrature = new ScalarFieldQuadrature( GridData, XDGField, new CellQuadratureScheme( new FixedRuleFactory <QuadRule>(standardRule), levelSetTracker.Regions.GetCutCellSubGrid().Complement().VolumeMask), standardRule.OrderOfPrecision); uncutQuadrature.Execute(); referenceValue -= uncutQuadrature.Result; } return(referenceValue); }
/// <summary> /// Sets level-set and solution at time (<paramref name="time"/> + <paramref name="dt"/>). /// </summary> double DelUpdateLevelset(DGField[] CurrentState, double time, double dt, double UnderRelax, bool _incremental) { // new time double t = time + dt; // project new level-set double s = 1.0; LevSet.ProjectField((x, y) => - (x - s * t).Pow2() - y.Pow2() + (2.4).Pow2()); LsTrk.UpdateTracker(incremental: _incremental); LsTrk.PushStacks(); // exact solution for new timestep uXEx.GetSpeciesShadowField("A").ProjectField((x, y) => x + alpha_A * t); uXEx.GetSpeciesShadowField("B").ProjectField((x, y) => x + alpha_B * t); // uX.Clear(); //uX.Acc(1.0, uXEx); // single-phase-properties u.Clear(); u.ProjectField(NonVectorizedScalarFunction.Vectorize(uEx, t)); Grad_u.Clear(); Grad_u.Gradient(1.0, u); MagGrad_u.Clear(); MagGrad_u.ProjectFunction(1.0, (double[] X, double[] U, int jCell) => Math.Sqrt(U[0].Pow2() + U[1].Pow2()), new Foundation.Quadrature.CellQuadratureScheme(), Grad_u.ToArray()); // return level-set residual return(0.0); }
/// <summary> /// Sets level-set and solution at time (<paramref name="time"/> + <paramref name="dt"/>). /// </summary> double DelUpdateLevelset(DGField[] CurrentState, double time, double dt, double UnderRelax, bool _incremental) { // new time double t = time + dt; // project new level-set LevSet.ProjectField(this.Control.LevelSet.Vectorize(t)); LsTrk.UpdateTracker(incremental: _incremental); // exact solution for new timestep uEx.GetSpeciesShadowField("A").ProjectField(NonVectorizedScalarFunction.Vectorize(this.Control.uEx_A, t)); uEx.GetSpeciesShadowField("B").ProjectField(NonVectorizedScalarFunction.Vectorize(this.Control.uEx_B, t)); u.Clear(); u.Acc(1.0, uEx); // markieren, wo ueberhaupt A und B sind Amarker.Clear(); Bmarker.Clear(); Amarker.AccConstant(+1.0, LsTrk._Regions.GetSpeciesSubGrid("A").VolumeMask); Bmarker.AccConstant(1.0, LsTrk._Regions.GetSpeciesSubGrid("B").VolumeMask); // MPI rank MPICellRank.Clear(); MPICellRank.AccConstant(base.MPIRank); // return level-set residual return(0.0); }
public static void ProjectKineticDissipation(this XDGField proj, LevelSetTracker LsTrk, DGField[] Velocity, double[] mu, int momentFittingOrder, int HistInd = 1) { using (new FuncTrace()) { int D = LsTrk.GridDat.SpatialDimension; if (Velocity.Count() != D) { throw new ArgumentException(); } if (LsTrk.SpeciesIdS.Count != mu.Length) { throw new ArgumentException(); } var SchemeHelper = LsTrk.GetXDGSpaceMetrics(LsTrk.SpeciesIdS.ToArray(), momentFittingOrder, HistInd).XQuadSchemeHelper; for (int iSpc = 0; iSpc < LsTrk.SpeciesIdS.Count; iSpc++) { SpeciesId spcId = LsTrk.SpeciesIdS[iSpc]; double _mu = mu[iSpc]; var Uspc = Velocity.Select(u => (u as XDGField).GetSpeciesShadowField(spcId)).ToArray(); ScalarFunctionEx spcKinDissip = GetSpeciesKineticDissipationFunc(Uspc, _mu); proj.GetSpeciesShadowField(spcId).ProjectField(spcKinDissip); } } }
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); }
protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt) { dt = Control.dtFixed; Console.WriteLine("Timestep #{0}, dt = {1} ...", TimestepNo, dt); // advance level-set // ----------------- double x0 = 0.17 * (phystime + dt); this.Pressure.UpdateBehaviour = BehaveUnder_LevSetMoovement.AutoExtrapolate; this.LevSet.ProjectField((_2D)((x, y) => Phi(new[] { x, y }, x0))); this.LsTrk.PushStacks(); this.LsTrk.UpdateTracker(phystime + dt); // update markers // -------------- this.Amarker.Clear(); this.Bmarker.Clear(); this.Amarker.AccConstant(1.0, this.LsTrk.Regions.GetSpeciesMask("A")); this.Bmarker.AccConstant(1.0, this.LsTrk.Regions.GetSpeciesMask("B")); // test the auto-extrapolation // --------------------------- var RefPressure = new XDGField(this.Pressure.Basis); RefPressure.GetSpeciesShadowField("A").ProjectField(PressureExactA); RefPressure.GetSpeciesShadowField("B").ProjectField(PressureExactB); RefPressure.Acc(-1.0, Pressure); AutoExtrapolationErr = RefPressure.L2Norm(); Console.WriteLine("Error of extrapolation: " + AutoExtrapolationErr); Assert.LessOrEqual(AutoExtrapolationErr, 1.0e-8, "Error after auto-extrapolation to high."); Console.WriteLine("done."); return(dt); }
public static void ProjectKineticEnergy(this XDGField proj, LevelSetTracker LsTrk, XDGField[] Velocity, double[] rho, int momentFittingOrder, int HistInd = 1) { using (new FuncTrace()) { int D = LsTrk.GridDat.SpatialDimension; if (Velocity.Count() != D) { throw new ArgumentException(); } if (LsTrk.SpeciesIdS.Count != rho.Length) { throw new ArgumentException(); } var SchemeHelper = LsTrk.GetXDGSpaceMetrics(LsTrk.SpeciesIdS.ToArray(), momentFittingOrder, HistInd).XQuadSchemeHelper; for (int iSpc = 0; iSpc < LsTrk.SpeciesIdS.Count; iSpc++) { SpeciesId spcId = LsTrk.SpeciesIdS[iSpc]; double _rho = rho[iSpc]; var Uspc = Velocity.Select(u => (u as XDGField).GetSpeciesShadowField(spcId)).ToArray(); //ScalarFunctionEx spcKinDissip = GetSpeciesKineticDissipationFunc(Uspc, _rho); ScalarFunctionEx spcKinEnergy = delegate(int i0, int Len, NodeSet nds, MultidimensionalArray result) { int K = result.GetLength(1); // No nof Nodes MultidimensionalArray U_res = MultidimensionalArray.Create(Len, K, D); for (int i = 0; i < D; i++) { Uspc[i].Evaluate(i0, Len, nds, U_res.ExtractSubArrayShallow(-1, -1, i)); } double acc; for (int j = 0; j < Len; j++) { for (int k = 0; k < K; k++) { acc = 0.0; for (int d = 0; d < D; d++) { acc += U_res[j, k, d] * U_res[j, k, d]; } result[j, k] = _rho * acc / 2.0; } } }; proj.GetSpeciesShadowField(spcId).ProjectField(spcKinEnergy); } } }
static void SetTestValue(XDGField Xf, IDictionary <SpeciesId, double> mod) { var Tracker = Xf.Basis.Tracker; foreach (var S in Tracker.SpeciesIdS) { var f = Xf.GetSpeciesShadowField(S); SetTestValue(f); f.Scale(mod[S]); //f.AccConstant(accVal[S]); } }
/// <summary> /// Injects an XDG field from a coarsr grid to a fine grid. /// </summary> public static XDGField InjectXDGField(int[] Fine2Coarse, XDGField injected, XDGField cors_field, CellMask subGrd = null) { var trk = injected.Basis.Tracker; foreach (var spc in trk.SpeciesIdS) { var grd = trk.Regions.GetSpeciesMask(spc); InjectDGField(Fine2Coarse, injected.GetSpeciesShadowField(spc), cors_field.GetSpeciesShadowField(spc), subGrd == null ? grd : grd.Intersect(subGrd)); } return(injected); }
/// <summary> /// Calculates the Torque around the center of mass /// </summary> /// <param name="U"></param> /// <param name="P"></param> /// <param name="momentFittingVariant"></param> /// <param name="muA"></param> /// <param name="particleRadius"></param> /// <returns></returns> static public void GetCellValues(VectorField <XDGField> U, XDGField P, double muA, double particleRadius, SinglePhaseField P_atIB, SinglePhaseField gradU_atIB, SinglePhaseField gradUT_atIB) { var LsTrk = U[0].Basis.Tracker; int D = LsTrk.GridDat.SpatialDimension; var UA = U.Select(u => u.GetSpeciesShadowField("A")).ToArray(); if (D > 2) { throw new NotImplementedException("Currently only 2D cases supported"); } int RequiredOrder = U[0].Basis.Degree * 3 + 2; //if (RequiredOrder > agg.HMForder) // throw new ArgumentException(); Console.WriteLine("Cell values calculated by: {0}, order = {1}", LsTrk.CutCellQuadratureType, RequiredOrder); ConventionalDGField pA = null; double circumference = new double(); pA = P.GetSpeciesShadowField("A"); for (int n = 0; n < 4; n++) { ScalarFunctionEx ErrFunc_CellVal = delegate(int j0, int Len, NodeSet Ns, MultidimensionalArray result) { int K = result.GetLength(1); // No nof Nodes MultidimensionalArray Grad_UARes = MultidimensionalArray.Create(Len, K, D, D);; MultidimensionalArray pARes = MultidimensionalArray.Create(Len, K); // Evaluate tangential velocity to level-set surface var Normals = LsTrk.DataHistories[0].Current.GetLevelSetNormals(Ns, j0, Len); for (int i = 0; i < D; i++) { UA[i].EvaluateGradient(j0, Len, Ns, Grad_UARes.ExtractSubArrayShallow(-1, -1, i, -1)); } pA.Evaluate(j0, Len, Ns, pARes); for (int j = 0; j < Len; j++) { for (int k = 0; k < K; k++) { double acc = 0.0; double acc2 = 0.0; switch (n) { case 0: // Pressure part acc += pARes[j, k] * Normals[j, k, 0]; acc *= -Normals[j, k, 1] * particleRadius; acc2 += pARes[j, k] * Normals[j, k, 1]; acc2 *= Normals[j, k, 0] * particleRadius; result[j, k] = acc + acc2; break; case 1: // GradU part acc -= (1 * muA) * Grad_UARes[j, k, 0, 0] * Normals[j, k, 0]; // Attention was 2 times acc -= (muA) * Grad_UARes[j, k, 0, 1] * Normals[j, k, 1]; acc *= -Normals[j, k, 1] * particleRadius; acc2 -= (1 * muA) * Grad_UARes[j, k, 1, 1] * Normals[j, k, 1]; acc2 -= (muA) * Grad_UARes[j, k, 1, 0] * Normals[j, k, 0]; acc2 *= Normals[j, k, 0] * particleRadius; result[j, k] = acc + acc2; break; case 2: // GradU_T part acc -= (1 * muA) * Grad_UARes[j, k, 0, 0] * Normals[j, k, 0]; // Attention was 2 times acc -= (muA) * Grad_UARes[j, k, 1, 0] * Normals[j, k, 1]; acc *= -Normals[j, k, 1] * particleRadius; acc2 -= (1 * muA) * Grad_UARes[j, k, 1, 1] * Normals[j, k, 1]; // Attention was 2 times acc2 -= (muA) * Grad_UARes[j, k, 0, 1] * Normals[j, k, 0]; acc2 *= Normals[j, k, 0] * particleRadius; result[j, k] = acc + acc2; break; case 3: // Standardization with radians result[j, k] = 1; break; default: throw new NotImplementedException(); } } } }; var SchemeHelper = LsTrk.GetXDGSpaceMetrics(new[] { LsTrk.GetSpeciesId("A") }, RequiredOrder, 1).XQuadSchemeHelper; // new XQuadSchemeHelper(LsTrk, momentFittingVariant, ); CellQuadratureScheme cqs = SchemeHelper.GetLevelSetquadScheme(0, LsTrk.Regions.GetCutCellMask()); CellQuadrature.GetQuadrature(new int[] { 1 }, LsTrk.GridDat, cqs.Compile(LsTrk.GridDat, RequiredOrder), delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) { ErrFunc_CellVal(i0, Length, QR.Nodes, EvalResult.ExtractSubArrayShallow(-1, -1, 0)); }, delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { for (int i = 0; i < Length; i++) { switch (n) { case 0: P_atIB.SetMeanValue(i0, ResultsOfIntegration[i, 0]); break; case 1: gradU_atIB.SetMeanValue(i0, ResultsOfIntegration[i, 0]); break; case 2: gradUT_atIB.SetMeanValue(i0, ResultsOfIntegration[i, 0]); break; case 3: circumference += ResultsOfIntegration[i, 0]; P_atIB.SetMeanValue(i0, P_atIB.GetMeanValue(i0) / ResultsOfIntegration[i, 0]); gradU_atIB.SetMeanValue(i0, gradU_atIB.GetMeanValue(i0) / ResultsOfIntegration[i, 0]); gradUT_atIB.SetMeanValue(i0, gradUT_atIB.GetMeanValue(i0) / ResultsOfIntegration[i, 0]); break; default: throw new NotImplementedException(); } } } ).Execute(); } Console.WriteLine("Circle circumference: " + circumference); }
public static ScalarFunctionEx GetEnergyJumpFunc(LevelSetTracker LsTrk, VectorField <XDGField> Velocity, XDGField Pressure, double muA, double muB, bool squared) { var UA = Velocity.Select(u => u.GetSpeciesShadowField("A")).ToArray(); var UB = Velocity.Select(u => u.GetSpeciesShadowField("B")).ToArray(); ConventionalDGField pA = null, pB = null; bool UsePressure = Pressure != null; if (UsePressure) { pA = Pressure.GetSpeciesShadowField("A"); pB = Pressure.GetSpeciesShadowField("B"); } int D = LsTrk.GridDat.SpatialDimension; ScalarFunctionEx EnergyJumpFunc = delegate(int j0, int Len, NodeSet Ns, MultidimensionalArray result) { int K = result.GetLength(1); // No nof Nodes MultidimensionalArray UA_res = MultidimensionalArray.Create(Len, K, D); MultidimensionalArray UB_res = MultidimensionalArray.Create(Len, K, D); MultidimensionalArray GradUA_res = MultidimensionalArray.Create(Len, K, D, D); MultidimensionalArray GradUB_res = MultidimensionalArray.Create(Len, K, D, D); MultidimensionalArray pA_res = MultidimensionalArray.Create(Len, K); MultidimensionalArray pB_res = MultidimensionalArray.Create(Len, K); for (int i = 0; i < D; i++) { UA[i].Evaluate(j0, Len, Ns, UA_res.ExtractSubArrayShallow(-1, -1, i)); UB[i].Evaluate(j0, Len, Ns, UB_res.ExtractSubArrayShallow(-1, -1, i)); UA[i].EvaluateGradient(j0, Len, Ns, GradUA_res.ExtractSubArrayShallow(-1, -1, i, -1)); UB[i].EvaluateGradient(j0, Len, Ns, GradUB_res.ExtractSubArrayShallow(-1, -1, i, -1)); } if (UsePressure) { pA.Evaluate(j0, Len, Ns, pA_res); pB.Evaluate(j0, Len, Ns, pB_res); } else { pA_res.Clear(); pB_res.Clear(); } var Normals = LsTrk.DataHistories[0].Current.GetLevelSetNormals(Ns, j0, Len); for (int j = 0; j < Len; j++) { for (int k = 0; k < K; k++) { double acc = 0.0; for (int d = 0; d < D; d++) { // pressure if (UsePressure) { acc += (pB_res[j, k] * UB_res[j, k, d] - pA_res[j, k] * UA_res[j, k, d]) * Normals[j, k, d]; } // Nabla U + (Nabla U) ^T for (int dd = 0; dd < D; dd++) { acc -= (muB * GradUB_res[j, k, d, dd] * UB_res[j, k, dd] - muA * GradUA_res[j, k, d, dd] * UA_res[j, k, dd]) * Normals[j, k, d]; acc -= (muB * GradUB_res[j, k, dd, d] * UB_res[j, k, dd] - muA * GradUA_res[j, k, dd, d] * UA_res[j, k, dd]) * Normals[j, k, d]; // Transposed Term } } if (squared) { result[j, k] = acc.Pow2(); } else { result[j, k] = acc; } } } }; return(EnergyJumpFunc); }
static ScalarFunctionEx GetEnergyBalanceFunc(XDGField P, VectorField <XDGField> U, ConventionalDGField[] Umean, SinglePhaseField C, double muA, double muB, double sigma, bool squared) { int D = P.Basis.GridDat.SpatialDimension; ConventionalDGField pA = P.GetSpeciesShadowField("A"); ConventionalDGField pB = P.GetSpeciesShadowField("B"); var UA = U.Select(u => u.GetSpeciesShadowField("A")).ToArray(); var UB = U.Select(u => u.GetSpeciesShadowField("B")).ToArray(); return(delegate(int i0, int Len, NodeSet nds, MultidimensionalArray result) { int K = result.GetLength(1); // No nof Nodes MultidimensionalArray pA_res = MultidimensionalArray.Create(Len, K); MultidimensionalArray pB_res = MultidimensionalArray.Create(Len, K); MultidimensionalArray UA_res = MultidimensionalArray.Create(Len, K, D); MultidimensionalArray UB_res = MultidimensionalArray.Create(Len, K, D); MultidimensionalArray GradUA_res = MultidimensionalArray.Create(Len, K, D, D); MultidimensionalArray GradUB_res = MultidimensionalArray.Create(Len, K, D, D); MultidimensionalArray U_res = MultidimensionalArray.Create(Len, K, D); MultidimensionalArray GradU_res = MultidimensionalArray.Create(Len, K, D, D); MultidimensionalArray Curv_res = MultidimensionalArray.Create(Len, K); pA.Evaluate(i0, Len, nds, pA_res); pB.Evaluate(i0, Len, nds, pB_res); for (int i = 0; i < D; i++) { UA[i].Evaluate(i0, Len, nds, UA_res.ExtractSubArrayShallow(-1, -1, i)); UB[i].Evaluate(i0, Len, nds, UB_res.ExtractSubArrayShallow(-1, -1, i)); Umean[i].Evaluate(i0, Len, nds, U_res.ExtractSubArrayShallow(-1, -1, i)); UA[i].EvaluateGradient(i0, Len, nds, GradUA_res.ExtractSubArrayShallow(-1, -1, i, -1)); UB[i].EvaluateGradient(i0, Len, nds, GradUB_res.ExtractSubArrayShallow(-1, -1, i, -1)); Umean[i].EvaluateGradient(i0, Len, nds, GradU_res.ExtractSubArrayShallow(-1, -1, i, -1)); } C.Evaluate(i0, Len, nds, Curv_res); var Normals = P.Basis.Tracker.DataHistories[0].Current.GetLevelSetNormals(nds, i0, Len); for (int j = 0; j < Len; j++) { for (int k = 0; k < K; k++) { double acc = 0.0; for (int d = 0; d < D; d++) { // enrgy jump at interface acc -= (pB_res[j, k] * UB_res[j, k, d] - pA_res[j, k] * UA_res[j, k, d]) * Normals[j, k, d]; for (int dd = 0; dd < D; dd++) { acc += (muB * GradUB_res[j, k, d, dd] * UB_res[j, k, dd] - muA * GradUA_res[j, k, d, dd] * UA_res[j, k, dd]) * Normals[j, k, d]; acc += (muB * GradUB_res[j, k, dd, d] * UB_res[j, k, dd] - muA * GradUA_res[j, k, dd, d] * UA_res[j, k, dd]) * Normals[j, k, d]; // Transposed Term } // surface energy changerate //for (int dd = 0; dd < D; dd++) { // if (dd == d) { // acc += sigma * (1 - Normals[j, k, d] * Normals[j, k, dd]) * GradU_res[j, k, dd, d]; // } else { // acc += sigma * (-Normals[j, k, d] * Normals[j, k, dd]) * GradU_res[j, k, dd, d]; // } //} // curvature energy acc -= sigma * Curv_res[j, k] * U_res[j, k, d] * Normals[j, k, d]; } if (squared) { result[j, k] = acc.Pow2(); } else { result[j, k] = acc; } } } }); }
protected override void SetInitial() { base.SetInitial(); this.CreateEquationsAndSolvers(null); if (this.Control.MultiStepInit == true) { int CallCount = 0; if (m_RK_Timestepper != null) { throw new NotSupportedException(); } m_BDF_Timestepper.MultiInit(0.0, 0, this.Control.GetFixedTimestep(), delegate(int TimestepIndex, double Time, DGField[] St) { Console.WriteLine("Timestep index {0}, time {1} ", TimestepIndex, Time); // level-set // --------- this.Phi.ProjectField(X => this.Control.Phi(X, Time)); // HMF hacks 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(Time) }; } if (CallCount == 0) { this.LsTrk.UpdateTracker(); } else { this.LsTrk.UpdateTracker(incremental: true); } CallCount++; // solution // -------- XDGField _u = (XDGField)St[0]; _u.Clear(); _u.GetSpeciesShadowField("A").ProjectField((X => this.Control.uA_Ex(X, Time))); _u.GetSpeciesShadowField("B").ProjectField((X => this.Control.uB_Ex(X, Time))); }); } else { this.Phi.ProjectField(X => this.Control.Phi(X, 0.0)); this.LsTrk.UpdateTracker(); u.Clear(); u.GetSpeciesShadowField("A").ProjectField((X => this.Control.uA_Ex(X, 0.0))); u.GetSpeciesShadowField("B").ProjectField((X => this.Control.uB_Ex(X, 0.0))); if (m_BDF_Timestepper != null) { m_BDF_Timestepper.SingleInit(); } } }
/// <summary> /// Checks MPI exchange /// </summary> void CheckExchange(bool ExchangeShadow) { // its important to test more than one field! var xf = new XDGField(new XDGBasis(this.LsTrk, 0), "xf"); var xf2 = new XDGField(new XDGBasis(this.LsTrk, 0), "xf2"); int J = this.GridData.iLogicalCells.NoOfLocalUpdatedCells; int JE = this.GridData.iLogicalCells.Count; //long[] GiD = this.GridData.CurrentGlobalIdPermutation.Values; long GetGid(int j) { return(this.GridData.iLogicalCells.GetGlobalID(j)); } { var st = new SinglePhaseField(new Basis(this.GridData, 1), "muh"); for (int j = 0; j < J; j++) { st.Coordinates[j, 0] = GetGid(j); } var trx = new BoSSS.Foundation.Comm.Transceiver(st); trx.TransceiveStartImReturn(); trx.TransceiveFinish(); for (int j = 0; j < JE; j++) { double should = GetGid(j); Assert.IsTrue(st.Coordinates[j, 0] == should, "everything is f****d"); } } // --------------------- foreach (string s in this.LsTrk.SpeciesNames) { double sv = s[0] * 0.01; var xfs = xf.GetSpeciesShadowField(s); var xfs2 = xf2.GetSpeciesShadowField(s); for (int j = 0; j < J; j++) { xfs.Coordinates[j, 0] = GetGid(j) + sv; xfs2.Coordinates[j, 0] = 1.0e5 + GetGid(j) + sv; } } double[] xfB4 = xf.CoordinateVector.ToArray(); double[] xf2B4 = xf2.CoordinateVector.ToArray(); // --------------------- if (ExchangeShadow) { // exchange shadow fields separately foreach (string s in this.LsTrk.SpeciesNames) { var xfs = xf.GetSpeciesShadowField(s); var xfs2 = xf2.GetSpeciesShadowField(s); //var xfsCopy = new SinglePhaseField(xfs.Basis, "muh"); //xfsCopy.Acc(1.0, xfs); //dd.Add(s, xfsCopy); var trx = new BoSSS.Foundation.Comm.Transceiver(xfs, xfs2); trx.TransceiveStartImReturn(); trx.TransceiveFinish(); } } else { // exchange XDG fields var trx2 = new BoSSS.Foundation.Comm.Transceiver(xf, xf2); trx2.TransceiveStartImReturn(); trx2.TransceiveFinish(); } foreach (string s in this.LsTrk.SpeciesNames) { double sv = s[0] * 0.01; var xfs = xf.GetSpeciesShadowField(s); var xfs2 = xf2.GetSpeciesShadowField(s); for (int j = 0; j < JE; j++) { double should = GetGid(j) + sv; double should2 = 1.0e5 + GetGid(j) + sv; string nerv = ExchangeShadow ? "shadow" : "XDG"; Assert.IsTrue(xfs.Coordinates[j, 0] == 0.0 || xfs.Coordinates[j, 0] == should, $"error in MPI exchange of {nerv} fields"); Assert.IsTrue(xfs2.Coordinates[j, 0] == 0.0 || xfs2.Coordinates[j, 0] == should2, $"error in MPI exchange of {nerv} fields (2nd field)"); } } }
protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt) { Console.WriteLine(" Timestep # " + TimestepNo + ", phystime = " + phystime); //phystime = 1.8; LsUpdate(phystime); // operator-matrix assemblieren MsrMatrix OperatorMatrix = new MsrMatrix(u.Mapping, u.Mapping); double[] Affine = new double[OperatorMatrix.RowPartitioning.LocalLength]; // Agglomerator setup MultiphaseCellAgglomerator Agg = LsTrk.GetAgglomerator(new SpeciesId[] { LsTrk.GetSpeciesId("B") }, QuadOrder, this.THRESHOLD); // plausibility of cell length scales if (SER_PAR_COMPARISON) { TestLengthScales(QuadOrder, TimestepNo); } Console.WriteLine("Inter-Process agglomeration? " + Agg.GetAgglomerator(LsTrk.GetSpeciesId("B")).AggInfo.InterProcessAgglomeration); if (this.THRESHOLD > 0.01) { TestAgglomeration_Extraploation(Agg); TestAgglomeration_Projection(QuadOrder, Agg); } CheckExchange(true); CheckExchange(false); // operator matrix assembly XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Op.GetMatrixBuilder(base.LsTrk, u.Mapping, null, u.Mapping); mtxBuilder.time = 0.0; mtxBuilder.ComputeMatrix(OperatorMatrix, Affine); Agg.ManipulateMatrixAndRHS(OperatorMatrix, Affine, u.Mapping, u.Mapping); // mass matrix factory var Mfact = LsTrk.GetXDGSpaceMetrics(new SpeciesId[] { LsTrk.GetSpeciesId("B") }, QuadOrder, 1).MassMatrixFactory;// new MassMatrixFactory(u.Basis, Agg); // Mass matrix/Inverse Mass matrix //var MassInv = Mfact.GetMassMatrix(u.Mapping, new double[] { 1.0 }, true, LsTrk.GetSpeciesId("B")); var Mass = Mfact.GetMassMatrix(u.Mapping, new double[] { 1.0 }, false, LsTrk.GetSpeciesId("B")); Agg.ManipulateMatrixAndRHS(Mass, default(double[]), u.Mapping, u.Mapping); var MassInv = Mass.InvertBlocks(OnlyDiagonal: true, Subblocks: true, ignoreEmptyBlocks: true, SymmetricalInversion: false); // test that operator depends only on B-species values double DepTest = LsTrk.Regions.GetSpeciesSubGrid("B").TestMatrixDependency(OperatorMatrix, u.Mapping, u.Mapping); Console.WriteLine("Matrix dependency test: " + DepTest); Assert.LessOrEqual(DepTest, 0.0); // diagnostic output Console.WriteLine("Number of Agglomerations (all species): " + Agg.TotalNumberOfAgglomerations); Console.WriteLine("Number of Agglomerations (species 'B'): " + Agg.GetAgglomerator(LsTrk.GetSpeciesId("B")).AggInfo.SourceCells.NoOfItemsLocally.MPISum()); // operator auswerten: double[] x = new double[Affine.Length]; BLAS.daxpy(x.Length, 1.0, Affine, 1, x, 1); OperatorMatrix.SpMVpara(1.0, u.CoordinateVector, 1.0, x); MassInv.SpMV(1.0, x, 0.0, du_dx.CoordinateVector); Agg.GetAgglomerator(LsTrk.GetSpeciesId("B")).Extrapolate(du_dx.Mapping); // markieren, wo ueberhaupt A und B sind Bmarker.AccConstant(1.0, LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask); Amarker.AccConstant(+1.0, LsTrk.Regions.GetSpeciesSubGrid("A").VolumeMask); if (usePhi0 && usePhi1) { Xmarker.AccConstant(+1.0, LsTrk.Regions.GetSpeciesSubGrid("X").VolumeMask); } // compute error ERR.Clear(); ERR.Acc(1.0, du_dx_Exact, LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask); ERR.Acc(-1.0, du_dx, LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask); double L2Err = ERR.L2Norm(LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask); Console.WriteLine("L2 Error: " + L2Err); XERR.Clear(); XERR.GetSpeciesShadowField("B").Acc(1.0, ERR, LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask); double xL2Err = XERR.L2Norm(); Console.WriteLine("L2 Error (in XDG space): " + xL2Err); // check error double ErrorThreshold = 1.0e-1; if (this.MomentFittingVariant == XQuadFactoryHelper.MomentFittingVariants.OneStepGaussAndStokes) { ErrorThreshold = 1.0e-6; // HMF is designed for such integrands and should perform close to machine accuracy; on general integrands, the precision is different. } bool IsPassed = ((L2Err <= ErrorThreshold || this.THRESHOLD <= ErrorThreshold) && xL2Err <= ErrorThreshold); if (IsPassed) { Console.WriteLine("Test PASSED"); } else { Console.WriteLine("Test FAILED: check errors."); //PlotCurrentState(phystime, TimestepNo, 3); } if (TimestepNo > 1) { if (this.THRESHOLD > ErrorThreshold) { // without agglomeration, the error in very tiny cut-cells may be large over the whole cell // However, the error in the XDG-space should be small under all circumstances Assert.LessOrEqual(L2Err, ErrorThreshold, "DG L2 error of computing du_dx"); } Assert.LessOrEqual(xL2Err, ErrorThreshold, "XDG L2 error of computing du_dx"); } // return/Ende base.NoOfTimesteps = 17; //base.NoOfTimesteps = 2; dt = 0.3; return(dt); }
public static void XDG_ProlongationTest( [Values(0, 1, 2, 3)] int p, [Values(0.0, 0.3)] double AggregationThreshold, [Values(0, 1)] int TrackerWidth, [Values(MultigridOperator.Mode.Eye, MultigridOperator.Mode.IdMass)] MultigridOperator.Mode mode) { XQuadFactoryHelper.MomentFittingVariants variant = XQuadFactoryHelper.MomentFittingVariants.OneStepGaussAndStokes; var xt = new XDGTestSetup(p, AggregationThreshold, TrackerWidth, MultigridOperator.Mode.Eye, variant //, ((Func<double[], double>)(X => X[0] + 0.75)).Vectorize() ); int Jup = grid.Cells.NoOfLocalUpdatedCells; Random rnd = new Random(); int Ltop = xt.XdgMultigridOp.Mapping.LocalLength; // Number of DOF's on top multigrid level. double[] RndVec = Ltop.ForLoop(i => rnd.NextDouble()); double[] NoJmpVec = new double[Ltop]; for (int iLevel = 0; iLevel < MgSeq.Length - 1; iLevel++) { XDG_Recursive(0, iLevel, xt.XdgMultigridOp, RndVec, NoJmpVec); // restrict RndVec downt to level 'iLevel', and back up // right now, the XDG field defined by 'NoJmpVec' should be a member // of the aggregated XDG space on level 'iLevel'; // so, there should be no inter-element jumps on the fine level, for each aggregated cell. // Let's test that! XDGField Test = new XDGField(xt.XB, "Test"); xt.XdgMultigridOp.TransformSolFrom(Test.CoordinateVector, NoJmpVec); //xt.agg.Extrapolate(Test.Mapping); var aggGrd = MgSeq[iLevel]; foreach (var spc in xt.LsTrk.SpeciesIdS) { var Test_spc = Test.GetSpeciesShadowField(spc); var SpcMask = xt.LsTrk.Regions.GetSpeciesMask(spc); BitArray AggSourceBitmask = xt.agg.GetAgglomerator(spc).AggInfo.SourceCells.GetBitMask(); double Err = 0; for (int jagg = 0; jagg < aggGrd.iLogicalCells.NoOfLocalUpdatedCells; jagg++) { BitArray CompCellMask = new BitArray(Jup); foreach (int jCell in aggGrd.iLogicalCells.AggregateCellToParts[jagg]) { if (!AggSourceBitmask[jCell]) { CompCellMask[jCell] = true; } } SubGrid CompCellSubGrid = new SubGrid((new CellMask(grid, CompCellMask)).Intersect(SpcMask)); Err += JumpNorm(Test_spc, CompCellSubGrid.InnerEdgesMask).Pow2(); } Console.WriteLine("prolongation jump test (level {0}, species {2}): {1}", iLevel, Err, xt.LsTrk.GetSpeciesName(spc)); Assert.LessOrEqual(Err, 1.0e-8); } } }
protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt) { Console.WriteLine(" Timestep # " + TimestepNo + ", phystime = " + phystime); //phystime = 1.8; LsUpdate(phystime); // operator-matrix assemblieren MsrMatrix OperatorMatrix = new MsrMatrix(u.Mapping, u.Mapping); double[] Affine = new double[OperatorMatrix.RowPartitioning.LocalLength]; MultiphaseCellAgglomerator Agg; MassMatrixFactory Mfact; // Agglomerator setup int quadOrder = Op.QuadOrderFunction(new int[] { u.Basis.Degree }, new int[0], new int[] { u.Basis.Degree }); //Agg = new MultiphaseCellAgglomerator(new CutCellMetrics(MomentFittingVariant, quadOrder, LsTrk, ), this.THRESHOLD, false); Agg = LsTrk.GetAgglomerator(new SpeciesId[] { LsTrk.GetSpeciesId("B") }, quadOrder, this.THRESHOLD); Console.WriteLine("Inter-Process agglomeration? " + Agg.GetAgglomerator(LsTrk.GetSpeciesId("B")).AggInfo.InterProcessAgglomeration); if (this.THRESHOLD > 0.01) { TestAgglomeration_Extraploation(Agg); TestAgglomeration_Projection(quadOrder, Agg); } // operator matrix assembly Op.ComputeMatrixEx(LsTrk, u.Mapping, null, u.Mapping, OperatorMatrix, Affine, false, 0.0, true, Agg.CellLengthScales, LsTrk.GetSpeciesId("B")); Agg.ManipulateMatrixAndRHS(OperatorMatrix, Affine, u.Mapping, u.Mapping); // mass matrix factory Mfact = LsTrk.GetXDGSpaceMetrics(new SpeciesId[] { LsTrk.GetSpeciesId("B") }, quadOrder, 1).MassMatrixFactory;// new MassMatrixFactory(u.Basis, Agg); // Mass matrix/Inverse Mass matrix //var MassInv = Mfact.GetMassMatrix(u.Mapping, new double[] { 1.0 }, true, LsTrk.GetSpeciesId("B")); var Mass = Mfact.GetMassMatrix(u.Mapping, new double[] { 1.0 }, false, LsTrk.GetSpeciesId("B")); Agg.ManipulateMatrixAndRHS(Mass, default(double[]), u.Mapping, u.Mapping); var MassInv = Mass.InvertBlocks(OnlyDiagonal: true, Subblocks: true, ignoreEmptyBlocks: true, SymmetricalInversion: false); // test that operator depends only on B-species values double DepTest = LsTrk.Regions.GetSpeciesSubGrid("B").TestMatrixDependency(OperatorMatrix, u.Mapping, u.Mapping); Console.WriteLine("Matrix dependency test: " + DepTest); Assert.LessOrEqual(DepTest, 0.0); // diagnostic output Console.WriteLine("Number of Agglomerations (all species): " + Agg.TotalNumberOfAgglomerations); Console.WriteLine("Number of Agglomerations (species 'B'): " + Agg.GetAgglomerator(LsTrk.GetSpeciesId("B")).AggInfo.SourceCells.NoOfItemsLocally.MPISum()); // operator auswerten: double[] x = new double[Affine.Length]; BLAS.daxpy(x.Length, 1.0, Affine, 1, x, 1); OperatorMatrix.SpMVpara(1.0, u.CoordinateVector, 1.0, x); MassInv.SpMV(1.0, x, 0.0, du_dx.CoordinateVector); Agg.GetAgglomerator(LsTrk.GetSpeciesId("B")).Extrapolate(du_dx.Mapping); // markieren, wo ueberhaupt A und B sind Bmarker.AccConstant(1.0, LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask); Amarker.AccConstant(+1.0, LsTrk.Regions.GetSpeciesSubGrid("A").VolumeMask); Xmarker.AccConstant(+1.0, LsTrk.Regions.GetSpeciesSubGrid("X").VolumeMask); // compute error ERR.Clear(); ERR.Acc(1.0, du_dx_Exact, LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask); ERR.Acc(-1.0, du_dx, LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask); double L2Err = ERR.L2Norm(LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask); Console.WriteLine("L2 Error: " + L2Err); XERR.Clear(); XERR.GetSpeciesShadowField("B").Acc(1.0, ERR, LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask); double xL2Err = XERR.L2Norm(); Console.WriteLine("L2 Error (in XDG space): " + xL2Err); // check error if (this.THRESHOLD > 0.01) { // without agglomeration, the error in very tiny cut-cells may be large over the whole cell // However, the error in the XDG-space should be small under all circumstances Assert.LessOrEqual(L2Err, 1.0e-6); } Assert.LessOrEqual(xL2Err, 1.0e-6); bool IsPassed = ((L2Err <= 1.0e-6 || this.THRESHOLD <= 0.01) && xL2Err <= 1.0e-7); if (IsPassed) { Console.WriteLine("Test PASSED"); } else { Console.WriteLine("Test FAILED: check errors."); } // return/Ende base.NoOfTimesteps = 17; //base.NoOfTimesteps = 2; dt = 0.3; return(dt); }