Exemplo n.º 1
0
        /// <summary>
        /// Sets level-set and solution at time (<paramref name="time"/> + <paramref name="dt"/>).
        /// </summary>
        double DelUpdateLevelset(DGField[] CurrentState, double time, double dt, double UnderRelax, bool _incremental)
        {
            // new time
            double t = time + dt;

            // project new level-set
            double s = 1.0;

            LevSet.ProjectField((x, y) => - (x - s * t).Pow2() - y.Pow2() + (2.4).Pow2());
            LsTrk.UpdateTracker(incremental: _incremental);

            // exact solution for new timestep
            uEx.GetSpeciesShadowField("A").ProjectField((x, y) => x + alpha_A * t);
            uEx.GetSpeciesShadowField("B").ProjectField((x, y) => x + alpha_B * t);

            u.Clear();
            u.Acc(1.0, uEx);

            // markieren, wo ueberhaupt A und B sind
            Amarker.Clear();
            Bmarker.Clear();
            Amarker.AccConstant(+1.0, LsTrk.Regions.GetSpeciesSubGrid("A").VolumeMask);
            Bmarker.AccConstant(1.0, LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask);

            // MPI rank
            MPICellRank.Clear();
            MPICellRank.AccConstant(base.MPIRank);

            // return level-set residual
            return(0.0);
        }
Exemplo n.º 2
0
        private double SetUpConfiguration()
        {
            testCase.UpdateLevelSet(levelSet);
            levelSetTracker.UpdateTracker(__NearRegionWith: 0, incremental: false, __LevSetAllowedMovement: 2);

            XDGField.Clear();
            XDGField.GetSpeciesShadowField("A").ProjectField(
                1.0, testCase.JumpingFieldSpeciesAInitialValue, default(CellQuadratureScheme));
            XDGField.GetSpeciesShadowField("B").ProjectField(
                1.0, testCase.JumpingFieldSpeciesBInitialValue, default(CellQuadratureScheme));

            SinglePhaseField.Clear();
            SinglePhaseField.ProjectField(testCase.ContinuousFieldInitialValue);

            double referenceValue = testCase.Solution;

            if (testCase is IVolumeTestCase)
            {
                QuadRule standardRule = Grid.RefElements[0].GetQuadratureRule(2 * XDGField.Basis.Degree + 1);
                ScalarFieldQuadrature uncutQuadrature = new ScalarFieldQuadrature(
                    GridData,
                    XDGField,
                    new CellQuadratureScheme(
                        new FixedRuleFactory <QuadRule>(standardRule),
                        levelSetTracker.Regions.GetCutCellSubGrid().Complement().VolumeMask),
                    standardRule.OrderOfPrecision);
                uncutQuadrature.Execute();

                referenceValue -= uncutQuadrature.Result;
            }

            return(referenceValue);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Sets level-set and solution at time (<paramref name="time"/> + <paramref name="dt"/>).
        /// </summary>
        double DelUpdateLevelset(DGField[] CurrentState, double time, double dt, double UnderRelax, bool _incremental)
        {
            // new time
            double t = time + dt;

            // project new level-set
            double s = 1.0;

            LevSet.ProjectField((x, y) => - (x - s * t).Pow2() - y.Pow2() + (2.4).Pow2());
            LsTrk.UpdateTracker(incremental: _incremental);
            LsTrk.PushStacks();

            // exact solution for new timestep
            uXEx.GetSpeciesShadowField("A").ProjectField((x, y) => x + alpha_A * t);
            uXEx.GetSpeciesShadowField("B").ProjectField((x, y) => x + alpha_B * t);

            // uX.Clear();
            //uX.Acc(1.0, uXEx);

            // single-phase-properties
            u.Clear();
            u.ProjectField(NonVectorizedScalarFunction.Vectorize(uEx, t));

            Grad_u.Clear();
            Grad_u.Gradient(1.0, u);

            MagGrad_u.Clear();
            MagGrad_u.ProjectFunction(1.0,
                                      (double[] X, double[] U, int jCell) => Math.Sqrt(U[0].Pow2() + U[1].Pow2()),
                                      new Foundation.Quadrature.CellQuadratureScheme(),
                                      Grad_u.ToArray());

            // return level-set residual
            return(0.0);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Sets level-set and solution at time (<paramref name="time"/> + <paramref name="dt"/>).
        /// </summary>
        double DelUpdateLevelset(DGField[] CurrentState, double time, double dt, double UnderRelax, bool _incremental)
        {
            // new time
            double t = time + dt;

            // project new level-set
            LevSet.ProjectField(this.Control.LevelSet.Vectorize(t));
            LsTrk.UpdateTracker(incremental: _incremental);

            // exact solution for new timestep
            uEx.GetSpeciesShadowField("A").ProjectField(NonVectorizedScalarFunction.Vectorize(this.Control.uEx_A, t));
            uEx.GetSpeciesShadowField("B").ProjectField(NonVectorizedScalarFunction.Vectorize(this.Control.uEx_B, t));

            u.Clear();
            u.Acc(1.0, uEx);

            // markieren, wo ueberhaupt A und B sind
            Amarker.Clear();
            Bmarker.Clear();
            Amarker.AccConstant(+1.0, LsTrk._Regions.GetSpeciesSubGrid("A").VolumeMask);
            Bmarker.AccConstant(1.0, LsTrk._Regions.GetSpeciesSubGrid("B").VolumeMask);

            // MPI rank
            MPICellRank.Clear();
            MPICellRank.AccConstant(base.MPIRank);

            // return level-set residual
            return(0.0);
        }
Exemplo n.º 5
0
        public static void ProjectKineticDissipation(this XDGField proj, LevelSetTracker LsTrk, DGField[] Velocity, double[] mu, int momentFittingOrder, int HistInd = 1)
        {
            using (new FuncTrace()) {
                int D = LsTrk.GridDat.SpatialDimension;
                if (Velocity.Count() != D)
                {
                    throw new ArgumentException();
                }
                if (LsTrk.SpeciesIdS.Count != mu.Length)
                {
                    throw new ArgumentException();
                }

                var SchemeHelper = LsTrk.GetXDGSpaceMetrics(LsTrk.SpeciesIdS.ToArray(), momentFittingOrder, HistInd).XQuadSchemeHelper;

                for (int iSpc = 0; iSpc < LsTrk.SpeciesIdS.Count; iSpc++)
                {
                    SpeciesId spcId = LsTrk.SpeciesIdS[iSpc];
                    double    _mu   = mu[iSpc];

                    var Uspc = Velocity.Select(u => (u as XDGField).GetSpeciesShadowField(spcId)).ToArray();
                    ScalarFunctionEx spcKinDissip = GetSpeciesKineticDissipationFunc(Uspc, _mu);

                    proj.GetSpeciesShadowField(spcId).ProjectField(spcKinDissip);
                }
            }
        }
Exemplo n.º 6
0
        void TestAgglomeration_Extraploation(MultiphaseCellAgglomerator Agg)
        {
            _2D SomePolynomial;

            if (this.u.Basis.Degree == 0)
            {
                SomePolynomial = (x, y) => 3.2;
            }
            else if (this.u.Basis.Degree == 1)
            {
                SomePolynomial = (x, y) => 3.2 + x - 2.4 * y;
            }
            else
            {
                SomePolynomial = (x, y) => x * x + y * y;
            }

            // ========================================================
            // extrapolate polynomial function for species B of a XDG-field
            // ========================================================


            var Bmask = LsTrk.Regions.GetSpeciesMask("B");

            XDGField xt = new XDGField(new XDGBasis(this.LsTrk, this.u.Basis.Degree), "XDG-test");

            xt.GetSpeciesShadowField("B").ProjectField(1.0,
                                                       SomePolynomial.Vectorize(),
                                                       new CellQuadratureScheme(true, Bmask));


            double[] bkupVec = xt.CoordinateVector.ToArray();

            Agg.ClearAgglomerated(xt.Mapping);
            Agg.Extrapolate(xt.Mapping);

            double Err = GenericBlas.L2DistPow2(bkupVec, xt.CoordinateVector).MPISum().Sqrt();

            Console.WriteLine("Agglom: extrapolation error: " + Err);
            Assert.LessOrEqual(Err, 1.0e-10);

            // ========================================================
            // extrapolate polynomial function for a single-phase-field
            // ========================================================

            SinglePhaseField xt2 = new SinglePhaseField(this.u.Basis, "DG-test");

            xt2.ProjectField(SomePolynomial);

            double[] bkupVec2 = xt2.CoordinateVector.ToArray();

            Agg.ClearAgglomerated(xt2.Mapping);
            Agg.Extrapolate(xt2.Mapping);

            double Err2 = GenericBlas.L2DistPow2(bkupVec, xt.CoordinateVector).MPISum().Sqrt();

            Console.WriteLine("Agglom: extrapolation error: " + Err2);
            Assert.LessOrEqual(Err2, 1.0e-10);
        }
Exemplo n.º 7
0
        protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt)
        {
            dt = Control.dtFixed;


            Console.WriteLine("Timestep #{0}, dt = {1} ...", TimestepNo, dt);

            // advance level-set
            // -----------------

            double x0 = 0.17 * (phystime + dt);

            this.Pressure.UpdateBehaviour = BehaveUnder_LevSetMoovement.AutoExtrapolate;
            this.LevSet.ProjectField((_2D)((x, y) => Phi(new[] { x, y }, x0)));
            this.LsTrk.PushStacks();
            this.LsTrk.UpdateTracker(phystime + dt);


            // update markers
            // --------------
            this.Amarker.Clear();
            this.Bmarker.Clear();
            this.Amarker.AccConstant(1.0, this.LsTrk.Regions.GetSpeciesMask("A"));
            this.Bmarker.AccConstant(1.0, this.LsTrk.Regions.GetSpeciesMask("B"));

            // test the auto-extrapolation
            // ---------------------------

            var RefPressure = new XDGField(this.Pressure.Basis);

            RefPressure.GetSpeciesShadowField("A").ProjectField(PressureExactA);
            RefPressure.GetSpeciesShadowField("B").ProjectField(PressureExactB);
            RefPressure.Acc(-1.0, Pressure);

            AutoExtrapolationErr = RefPressure.L2Norm();
            Console.WriteLine("Error of extrapolation: " + AutoExtrapolationErr);
            Assert.LessOrEqual(AutoExtrapolationErr, 1.0e-8, "Error after auto-extrapolation to high.");


            Console.WriteLine("done.");

            return(dt);
        }
Exemplo n.º 8
0
        public static void ProjectKineticEnergy(this XDGField proj, LevelSetTracker LsTrk, XDGField[] Velocity, double[] rho, int momentFittingOrder, int HistInd = 1)
        {
            using (new FuncTrace()) {
                int D = LsTrk.GridDat.SpatialDimension;
                if (Velocity.Count() != D)
                {
                    throw new ArgumentException();
                }
                if (LsTrk.SpeciesIdS.Count != rho.Length)
                {
                    throw new ArgumentException();
                }

                var SchemeHelper = LsTrk.GetXDGSpaceMetrics(LsTrk.SpeciesIdS.ToArray(), momentFittingOrder, HistInd).XQuadSchemeHelper;

                for (int iSpc = 0; iSpc < LsTrk.SpeciesIdS.Count; iSpc++)
                {
                    SpeciesId spcId = LsTrk.SpeciesIdS[iSpc];
                    double    _rho  = rho[iSpc];

                    var Uspc = Velocity.Select(u => (u as XDGField).GetSpeciesShadowField(spcId)).ToArray();
                    //ScalarFunctionEx spcKinDissip = GetSpeciesKineticDissipationFunc(Uspc, _rho);

                    ScalarFunctionEx spcKinEnergy = delegate(int i0, int Len, NodeSet nds, MultidimensionalArray result) {
                        int K = result.GetLength(1); // No nof Nodes

                        MultidimensionalArray U_res = MultidimensionalArray.Create(Len, K, D);
                        for (int i = 0; i < D; i++)
                        {
                            Uspc[i].Evaluate(i0, Len, nds, U_res.ExtractSubArrayShallow(-1, -1, i));
                        }

                        double acc;
                        for (int j = 0; j < Len; j++)
                        {
                            for (int k = 0; k < K; k++)
                            {
                                acc = 0.0;

                                for (int d = 0; d < D; d++)
                                {
                                    acc += U_res[j, k, d] * U_res[j, k, d];
                                }
                                result[j, k] = _rho * acc / 2.0;
                            }
                        }
                    };

                    proj.GetSpeciesShadowField(spcId).ProjectField(spcKinEnergy);
                }
            }
        }
Exemplo n.º 9
0
        static void SetTestValue(XDGField Xf, IDictionary <SpeciesId, double> mod)
        {
            var Tracker = Xf.Basis.Tracker;

            foreach (var S in Tracker.SpeciesIdS)
            {
                var f = Xf.GetSpeciesShadowField(S);

                SetTestValue(f);
                f.Scale(mod[S]);
                //f.AccConstant(accVal[S]);
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Injects an XDG field from a coarsr grid to a fine grid.
        /// </summary>
        public static XDGField InjectXDGField(int[] Fine2Coarse, XDGField injected, XDGField cors_field, CellMask subGrd = null)
        {
            var trk = injected.Basis.Tracker;

            foreach (var spc in trk.SpeciesIdS)
            {
                var grd = trk.Regions.GetSpeciesMask(spc);

                InjectDGField(Fine2Coarse,
                              injected.GetSpeciesShadowField(spc),
                              cors_field.GetSpeciesShadowField(spc),
                              subGrd == null ? grd : grd.Intersect(subGrd));
            }
            return(injected);
        }
Exemplo n.º 11
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);
        }
Exemplo n.º 12
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);
        }
Exemplo n.º 13
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;
                        }
                    }
                }
            });
        }
Exemplo n.º 14
0
        protected override void SetInitial()
        {
            base.SetInitial();

            this.CreateEquationsAndSolvers(null);

            if (this.Control.MultiStepInit == true)
            {
                int CallCount = 0;

                if (m_RK_Timestepper != null)
                {
                    throw new NotSupportedException();
                }

                m_BDF_Timestepper.MultiInit(0.0, 0, this.Control.GetFixedTimestep(),
                                            delegate(int TimestepIndex, double Time, DGField[] St) {
                    Console.WriteLine("Timestep index {0}, time {1} ", TimestepIndex, Time);

                    // level-set
                    // ---------

                    this.Phi.ProjectField(X => this.Control.Phi(X, Time));

                    // HMF hacks
                    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(Time) };
                    }

                    if (CallCount == 0)
                    {
                        this.LsTrk.UpdateTracker();
                    }
                    else
                    {
                        this.LsTrk.UpdateTracker(incremental: true);
                    }

                    CallCount++;

                    // solution
                    // --------

                    XDGField _u = (XDGField)St[0];
                    _u.Clear();
                    _u.GetSpeciesShadowField("A").ProjectField((X => this.Control.uA_Ex(X, Time)));
                    _u.GetSpeciesShadowField("B").ProjectField((X => this.Control.uB_Ex(X, Time)));
                });
            }
            else
            {
                this.Phi.ProjectField(X => this.Control.Phi(X, 0.0));
                this.LsTrk.UpdateTracker();
                u.Clear();
                u.GetSpeciesShadowField("A").ProjectField((X => this.Control.uA_Ex(X, 0.0)));
                u.GetSpeciesShadowField("B").ProjectField((X => this.Control.uB_Ex(X, 0.0)));

                if (m_BDF_Timestepper != null)
                {
                    m_BDF_Timestepper.SingleInit();
                }
            }
        }
Exemplo n.º 15
0
        /// <summary>
        /// Checks MPI exchange
        /// </summary>
        void CheckExchange(bool ExchangeShadow)
        {
            // its important to test more than one field!
            var xf  = new XDGField(new XDGBasis(this.LsTrk, 0), "xf");
            var xf2 = new XDGField(new XDGBasis(this.LsTrk, 0), "xf2");
            int J   = this.GridData.iLogicalCells.NoOfLocalUpdatedCells;
            int JE  = this.GridData.iLogicalCells.Count;

            //long[] GiD = this.GridData.CurrentGlobalIdPermutation.Values;

            long GetGid(int j)
            {
                return(this.GridData.iLogicalCells.GetGlobalID(j));
            }

            {
                var st = new SinglePhaseField(new Basis(this.GridData, 1), "muh");
                for (int j = 0; j < J; j++)
                {
                    st.Coordinates[j, 0] = GetGid(j);
                }

                var trx = new BoSSS.Foundation.Comm.Transceiver(st);
                trx.TransceiveStartImReturn();
                trx.TransceiveFinish();


                for (int j = 0; j < JE; j++)
                {
                    double should = GetGid(j);
                    Assert.IsTrue(st.Coordinates[j, 0] == should, "everything is f****d");
                }
            }

            // ---------------------
            foreach (string s in this.LsTrk.SpeciesNames)
            {
                double sv   = s[0] * 0.01;
                var    xfs  = xf.GetSpeciesShadowField(s);
                var    xfs2 = xf2.GetSpeciesShadowField(s);
                for (int j = 0; j < J; j++)
                {
                    xfs.Coordinates[j, 0]  = GetGid(j) + sv;
                    xfs2.Coordinates[j, 0] = 1.0e5 + GetGid(j) + sv;
                }
            }

            double[] xfB4  = xf.CoordinateVector.ToArray();
            double[] xf2B4 = xf2.CoordinateVector.ToArray();

            // ---------------------
            if (ExchangeShadow)
            {
                // exchange shadow fields separately
                foreach (string s in this.LsTrk.SpeciesNames)
                {
                    var xfs  = xf.GetSpeciesShadowField(s);
                    var xfs2 = xf2.GetSpeciesShadowField(s);

                    //var xfsCopy = new SinglePhaseField(xfs.Basis, "muh");
                    //xfsCopy.Acc(1.0, xfs);
                    //dd.Add(s, xfsCopy);

                    var trx = new BoSSS.Foundation.Comm.Transceiver(xfs, xfs2);
                    trx.TransceiveStartImReturn();
                    trx.TransceiveFinish();
                }
            }
            else
            {
                // exchange XDG fields
                var trx2 = new BoSSS.Foundation.Comm.Transceiver(xf, xf2);
                trx2.TransceiveStartImReturn();
                trx2.TransceiveFinish();
            }

            foreach (string s in this.LsTrk.SpeciesNames)
            {
                double sv   = s[0] * 0.01;
                var    xfs  = xf.GetSpeciesShadowField(s);
                var    xfs2 = xf2.GetSpeciesShadowField(s);

                for (int j = 0; j < JE; j++)
                {
                    double should  = GetGid(j) + sv;
                    double should2 = 1.0e5 + GetGid(j) + sv;

                    string nerv = ExchangeShadow ? "shadow" : "XDG";
                    Assert.IsTrue(xfs.Coordinates[j, 0] == 0.0 || xfs.Coordinates[j, 0] == should, $"error in MPI exchange of {nerv} fields");
                    Assert.IsTrue(xfs2.Coordinates[j, 0] == 0.0 || xfs2.Coordinates[j, 0] == should2, $"error in MPI exchange of {nerv} fields (2nd field)");
                }
            }
        }
Exemplo n.º 16
0
        protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt)
        {
            Console.WriteLine("    Timestep # " + TimestepNo + ", phystime = " + phystime);

            //phystime = 1.8;
            LsUpdate(phystime);


            // operator-matrix assemblieren
            MsrMatrix OperatorMatrix = new MsrMatrix(u.Mapping, u.Mapping);

            double[] Affine = new double[OperatorMatrix.RowPartitioning.LocalLength];

            // Agglomerator setup
            MultiphaseCellAgglomerator Agg = LsTrk.GetAgglomerator(new SpeciesId[] { LsTrk.GetSpeciesId("B") }, QuadOrder, this.THRESHOLD);

            // plausibility of cell length scales
            if (SER_PAR_COMPARISON)
            {
                TestLengthScales(QuadOrder, TimestepNo);
            }

            Console.WriteLine("Inter-Process agglomeration? " + Agg.GetAgglomerator(LsTrk.GetSpeciesId("B")).AggInfo.InterProcessAgglomeration);
            if (this.THRESHOLD > 0.01)
            {
                TestAgglomeration_Extraploation(Agg);
                TestAgglomeration_Projection(QuadOrder, Agg);
            }
            CheckExchange(true);
            CheckExchange(false);

            // operator matrix assembly
            XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Op.GetMatrixBuilder(base.LsTrk, u.Mapping, null, u.Mapping);
            mtxBuilder.time = 0.0;
            mtxBuilder.ComputeMatrix(OperatorMatrix, Affine);
            Agg.ManipulateMatrixAndRHS(OperatorMatrix, Affine, u.Mapping, u.Mapping);

            // mass matrix factory
            var Mfact = LsTrk.GetXDGSpaceMetrics(new SpeciesId[] { LsTrk.GetSpeciesId("B") }, QuadOrder, 1).MassMatrixFactory;// new MassMatrixFactory(u.Basis, Agg);

            // Mass matrix/Inverse Mass matrix
            //var MassInv = Mfact.GetMassMatrix(u.Mapping, new double[] { 1.0 }, true, LsTrk.GetSpeciesId("B"));
            var Mass = Mfact.GetMassMatrix(u.Mapping, new double[] { 1.0 }, false, LsTrk.GetSpeciesId("B"));

            Agg.ManipulateMatrixAndRHS(Mass, default(double[]), u.Mapping, u.Mapping);
            var MassInv = Mass.InvertBlocks(OnlyDiagonal: true, Subblocks: true, ignoreEmptyBlocks: true, SymmetricalInversion: false);


            // test that operator depends only on B-species values
            double DepTest = LsTrk.Regions.GetSpeciesSubGrid("B").TestMatrixDependency(OperatorMatrix, u.Mapping, u.Mapping);

            Console.WriteLine("Matrix dependency test: " + DepTest);
            Assert.LessOrEqual(DepTest, 0.0);

            // diagnostic output
            Console.WriteLine("Number of Agglomerations (all species): " + Agg.TotalNumberOfAgglomerations);
            Console.WriteLine("Number of Agglomerations (species 'B'): " + Agg.GetAgglomerator(LsTrk.GetSpeciesId("B")).AggInfo.SourceCells.NoOfItemsLocally.MPISum());

            // operator auswerten:
            double[] x = new double[Affine.Length];
            BLAS.daxpy(x.Length, 1.0, Affine, 1, x, 1);
            OperatorMatrix.SpMVpara(1.0, u.CoordinateVector, 1.0, x);
            MassInv.SpMV(1.0, x, 0.0, du_dx.CoordinateVector);
            Agg.GetAgglomerator(LsTrk.GetSpeciesId("B")).Extrapolate(du_dx.Mapping);

            // markieren, wo ueberhaupt A und B sind
            Bmarker.AccConstant(1.0, LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask);
            Amarker.AccConstant(+1.0, LsTrk.Regions.GetSpeciesSubGrid("A").VolumeMask);
            if (usePhi0 && usePhi1)
            {
                Xmarker.AccConstant(+1.0, LsTrk.Regions.GetSpeciesSubGrid("X").VolumeMask);
            }

            // compute error
            ERR.Clear();
            ERR.Acc(1.0, du_dx_Exact, LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask);
            ERR.Acc(-1.0, du_dx, LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask);
            double L2Err = ERR.L2Norm(LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask);

            Console.WriteLine("L2 Error: " + L2Err);

            XERR.Clear();
            XERR.GetSpeciesShadowField("B").Acc(1.0, ERR, LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask);
            double xL2Err = XERR.L2Norm();

            Console.WriteLine("L2 Error (in XDG space): " + xL2Err);



            // check error
            double ErrorThreshold = 1.0e-1;

            if (this.MomentFittingVariant == XQuadFactoryHelper.MomentFittingVariants.OneStepGaussAndStokes)
            {
                ErrorThreshold = 1.0e-6; // HMF is designed for such integrands and should perform close to machine accuracy; on general integrands, the precision is different.
            }
            bool IsPassed = ((L2Err <= ErrorThreshold || this.THRESHOLD <= ErrorThreshold) && xL2Err <= ErrorThreshold);

            if (IsPassed)
            {
                Console.WriteLine("Test PASSED");
            }
            else
            {
                Console.WriteLine("Test FAILED: check errors.");
                //PlotCurrentState(phystime, TimestepNo, 3);
            }

            if (TimestepNo > 1)
            {
                if (this.THRESHOLD > ErrorThreshold)
                {
                    // without agglomeration, the error in very tiny cut-cells may be large over the whole cell
                    // However, the error in the XDG-space should be small under all circumstances
                    Assert.LessOrEqual(L2Err, ErrorThreshold, "DG L2 error of computing du_dx");
                }
                Assert.LessOrEqual(xL2Err, ErrorThreshold, "XDG L2 error of computing du_dx");
            }



            // return/Ende
            base.NoOfTimesteps = 17;
            //base.NoOfTimesteps = 2;
            dt = 0.3;
            return(dt);
        }
Exemplo n.º 17
0
        public static void XDG_ProlongationTest(
            [Values(0, 1, 2, 3)] int p,
            [Values(0.0, 0.3)] double AggregationThreshold,
            [Values(0, 1)] int TrackerWidth,
            [Values(MultigridOperator.Mode.Eye, MultigridOperator.Mode.IdMass)] MultigridOperator.Mode mode)
        {
            XQuadFactoryHelper.MomentFittingVariants variant = XQuadFactoryHelper.MomentFittingVariants.OneStepGaussAndStokes;
            var xt = new XDGTestSetup(p, AggregationThreshold, TrackerWidth, MultigridOperator.Mode.Eye, variant
                                      //, ((Func<double[], double>)(X => X[0] + 0.75)).Vectorize()
                                      );
            int Jup = grid.Cells.NoOfLocalUpdatedCells;


            Random rnd  = new Random();
            int    Ltop = xt.XdgMultigridOp.Mapping.LocalLength; // Number of DOF's on top multigrid level.


            double[] RndVec   = Ltop.ForLoop(i => rnd.NextDouble());
            double[] NoJmpVec = new double[Ltop];

            for (int iLevel = 0; iLevel < MgSeq.Length - 1; iLevel++)
            {
                XDG_Recursive(0, iLevel, xt.XdgMultigridOp, RndVec, NoJmpVec); // restrict RndVec downt to level 'iLevel', and back up

                // right now, the XDG field defined by 'NoJmpVec' should be a member
                // of the aggregated XDG space on level 'iLevel';
                // so, there should be no inter-element jumps on the fine level, for each aggregated cell.
                // Let's test that!

                XDGField Test = new XDGField(xt.XB, "Test");
                xt.XdgMultigridOp.TransformSolFrom(Test.CoordinateVector, NoJmpVec);
                //xt.agg.Extrapolate(Test.Mapping);
                var aggGrd = MgSeq[iLevel];

                foreach (var spc in xt.LsTrk.SpeciesIdS)
                {
                    var Test_spc = Test.GetSpeciesShadowField(spc);
                    var SpcMask  = xt.LsTrk.Regions.GetSpeciesMask(spc);

                    BitArray AggSourceBitmask = xt.agg.GetAgglomerator(spc).AggInfo.SourceCells.GetBitMask();

                    double Err = 0;
                    for (int jagg = 0; jagg < aggGrd.iLogicalCells.NoOfLocalUpdatedCells; jagg++)
                    {
                        BitArray CompCellMask = new BitArray(Jup);
                        foreach (int jCell in aggGrd.iLogicalCells.AggregateCellToParts[jagg])
                        {
                            if (!AggSourceBitmask[jCell])
                            {
                                CompCellMask[jCell] = true;
                            }
                        }

                        SubGrid CompCellSubGrid = new SubGrid((new CellMask(grid, CompCellMask)).Intersect(SpcMask));

                        Err += JumpNorm(Test_spc, CompCellSubGrid.InnerEdgesMask).Pow2();
                    }


                    Console.WriteLine("prolongation jump test (level {0}, species {2}): {1}", iLevel, Err, xt.LsTrk.GetSpeciesName(spc));
                    Assert.LessOrEqual(Err, 1.0e-8);
                }
            }
        }
Exemplo n.º 18
0
        protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt)
        {
            Console.WriteLine("    Timestep # " + TimestepNo + ", phystime = " + phystime);

            //phystime = 1.8;
            LsUpdate(phystime);


            // operator-matrix assemblieren
            MsrMatrix OperatorMatrix = new MsrMatrix(u.Mapping, u.Mapping);

            double[] Affine = new double[OperatorMatrix.RowPartitioning.LocalLength];
            MultiphaseCellAgglomerator Agg;
            MassMatrixFactory          Mfact;

            // Agglomerator setup
            int quadOrder = Op.QuadOrderFunction(new int[] { u.Basis.Degree }, new int[0], new int[] { u.Basis.Degree });

            //Agg = new MultiphaseCellAgglomerator(new CutCellMetrics(MomentFittingVariant, quadOrder, LsTrk, ), this.THRESHOLD, false);
            Agg = LsTrk.GetAgglomerator(new SpeciesId[] { LsTrk.GetSpeciesId("B") }, quadOrder, this.THRESHOLD);

            Console.WriteLine("Inter-Process agglomeration? " + Agg.GetAgglomerator(LsTrk.GetSpeciesId("B")).AggInfo.InterProcessAgglomeration);
            if (this.THRESHOLD > 0.01)
            {
                TestAgglomeration_Extraploation(Agg);
                TestAgglomeration_Projection(quadOrder, Agg);
            }

            // operator matrix assembly
            Op.ComputeMatrixEx(LsTrk,
                               u.Mapping, null, u.Mapping,
                               OperatorMatrix, Affine, false, 0.0, true,
                               Agg.CellLengthScales,
                               LsTrk.GetSpeciesId("B"));
            Agg.ManipulateMatrixAndRHS(OperatorMatrix, Affine, u.Mapping, u.Mapping);

            // mass matrix factory
            Mfact = LsTrk.GetXDGSpaceMetrics(new SpeciesId[] { LsTrk.GetSpeciesId("B") }, quadOrder, 1).MassMatrixFactory;// new MassMatrixFactory(u.Basis, Agg);

            // Mass matrix/Inverse Mass matrix
            //var MassInv = Mfact.GetMassMatrix(u.Mapping, new double[] { 1.0 }, true, LsTrk.GetSpeciesId("B"));
            var Mass = Mfact.GetMassMatrix(u.Mapping, new double[] { 1.0 }, false, LsTrk.GetSpeciesId("B"));

            Agg.ManipulateMatrixAndRHS(Mass, default(double[]), u.Mapping, u.Mapping);
            var MassInv = Mass.InvertBlocks(OnlyDiagonal: true, Subblocks: true, ignoreEmptyBlocks: true, SymmetricalInversion: false);


            // test that operator depends only on B-species values
            double DepTest = LsTrk.Regions.GetSpeciesSubGrid("B").TestMatrixDependency(OperatorMatrix, u.Mapping, u.Mapping);

            Console.WriteLine("Matrix dependency test: " + DepTest);
            Assert.LessOrEqual(DepTest, 0.0);

            // diagnostic output
            Console.WriteLine("Number of Agglomerations (all species): " + Agg.TotalNumberOfAgglomerations);
            Console.WriteLine("Number of Agglomerations (species 'B'): " + Agg.GetAgglomerator(LsTrk.GetSpeciesId("B")).AggInfo.SourceCells.NoOfItemsLocally.MPISum());

            // operator auswerten:
            double[] x = new double[Affine.Length];
            BLAS.daxpy(x.Length, 1.0, Affine, 1, x, 1);
            OperatorMatrix.SpMVpara(1.0, u.CoordinateVector, 1.0, x);
            MassInv.SpMV(1.0, x, 0.0, du_dx.CoordinateVector);
            Agg.GetAgglomerator(LsTrk.GetSpeciesId("B")).Extrapolate(du_dx.Mapping);


            // markieren, wo ueberhaupt A und B sind
            Bmarker.AccConstant(1.0, LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask);
            Amarker.AccConstant(+1.0, LsTrk.Regions.GetSpeciesSubGrid("A").VolumeMask);
            Xmarker.AccConstant(+1.0, LsTrk.Regions.GetSpeciesSubGrid("X").VolumeMask);

            // compute error
            ERR.Clear();
            ERR.Acc(1.0, du_dx_Exact, LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask);
            ERR.Acc(-1.0, du_dx, LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask);
            double L2Err = ERR.L2Norm(LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask);

            Console.WriteLine("L2 Error: " + L2Err);

            XERR.Clear();
            XERR.GetSpeciesShadowField("B").Acc(1.0, ERR, LsTrk.Regions.GetSpeciesSubGrid("B").VolumeMask);
            double xL2Err = XERR.L2Norm();

            Console.WriteLine("L2 Error (in XDG space): " + xL2Err);



            // check error
            if (this.THRESHOLD > 0.01)
            {
                // without agglomeration, the error in very tiny cut-cells may be large over the whole cell
                // However, the error in the XDG-space should be small under all circumstances
                Assert.LessOrEqual(L2Err, 1.0e-6);
            }
            Assert.LessOrEqual(xL2Err, 1.0e-6);

            bool IsPassed = ((L2Err <= 1.0e-6 || this.THRESHOLD <= 0.01) && xL2Err <= 1.0e-7);

            if (IsPassed)
            {
                Console.WriteLine("Test PASSED");
            }
            else
            {
                Console.WriteLine("Test FAILED: check errors.");
            }

            // return/Ende
            base.NoOfTimesteps = 17;
            //base.NoOfTimesteps = 2;
            dt = 0.3;
            return(dt);
        }