コード例 #1
0
        //TO BE CHANGED!!!!!
        public void GradientNorm(out SinglePhaseField norm, CellMask cm)
        {
            Basis basisForNorm = new Basis(this.GridDat, this.Basis.Degree * 2);

            norm = new SinglePhaseField(basisForNorm);

            Func <Basis, string, SinglePhaseField> fac = (Basis b, string id) => new SinglePhaseField(b, id);

            VectorField <SinglePhaseField> Gradient = new VectorField <SinglePhaseField>(GridDat.SpatialDimension, Basis, fac);

            for (int i = 0; i < GridDat.SpatialDimension; i++)
            {
                Gradient[i].Derivative(1.0, this, i, cm);
            }
            norm.ProjectAbs <SinglePhaseField>(1.0, Gradient);
        }
コード例 #2
0
        /// <summary>
        /// Assigns the normalized gradient of the level set to the Output
        /// vector
        /// </summary>
        /// <param name="Output">Normal vector</param>
        /// <param name="optionalSubGrid">
        /// Restriction of the computations to a an optional subgrid
        /// </param>
        /// <param name="bndMode"></param>
        public void ComputeNormalByFlux(VectorField <SinglePhaseField> Output, SubGrid optionalSubGrid = null, SpatialOperator.SubGridBoundaryModes bndMode = SpatialOperator.SubGridBoundaryModes.OpenBoundary)
        {
            if (this.m_Basis.Degree < 1)
            {
                throw new ArgumentException("For correct computation of these level set quantities, the level set has to be at least of degree 1!");
            }
            SinglePhaseField absval = new SinglePhaseField(Output[0].Basis);

            //Output.Clear();
            for (int i = 0; i < Output.Dim; i++)
            {
                Output[i].DerivativeByFlux(1.0, this, i, optionalSubGrid, bndMode);
            }

            absval.ProjectAbs(1.0, Output);
            for (int i = 0; i < Output.Dim; i++)
            {
                Output[i].ProjectQuotient(1.0, Output[i], absval, null, false);
            }
        }
コード例 #3
0
        /// <summary>
        /// Assigns the normalized gradient of the level set to the Output
        /// vector
        /// </summary>
        /// <param name="Output">Normal Vector</param>
        /// <param name="optionalCellMask">
        /// Cell mask used when computing the derivatives
        /// </param>
        public void ComputeNormal(VectorField <SinglePhaseField> Output, CellMask optionalCellMask)
        {
            if (this.m_Basis.Degree < 1)
            {
                throw new ArgumentException("For correct computation of these level set quantities, the level set has to be at least of degree 1!");
            }
            SinglePhaseField absval = new SinglePhaseField(Output[0].Basis);

            Output.Clear();
            for (int i = 0; i < Output.Dim; i++)
            {
                Output[i].Derivative(1.0, this, i, optionalCellMask);
            }

            absval.ProjectAbs(1.0, Output);

            for (int i = 0; i < Output.Dim; i++)
            {
                Output[i].ProjectQuotient(1.0, Output[i], absval, null, false);
            }
        }
コード例 #4
0
        /// <summary>
        /// Obtaining the time integrated spatial discretization of the reinitialization equation in a narrow band around the zero level set, based on a Godunov's numerical Hamiltonian calculation
        /// </summary>
        /// <param name="LS"> The level set function </param>
        /// <param name="Restriction"> The narrow band around the zero level set </param>
        /// <param name="NumberOfTimesteps">
        /// maximum number of pseudo-timesteps
        /// </param>
        /// <param name="thickness">
        /// The smoothing width of the signum function.
        /// This is the main stabilization parameter for re-initialization.
        /// It should be set to approximately 3 cells.
        /// </param>
        /// <param name="TimestepSize">
        /// size of the pseudo-timestep
        /// </param>
        public void ReInitialize(LevelSet LS, SubGrid Restriction, double thickness, double TimestepSize, int NumberOfTimesteps)
        {
            using (var tr = new FuncTrace()) {
                // log parameters:
                tr.Info("thickness: " + thickness.ToString(NumberFormatInfo.InvariantInfo));
                tr.Info("TimestepSize: " + TimestepSize.ToString(NumberFormatInfo.InvariantInfo));
                tr.Info("NumberOfTimesteps: " + NumberOfTimesteps);

                ExplicitEuler TimeIntegrator;

                SpatialOperator SO;
                Func <int[], int[], int[], int> QuadratureOrder = QuadOrderFunc.NonLinear(3);
                if (m_ctx.SpatialDimension == 2)
                {
                    SO = new SpatialOperator(1, 5, 1, QuadratureOrder, new string[] { "LS", "LSCGV", "LSDG[0]", "LSUG[0]", "LSDG[1]", "LSUG[1]", "Result" });
                    SO.EquationComponents["Result"].Add(new GodunovHamiltonian(m_ctx, thickness));
                    SO.Commit();
                    TimeIntegrator = new RungeKutta(m_Scheme, SO, new CoordinateMapping(LS), new CoordinateMapping(LSCGV, LSDG[0], LSUG[0], LSDG[1], LSUG[1]), sgrd: Restriction);
                }
                else
                {
                    SO = new SpatialOperator(1, 7, 1, QuadratureOrder, new string[] { "LS", "LSCGV", "LSDG[0]", "LSUG[0]", "LSDG[1]", "LSUG[1]", "LSDG[2]", "LSUG[2]", "Result" });
                    SO.EquationComponents["Result"].Add(new GodunovHamiltonian(m_ctx, thickness));
                    SO.Commit();
                    TimeIntegrator = new RungeKutta(m_Scheme, SO, new CoordinateMapping(LS), new CoordinateMapping(LSCGV, LSDG[0], LSUG[0], LSDG[1], LSUG[1], LSDG[2], LSUG[2]), sgrd: Restriction);
                }



                // Calculating the gradients in each sub-stage of a Runge-Kutta integration procedure
                ExplicitEuler.ChangeRateCallback EvalGradients = delegate(double t1, double t2) {
                    LSUG.Clear();
                    CalculateLevelSetGradient(LS, LSUG, "Upwind", Restriction);

                    LSDG.Clear();
                    CalculateLevelSetGradient(LS, LSDG, "Downwind", Restriction);

                    LSCG.Clear();
                    CalculateLevelSetGradient(LS, LSCG, "Central", Restriction);

                    LSCGV.Clear();
                    var VolMask = (Restriction != null) ? Restriction.VolumeMask : null;
                    LSCGV.ProjectAbs(1.0, VolMask, LSCG.ToArray());
                };
                TimeIntegrator.OnBeforeComputeChangeRate += EvalGradients;


                {
                    EvalGradients(0, 0);
                    var GodunovResi = new SinglePhaseField(LS.Basis, "Residual");
                    SO.Evaluate(1.0, 0.0, LS.Mapping, TimeIntegrator.ParameterMapping.Fields, GodunovResi.Mapping, Restriction);

                    //Tecplot.Tecplot.PlotFields(ArrayTools.Cat<DGField>( LSUG, LSDG, LS, GodunovResi), "Residual", 0, 3);
                }



                // pseudo-timestepping
                // ===================
                double   factor     = 1.0;
                double   time       = 0;
                LevelSet prevLevSet = new LevelSet(LS.Basis, "prevLevSet");

                CellMask RestrictionMask = (Restriction == null) ? null : Restriction.VolumeMask;

                for (int i = 0; (i < NumberOfTimesteps); i++)
                {
                    tr.Info("Level set reinitialization pseudo-timestepping, timestep " + i);

                    // backup old Levelset
                    // -------------------
                    prevLevSet.Clear();
                    prevLevSet.Acc(1.0, LS, RestrictionMask);

                    // time integration
                    // ----------------
                    double dt = TimestepSize * factor;
                    tr.Info("dt = " + dt.ToString(NumberFormatInfo.InvariantInfo) + " (factor = " + factor.ToString(NumberFormatInfo.InvariantInfo) + ")");
                    TimeIntegrator.Perform(dt);
                    time += dt;

                    // change norm
                    // ------

                    prevLevSet.Acc(-1.0, LS, RestrictionMask);
                    double ChangeNorm = prevLevSet.L2Norm(RestrictionMask);
                    Console.WriteLine("Reinit: PseudoTime: {0}  - Changenorm: {1}", i, ChangeNorm);

                    //Tecplot.Tecplot.PlotFields(new SinglePhaseField[] { LS }, m_ctx, "Reinit-" + i, "Reinit-" + i, i, 3);
                }

                //*/
            }
        }
コード例 #5
0
ファイル: Surface.cs プロジェクト: xyuan/BoSSS
        /// <summary>
        ///  In this method, the vector normal to the surface as well as certain derivatives
        /// of it that we intend to use are set up
        /// </summary>

        protected void NormalVec(double deltax)
        {
            wx = new SinglePhaseField(m_gradBasis, "wx");
            wy = new SinglePhaseField(m_gradBasis, "wy");

            if (m_Context.Grid.SpatialDimension == 2)
            {
                m_Gradw = new VectorField <SinglePhaseField>(wx, wy);
            }
            else if (m_Context.Grid.SpatialDimension == 3)
            {
                wz      = new SinglePhaseField(m_gradBasis, "wz");
                m_Gradw = new VectorField <SinglePhaseField>(wx, wy, wz);
            }
            else
            {
                throw new NotSupportedException("only spatial dimension 2 and 3 are supported.");
            }
            SinglePhaseField absval = new SinglePhaseField(m_gradBasis);

            m_Gradw[0].Derivative(1.0, m_Field, 0);
            m_Gradw[1].Derivative(1.0, m_Field, 1);

            if (m_Context.Grid.SpatialDimension == 3)
            {
                m_Gradw[2].Derivative(1.0, m_Field, 2);
            }

            /*
             * Normalization of the gradient vector
             * Might be better implemented using a
             * Function
             */

            absval.ProjectAbs(1.0, m_Gradw);
            m_Gradw[0].ProjectQuotient(1.0, m_Gradw[0], absval, null, false);
            m_Gradw[1].ProjectQuotient(1.0, m_Gradw[1], absval, null, false);

            if (m_Context.Grid.SpatialDimension == 3)
            {
                m_Gradw[2].ProjectQuotient(1.0, m_Gradw[2], absval, null, false);
            }
            SinglePhaseField n1x = new SinglePhaseField(m_derivsBasis, "n1x");
            SinglePhaseField n2x = new SinglePhaseField(m_derivsBasis, "n2x");
            SinglePhaseField n1y = new SinglePhaseField(m_derivsBasis, "n1y");
            SinglePhaseField n2y = new SinglePhaseField(m_derivsBasis, "n2y");

            if (m_Context.Grid.SpatialDimension == 3)
            {
                SinglePhaseField n3x = new SinglePhaseField(m_derivsBasis, "n3x");
                SinglePhaseField n3y = new SinglePhaseField(m_derivsBasis, "n3y");
                SinglePhaseField n1z = new SinglePhaseField(m_derivsBasis, "n1z");
                SinglePhaseField n2z = new SinglePhaseField(m_derivsBasis, "n2z");
                SinglePhaseField n3z = new SinglePhaseField(m_derivsBasis, "n3z");

                m_normderivs = new VectorField <SinglePhaseField>(n1x, n2x, n3x, n1y, n2y, n3y, n1z, n2z, n3z);

                /* Partial derivatives of the normal vector.
                 * These quantities are used in the product rule applied to the surface projection
                 * and to compute the mean curvature
                 */

                m_normderivs[0].Derivative(1.0, m_Gradw[0], 0);
                m_normderivs[1].Derivative(1.0, m_Gradw[1], 0);
                m_normderivs[2].Derivative(1.0, m_Gradw[2], 0);
                m_normderivs[3].Derivative(1.0, m_Gradw[0], 1);
                m_normderivs[4].Derivative(1.0, m_Gradw[1], 1);
                m_normderivs[5].Derivative(1.0, m_Gradw[2], 1);
                m_normderivs[6].Derivative(1.0, m_Gradw[0], 2);
                m_normderivs[7].Derivative(1.0, m_Gradw[1], 2);
                m_normderivs[8].Derivative(1.0, m_Gradw[2], 2);
            }
            else
            {
                m_normderivs = new VectorField <SinglePhaseField>(n1x, n2x, n1y, n2y);

                /* Partial derivatives of the normal vector.
                 * These quantities are used in the product rule applied to the surface projection
                 * and to compute the mean curvature
                 */

                m_normderivs[0].Derivative(1.0, m_Gradw[0], 0);
                m_normderivs[1].Derivative(1.0, m_Gradw[1], 0);
                m_normderivs[2].Derivative(1.0, m_Gradw[0], 1);
                m_normderivs[3].Derivative(1.0, m_Gradw[1], 1);
            }

            /*
             * Divergence of the surface normal vector yields the total curvature
             * which is twice the mean curvature
             * ATTENTION: here with inverse sign!!!!!
             */
            m_Curvature = new SinglePhaseField(m_derivsBasis);
            m_Curvature.Acc(1.0, m_normderivs[0]);
            m_Curvature.Acc(1.0, m_normderivs[4]);
            if (m_Context.Grid.SpatialDimension == 3)
            {
                m_Curvature.Acc(1.0, m_normderivs[8]);
            }

            m_sign = new SinglePhaseField(m_Basis, "sign");
            SinglePhaseField quot = new SinglePhaseField(m_Basis, "quot");
            SinglePhaseField sqrt = new SinglePhaseField(m_Basis, "sqrt");

            sqrt.ProjectProduct(1.0, m_Field, m_Field);
            sqrt.AccConstant(0.01);

            quot.ProjectPow(1.0, sqrt, deltax * deltax);
            m_sign.ProjectQuotient(1.0, m_Field, quot);
        }