/// <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()); }
public void createNodes(int[,] TrafoIdx, SinglePhaseField Phi, ConventionalDGField ExtProperty) { int iTrafo = TrafoIdx[associatedNeighbour.Item2, associatedNeighbour.Item3]; NodeSet CellNodes = this.EdgeNodes.GetVolumeNodeSet(this.Solver_Grid, iTrafo); //Writes Phi and ExtProperty values at edge nodes into the respective Buffer Phi.Evaluate(associatedNeighbour.Item1, 1, CellNodes, this.PhiEdgeEvalBuffer); ExtProperty.Evaluate(associatedNeighbour.Item1, 1, CellNodes, this.ExtEdgeEvalBuffer); //Writes the corresponding nodes into CellNodesGlobalBuffer this.Solver_Grid.TransformLocal2Global(this.EdgeNodes.GetVolumeNodeSet(this.Solver_Grid, iTrafo), this.EdgeNodesGlobal, associatedNeighbour.Item1); }
/// <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; } } } }); }