static double JumpNorm(DGField f) { GridData grd = (GridData)f.GridDat; int D = grd.SpatialDimension; var e2cTrafo = grd.Edges.Edge2CellTrafos; f.MPIExchange(); double Unorm = 0; EdgeQuadrature.GetQuadrature( new int[] { D + 1 }, grd, (new EdgeQuadratureScheme()).Compile(grd, f.Basis.Degree * 2), delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) { // Evaluate NodeSet NS = QR.Nodes; EvalResult.Clear(); int NoOfNodes = NS.NoOfNodes; for (int j = 0; j < Length; j++) { int iEdge = j + i0; int jCell_IN = grd.Edges.CellIndices[iEdge, 0]; int jCell_OT = grd.Edges.CellIndices[iEdge, 1]; var uDiff = EvalResult.ExtractSubArrayShallow(new int[] { j, 0, 0 }, new int[] { j, NoOfNodes - 1, -1 }); if (jCell_OT >= 0) { int iTrafo_IN = grd.Edges.Edge2CellTrafoIndex[iEdge, 0]; int iTrafo_OT = grd.Edges.Edge2CellTrafoIndex[iEdge, 1]; MultidimensionalArray uIN = MultidimensionalArray.Create(1, NoOfNodes); MultidimensionalArray uOT = MultidimensionalArray.Create(1, NoOfNodes); NodeSet NS_IN = NS.GetVolumeNodeSet(grd, iTrafo_IN); NodeSet NS_OT = NS.GetVolumeNodeSet(grd, iTrafo_OT); f.Evaluate(jCell_IN, 1, NS_IN, uIN); f.Evaluate(jCell_OT, 1, NS_OT, uOT); uDiff.Acc(+1.0, uIN); uDiff.Acc(-1.0, uOT); } else { uDiff.Clear(); } } EvalResult.ApplyAll(x => x * x); }, delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { // SaveIntegrationResults Unorm += ResultsOfIntegration.Sum(); }).Execute(); Unorm = Unorm.MPISum(); return(Unorm.Sqrt()); }
/// <summary> /// Calculates the drag (x-component) and lift (y-component) forces acting on a wall of a boundary fitted grid /// </summary> /// <param name="U"></param> /// <param name="P"></param> /// <param name="muA"></param> /// <returns></returns> static public double[] GetForces_BoundaryFitted(VectorField <SinglePhaseField> GradU, VectorField <SinglePhaseField> GradV, SinglePhaseField StressXX, SinglePhaseField StressXY, SinglePhaseField StressYY, SinglePhaseField P, LevelSetTracker LsTrk, double muA, double beta) { int D = LsTrk.GridDat.SpatialDimension; if (D > 2) { throw new ArgumentException("Method GetForces_BoundaryFitted only implemented for 2D (viscoelastic)!"); } // var UA = U.Select(u => u.GetSpeciesShadowField("A")).ToArray(); //var UA = U.ToArray(); MultidimensionalArray Grad_U = new MultidimensionalArray(D); var _GradU = GradU.ToArray(); var _GradV = GradV.ToArray(); int RequiredOrder = _GradU[0].Basis.Degree * 3 + 2; //int RequiredOrder = U[0].Basis.Degree * 3 + 2; //int RequiredOrder = LsTrk.GetXQuadFactoryHelper(momentFittingVariant).GetCachedSurfaceOrders(0).Max(); //Console.WriteLine("Order reduction: {0} -> {1}", _RequiredOrder, RequiredOrder); //if (RequiredOrder > agg.HMForder) // throw new ArgumentException(); Console.WriteLine("Forces coeff: {0}, order = {1}", LsTrk.CutCellQuadratureType, RequiredOrder); SinglePhaseField _StressXX = StressXX; SinglePhaseField _StressXY = StressXY; SinglePhaseField _StressYY = StressYY; SinglePhaseField pA = null; //pA = P.GetSpeciesShadowField("A"); pA = P; double[] forces = new double[D]; for (int d = 0; d < D; d++) { ScalarFunctionEx ErrFunc = delegate(int j0, int Len, NodeSet Ns, MultidimensionalArray result) { int K = result.GetLength(1); // No nof Nodes MultidimensionalArray Grad_URes = MultidimensionalArray.Create(Len, K, D); MultidimensionalArray Grad_VRes = MultidimensionalArray.Create(Len, K, D); MultidimensionalArray pARes = MultidimensionalArray.Create(Len, K); MultidimensionalArray StressXXRes = MultidimensionalArray.Create(Len, K); MultidimensionalArray StressXYRes = MultidimensionalArray.Create(Len, K); MultidimensionalArray StressYYRes = MultidimensionalArray.Create(Len, K); var Normals = LsTrk.GridDat.Edges.NormalsCache.GetNormals_Edge(Ns, j0, Len); //var Normals = MultidimensionalArray.Create(1, Ns.Length, 1); //var Normals = LsTrk.GridDat.Edges.NormalsForAffine; for (int i = 0; i < D; i++) { _GradU[i].EvaluateEdge(j0, Len, Ns, Grad_URes.ExtractSubArrayShallow(-1, -1, i), Grad_URes.ExtractSubArrayShallow(-1, -1, i), ResultIndexOffset: 0, ResultPreScale: 1); _GradV[i].EvaluateEdge(j0, Len, Ns, Grad_VRes.ExtractSubArrayShallow(-1, -1, i), Grad_VRes.ExtractSubArrayShallow(-1, -1, i), ResultIndexOffset: 0, ResultPreScale: 1); //UA[i].EvaluateGradient(j0, Len, Ns, Grad_UARes.ExtractSubArrayShallow(-1, -1, i, -1), 0, 1); } //pA.Evaluate(j0, Len, Ns, pARes); pA.EvaluateEdge(j0, Len, Ns, pARes, pARes, ResultIndexOffset: 0, ResultPreScale: 1); _StressXX.EvaluateEdge(j0, Len, Ns, StressXXRes, StressXXRes, ResultIndexOffset: 0, ResultPreScale: 1); _StressXY.EvaluateEdge(j0, Len, Ns, StressXYRes, StressXYRes, ResultIndexOffset: 0, ResultPreScale: 1); _StressYY.EvaluateEdge(j0, Len, Ns, StressYYRes, StressYYRes, ResultIndexOffset: 0, ResultPreScale: 1); //if (LsTrk.GridDat.SpatialDimension == 2) //{ for (int j = 0; j < Len; j++) { for (int k = 0; k < K; k++) { double acc = 0.0; // pressure switch (d) { case 0: acc += pARes[j, k] * Normals[j, k, 0]; acc -= (2 * muA * beta) * Grad_URes[j, k, 0] * Normals[j, k, 0]; acc -= (muA * beta) * Grad_URes[j, k, 1] * Normals[j, k, 1]; acc -= (muA * beta) * Grad_VRes[j, k, 0] * Normals[j, k, 1]; acc -= (muA * (1 - beta)) * StressXXRes[j, k] * Normals[j, k, 0]; acc -= (muA * (1 - beta)) * StressXYRes[j, k] * Normals[j, k, 1]; break; case 1: acc += pARes[j, k] * Normals[j, k, 1]; acc -= (2 * muA * beta) * Grad_VRes[j, k, 1] * Normals[j, k, 1]; acc -= (muA * beta) * Grad_VRes[j, k, 0] * Normals[j, k, 0]; acc -= (muA * beta) * Grad_URes[j, k, 1] * Normals[j, k, 0]; acc -= (muA * (1 - beta)) * StressXYRes[j, k] * Normals[j, k, 0]; acc -= (muA * (1 - beta)) * StressYYRes[j, k] * Normals[j, k, 1]; break; default: throw new NotImplementedException(); } result[j, k] = acc; } } //} //else //{ // for (int j = 0; j < Len; j++) // { // for (int k = 0; k < K; k++) // { // double acc = 0.0; // // pressure // switch (d) // { // case 0: // acc += pARes[j, k] * Normals[j, k, 0]; // acc -= (2 * muA) * Grad_UARes[j, k, 0, 0] * Normals[j, k, 0]; // acc -= (muA) * Grad_UARes[j, k, 0, 2] * Normals[j, k, 2]; // acc -= (muA) * Grad_UARes[j, k, 0, 1] * Normals[j, k, 1]; // acc -= (muA) * Grad_UARes[j, k, 1, 0] * Normals[j, k, 1]; // acc -= (muA) * Grad_UARes[j, k, 2, 0] * Normals[j, k, 2]; // break; // case 1: // acc += pARes[j, k] * Normals[j, k, 1]; // acc -= (2 * muA) * Grad_UARes[j, k, 1, 1] * Normals[j, k, 1]; // acc -= (muA) * Grad_UARes[j, k, 1, 2] * Normals[j, k, 2]; // acc -= (muA) * Grad_UARes[j, k, 1, 0] * Normals[j, k, 0]; // acc -= (muA) * Grad_UARes[j, k, 0, 1] * Normals[j, k, 0]; // acc -= (muA) * Grad_UARes[j, k, 2, 1] * Normals[j, k, 2]; // break; // case 2: // acc += pARes[j, k] * Normals[j, k, 2]; // acc -= (2 * muA) * Grad_UARes[j, k, 2, 2] * Normals[j, k, 2]; // acc -= (muA) * Grad_UARes[j, k, 2, 0] * Normals[j, k, 0]; // acc -= (muA) * Grad_UARes[j, k, 2, 1] * Normals[j, k, 1]; // acc -= (muA) * Grad_UARes[j, k, 0, 2] * Normals[j, k, 0]; // acc -= (muA) * Grad_UARes[j, k, 1, 2] * Normals[j, k, 1]; // break; // default: // throw new NotImplementedException(); // } // result[j, k] = acc; //} //} //} }; var SchemeHelper = LsTrk.GetXDGSpaceMetrics(new[] { LsTrk.GetSpeciesId("A") }, RequiredOrder, 1).XQuadSchemeHelper; EdgeMask Mask = new EdgeMask(LsTrk.GridDat, "Wall_cylinder"); EdgeQuadratureScheme eqs = SchemeHelper.GetEdgeQuadScheme(LsTrk.GetSpeciesId("A"), IntegrationDomain: Mask); EdgeQuadrature.GetQuadrature(new int[] { 1 }, LsTrk.GridDat, eqs.Compile(LsTrk.GridDat, RequiredOrder), // agg.HMForder), 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) { for (int i = 0; i < Length; i++) { forces[d] += ResultsOfIntegration[i, 0]; } } ).Execute(); } //for (int i = 0; i < D; i++) // forces[i] = MPI.Wrappers.MPIExtensions.MPISum(forces[i]); return(forces); }
/// <summary> /// Compares the cell surface and the boundary integral. /// </summary> public static void TestSealing(IGridData gdat) { int J = gdat.iLogicalCells.NoOfLocalUpdatedCells; int[,] E2Clog = gdat.iGeomEdges.LogicalCellIndices; // // compute cell surface via edge integrals // MultidimensionalArray CellSurf1 = MultidimensionalArray.Create(J); EdgeQuadrature.GetQuadrature(new int[] { 1 }, gdat, new EdgeQuadratureScheme().Compile(gdat, 2), delegate(int i0, int Length, QuadRule rule, MultidimensionalArray EvalResult) { // evaluate EvalResult.SetAll(1.0); }, delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { // save results for (int i = 0; i < Length; i++) { int iEdge = i + i0; int jCellIn = E2Clog[iEdge, 0]; int jCellOt = E2Clog[iEdge, 1]; CellSurf1[jCellIn] += ResultsOfIntegration[i, 0]; if (jCellOt >= 0 && jCellOt < J) { CellSurf1[jCellOt] += ResultsOfIntegration[i, 0]; } } }).Execute(); // // compute cell surface via cell boundary integrals // var cbqs = new CellBoundaryQuadratureScheme(false, null); foreach (var Kref in gdat.iGeomCells.RefElements) { cbqs.AddFactory(new StandardCellBoundaryQuadRuleFactory(Kref)); } MultidimensionalArray CellSurf2 = MultidimensionalArray.Create(J); CellBoundaryQuadrature <CellBoundaryQuadRule> .GetQuadrature(new int[] { 1 }, gdat, cbqs.Compile(gdat, 2), delegate(int i0, int Length, CellBoundaryQuadRule rule, MultidimensionalArray EvalResult) { // evaluate EvalResult.SetAll(1.0); }, delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { // save results int NoOfFaces = ResultsOfIntegration.GetLength(1); for (int i = 0; i < Length; i++) { int jCell = i + i0; for (int iFace = 0; iFace < NoOfFaces; iFace++) { CellSurf2[jCell] += ResultsOfIntegration[i, iFace, 0]; } } }, cs : CoordinateSystem.Physical).Execute(); // // compare // MultidimensionalArray Err = CellSurf1.CloneAs(); Err.Acc(-1.0, CellSurf2); double ErrNorm = Err.L2Norm(); double TotSurf = CellSurf1.L2Norm(); Console.WriteLine("Area Check " + Err.L2Norm()); Assert.LessOrEqual(ErrNorm / TotSurf, 1.0e-8); //for (int j = 0; j < J; j++) { // if (Err[j].Abs() >= 1.0e-6) { // Console.WriteLine("Mismatch between edge area and cell surface area in cell {0}, GlobalId {1}, No. of neighbors {3}, {2:0.####E-00}", j, gdat.CurrentGlobalIdPermutation.Values[j], Err[j], gdat.Cells.CellNeighbours[j].Length); // schas.SetMeanValue(j, 1); // } //} }
public void UpdateSensorValues(IEnumerable <DGField> fieldSet, ISpeciesMap speciesMap, CellMask cellMask) { using (new FuncTrace()) { DGField fieldToTest = fieldSet. Where(f => f.Identification == sensorVariable.Name). Single(); sensorValues = new SinglePhaseField( new Basis(fieldToTest.GridDat, 0)); var quadrature = EdgeQuadrature.GetQuadrature( new int[] { 1 }, (GridData)fieldToTest.GridDat, new EdgeQuadratureScheme().Compile(fieldToTest.GridDat, 2 * fieldToTest.Basis.Degree), delegate(int e0, int Length, QuadRule QR, MultidimensionalArray EvalResult) { MultidimensionalArray gIn = MultidimensionalArray.Create(Length, QR.NoOfNodes); MultidimensionalArray gOut = MultidimensionalArray.Create(Length, QR.NoOfNodes); fieldToTest.EvaluateEdge( e0, Length, QR.Nodes, gIn, gOut, MeanValueIN: null, MeanValueOT: null, GradientIN: null, GradientOT: null, ResultIndexOffset: 0, ResultPreScale: 0.0); for (int e = 0; e < Length; e++) { int edge = e + e0; // Check if "out" neighbor exist; ignore boundary edges for now int outCell = fieldToTest.GridDat.iLogicalEdges.CellIndices[edge, 1]; if (outCell < 0) { continue; } for (int node = 0; node < QR.NoOfNodes; node++) { double jump = gOut[e, node] - gIn[e, node]; double mean = 0.5 * (gOut[e, node] + gIn[e, node]); double s = jump / mean; if (!double.IsNaN(s)) { EvalResult[e, node, 0] = s * s / (Math.Sign(s) * s + 0.001); } } } }, delegate(int e0, int Length, MultidimensionalArray ResultsOfIntegration) { for (int e = 0; e < Length; e++) { int edge = e + e0; for (int neighbor = 0; neighbor < 2; neighbor++) // loop over IN/OUT cells { int jCell = fieldToTest.GridDat.iLogicalEdges.CellIndices[edge, neighbor]; if (jCell < 0) { break; } sensorValues.Coordinates[jCell, 0] += ResultsOfIntegration[e, 0]; } } }); quadrature.Execute(); } }