/// <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());
        }
Beispiel #2
0
            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);
            }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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;
                        }
                    }
                }
            });
        }