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 Forces acting from fluid onto the particle /// </summary> internal double[] Forces(out List <double[]>[] stressToPrintOut, CellMask cutCells) { double[] tempForces = new double[m_SpatialDim]; double[] IntegrationForces = tempForces.CloneAs(); List <double[]>[] stressToPrint = new List <double[]> [m_SpatialDim]; stressToPrint[0] = new List <double[]>(); stressToPrint[1] = new List <double[]>(); for (int d = 0; d < m_SpatialDim; d++) { void ErrFunc(int CurrentCellID, int Length, NodeSet Ns, MultidimensionalArray result) { int K = result.GetLength(1); MultidimensionalArray Grad_UARes = MultidimensionalArray.Create(Length, K, m_SpatialDim, m_SpatialDim); MultidimensionalArray pARes = MultidimensionalArray.Create(Length, K); MultidimensionalArray Normals = m_LevelSetTracker.DataHistories[0].Current.GetLevelSetNormals(Ns, CurrentCellID, Length); for (int i = 0; i < m_SpatialDim; i++) { m_U[i].EvaluateGradient(CurrentCellID, Length, Ns, Grad_UARes.ExtractSubArrayShallow(-1, -1, i, -1), 0, 1); } m_P.Evaluate(CurrentCellID, Length, Ns, pARes); for (int j = 0; j < Length; j++) { for (int k = 0; k < K; k++) { result[j, k] = StressTensor(Grad_UARes, pARes, Normals, m_FluidViscosity, k, j, m_SpatialDim, d); double t = Math.PI * (1 - Math.Sign(Normals[j, k, 1])) / 2 + Math.Acos(Normals[j, k, 0]); stressToPrint[d].Add(new double[] { t, result[j, k] }); } } } int[] noOfIntegrals = new int[] { 1 }; XQuadSchemeHelper SchemeHelper = m_LevelSetTracker.GetXDGSpaceMetrics(new[] { m_LevelSetTracker.GetSpeciesId("A") }, m_RequiredOrder, 1).XQuadSchemeHelper; CellQuadratureScheme cqs = SchemeHelper.GetLevelSetquadScheme(0, cutCells); ICompositeQuadRule <QuadRule> surfaceRule = cqs.Compile(m_LevelSetTracker.GridDat, m_RequiredOrder); CellQuadrature.GetQuadrature(noOfIntegrals, m_GridData, surfaceRule, delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) { ErrFunc(i0, Length, QR.Nodes, EvalResult.ExtractSubArrayShallow(-1, -1, 0)); }, delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { IntegrationForces[d] = ForceTorqueSummationWithNeumaierArray(IntegrationForces[d], ResultsOfIntegration, Length); } ).Execute(); } stressToPrintOut = stressToPrint.CloneAs(); return(tempForces = IntegrationForces.CloneAs()); }
private void ComputeAverageU <T>(IEnumerable <T> U0, VectorField <XDGField> U0mean, int order, XQuadSchemeHelper qh) where T : DGField { using (FuncTrace ft = new FuncTrace()) { var CC = this.LsTrk.Regions.GetCutCellMask(); int D = this.LsTrk.GridDat.SpatialDimension; double minvol = Math.Pow(this.LsTrk.GridDat.Cells.h_minGlobal, D); //var qh = new XQuadSchemeHelper(agg); foreach (var Spc in this.LsTrk.SpeciesIdS) // loop over species... //var Spc = this.LsTrk.GetSpeciesId("B"); { // shadow fields { DGField[] U0_Spc = U0.Select(U0_d => (U0_d is XDGField) ? ((DGField)((U0_d as XDGField).GetSpeciesShadowField(Spc))) : ((DGField)U0_d)).ToArray(); var U0mean_Spc = U0mean.Select(U0mean_d => U0mean_d.GetSpeciesShadowField(Spc)).ToArray(); // normal cells: for (int d = 0; d < D; d++) { U0mean_Spc[d].AccLaidBack(1.0, U0_Spc[d], this.LsTrk.Regions.GetSpeciesMask(Spc)); } // cut cells var scheme = qh.GetVolumeQuadScheme(Spc, IntegrationDomain: this.LsTrk.Regions.GetCutCellMask()); var rule = scheme.Compile(this.LsTrk.GridDat, order); CellQuadrature.GetQuadrature(new int[] { D + 1 }, // vector components: ( avg_vel[0], ... , avg_vel[D-1], cell_volume ) this.LsTrk.GridDat, rule, delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) { EvalResult.Clear(); for (int d = 0; d < D; d++) { U0_Spc[d].Evaluate(i0, Length, QR.Nodes, EvalResult.ExtractSubArrayShallow(-1, -1, d)); } var Vol = EvalResult.ExtractSubArrayShallow(-1, -1, D); Vol.SetAll(1.0); }, delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { for (int i = 0; i < Length; i++) { int jCell = i + i0; double Volume = ResultsOfIntegration[i, D]; if (Math.Abs(Volume) < minvol * 1.0e-12) { // keep current value // since the volume of species 'Spc' in cell 'jCell' is 0.0, the value in this cell should have no effect } else { for (int d = 0; d < D; d++) { double IntVal = ResultsOfIntegration[i, d]; U0mean_Spc[d].SetMeanValue(jCell, IntVal / Volume); } } } }).Execute(); } #if DEBUG { var Uncut = LsTrk.Regions.GetCutCellMask().Complement(); VectorField <SinglePhaseField> U0mean_check = new VectorField <SinglePhaseField>(D, new Basis(LsTrk.GridDat, 0), SinglePhaseField.Factory); for (int d = 0; d < D; d++) { U0mean_check[d].ProjectField(1.0, U0.ElementAt(d).Evaluate, new CellQuadratureScheme(false, Uncut).AddFixedOrderRules(LsTrk.GridDat, U0.ElementAt(d).Basis.Degree + 1)); } foreach (var _Spc in this.LsTrk.SpeciesIdS) // loop over species... { for (int d = 0; d < D; d++) { U0mean_check[d].AccLaidBack(-1.0, U0mean[d].GetSpeciesShadowField(_Spc), Uncut.Intersect(LsTrk.Regions.GetSpeciesMask(_Spc))); } } double checkNorm = U0mean_check.L2Norm(); Debug.Assert(checkNorm < 1.0e-6); } #endif U0mean.ForEach(F => F.CheckForNanOrInf(true, true, true)); } }