Esempio n. 1
0
        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());
        }
Esempio n. 3
0
        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));
            }
        }