/// <summary>
        /// Creating the time integrated DG-FEM discretization of the level set advection equation
        /// </summary>
        /// <param name="LevelSet"></param>
        /// <param name="ExtensionVelocity"></param>
        /// <param name="e"></param>
        void CreateAdvectionSpatialOperator(SinglePhaseField LevelSet, SinglePhaseField ExtensionVelocity, ExplicitEuler.ChangeRateCallback e, SubGrid subGrid)
        {
            SpatialOperator SO;
            Func <int[], int[], int[], int> QuadOrderFunction = QuadOrderFunc.Linear();
            int D = LevelSet.GridDat.SpatialDimension;

            //FieldFactory<SinglePhaseField> fac = new FieldFactory<SinglePhaseField>(SinglePhaseField.Factory);
            //VectorField<SinglePhaseField> LevelSetGradient = new VectorField<SinglePhaseField>(D,
            //    LevelSet.Basis,fac);

            SO = new SpatialOperator(1, 1, 1, QuadOrderFunction, new string[] { "LS", "S", "Result" });
            double PenaltyBase = ((double)((LevelSet.Basis.Degree + 1) * (LevelSet.Basis.Degree + D))) / ((double)D);

            SO.EquationComponents["Result"].Add(new ScalarVelocityAdvectionFlux(GridDat, PenaltyBase));
            SO.Commit();
            this.TimeIntegrator = new RungeKutta(RungeKuttaScheme.ExplicitEuler, SO, new CoordinateMapping(LevelSet), new CoordinateMapping(ExtensionVelocity), subGrid);

            // Performing the task e
            if (e != null)
            {
                this.TimeIntegrator.OnBeforeComputeChangeRate += e;
            }
        }
Example #2
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);
                }

                //*/
            }
        }
 /// <summary>
 /// ctor
 /// </summary>
 /// <param name="LevelSet"></param>
 /// <param name="ScalarExtVel"></param>
 /// <param name="e"><see cref="ExplicitEuler.ChangeRateCallback"/></param>
 public ScalarVelocityAdvection(LevelSetTracker LSTrk, SinglePhaseField LevelSet, SinglePhaseField ScalarExtVel, ExplicitEuler.ChangeRateCallback e = null, bool nearfield = false)
 {
     GridDat        = (GridData)(LevelSet.Basis.GridDat);
     D              = GridDat.SpatialDimension;
     this.LSTrk     = LSTrk;
     this.nearfield = nearfield;
     CreateAdvectionSpatialOperator(LevelSet, ScalarExtVel, e, nearfield ? LSTrk.Regions.GetNearFieldSubgrid(1) :null);
 }