Esempio n. 1
0
        protected override void CreateFields()
        {
            using (new FuncTrace()) {
                base.CreateFields();
                int D = this.GridData.SpatialDimension;


                this.DGLevSet = new ScalarFieldHistory <SinglePhaseField>(
                    new SinglePhaseField(new Basis(this.GridData, this.Control.FieldOptions["Phi"].Degree), "PhiDG"));

                if (this.Control.FieldOptions["PhiDG"].Degree >= 0 && this.Control.FieldOptions["PhiDG"].Degree != this.DGLevSet.Current.Basis.Degree)
                {
                    throw new ApplicationException("Specification of polynomial degree for 'PhiDG' is not supportet, since it is induced by polynomial degree of 'Phi'.");
                }

                // ==============================
                // Initialize ContinuityProjection
                // if needed, if not , Option: None
                // ==============================
                this.LevSet = ContinuityProjection.CreateField(
                    DGLevelSet: this.DGLevSet.Current,
                    gridData: (GridData)GridData,
                    Option: Control.LSContiProjectionMethod
                    );

                this.LsTrk = new LevelSetTracker((GridData)this.GridData, base.Control.CutCellQuadratureType, base.Control.LS_TrackerWidth, new string[] { "A", "B" }, this.LevSet);
                base.RegisterField(this.LevSet);
                this.LevSetGradient = new VectorField <SinglePhaseField>(D.ForLoop(d => new SinglePhaseField(this.LevSet.Basis, "dPhi_dx[" + d + "]")));
                base.RegisterField(this.LevSetGradient);

                base.RegisterField(this.DGLevSet.Current);
                this.DGLevSetGradient = new VectorField <SinglePhaseField>(D.ForLoop(d => new SinglePhaseField(this.DGLevSet.Current.Basis, "dPhiDG_dx[" + d + "]")));
                base.RegisterField(this.DGLevSetGradient);

                if (this.Control.CheckJumpConditions)
                {
                    Basis basis = new Basis(this.GridData, 0);

                    //Basis basis = new Basis(this.GridData, this.Control.FieldOptions[VariableNames.VelocityX].Degree);
                    this.MassBalanceAtInterface = new SinglePhaseField(basis, "MassBalanceAtInterface");
                    base.RegisterField(this.MassBalanceAtInterface);

                    //basis = new Basis(this.GridData, this.Control.FieldOptions[VariableNames.Pressure].Degree + this.Control.FieldOptions["Phi"].Degree);
                    this.MomentumBalanceAtInterface = new VectorField <SinglePhaseField>(D.ForLoop(d => new SinglePhaseField(basis, d + "-MomentumBalanceAtInterface")));
                    base.RegisterField(this.MomentumBalanceAtInterface);

                    //basis = new Basis(this.GridData, this.Control.FieldOptions[VariableNames.Pressure].Degree + this.Control.FieldOptions[VariableNames.VelocityX].Degree + this.Control.FieldOptions["Phi"].Degree);
                    this.EnergyBalanceAtInterface = new SinglePhaseField(basis, "EnergyBalanceAtInterface");
                    base.RegisterField(this.EnergyBalanceAtInterface);
                }
            }
        }
        /// <summary>
        /// Creates a continuous version of a DG level set field
        /// </summary>
        /// <param name="DGLevelSet">The input DG level set field</param>
        /// <param name="jCells">Local cell indices</param>
        /// <returns>A continuous level set <see cref="SinglePhaseField"/> with one order higher than the input</returns>
        public static SinglePhaseField ContinuousLevelSet(SinglePhaseField DGLevelSet, double[] jCells)
        {
            Console.WriteLine(String.Format("Continuity projection of field {0} started...", DGLevelSet.Identification));

            // Init
            IGridData        gridData           = DGLevelSet.GridDat;
            SinglePhaseField continuousLevelSet = new SinglePhaseField(new Basis(gridData, DGLevelSet.Basis.Degree + 1), DGLevelSet.Identification + "_cont");

            // Create narrow band
            List <int> allNeighbours = new List <int>();

            foreach (int cell in jCells)
            {
                gridData.GetCellNeighbours(cell, GetCellNeighbours_Mode.ViaVertices, out int[] cellNeighbours, out int[] connectingEntities);
                allNeighbours.Add(cell);
                allNeighbours.AddRange(cellNeighbours);
            }
            List <int> narrowBandCells   = allNeighbours.Distinct().ToList();
            BitArray   bitMaskNarrowBand = new BitArray(gridData.iLogicalCells.NoOfLocalUpdatedCells);

            foreach (int cell in narrowBandCells)
            {
                bitMaskNarrowBand[cell] = true;
            }
            CellMask narrowBand = new CellMask(gridData, bitMaskNarrowBand);

            // Create positive mask
            BitArray bitMaskPos = new BitArray(gridData.iLogicalCells.NoOfLocalUpdatedCells);

            for (int i = 0; i < gridData.iLogicalCells.NoOfLocalUpdatedCells; i++)
            {
                if (DGLevelSet.GetMeanValue(i) > 0 && !bitMaskNarrowBand[i])
                {
                    bitMaskPos[i] = true;
                }
            }
            CellMask posMask = new CellMask(gridData, bitMaskPos);

            // Continuity projection
            ContinuityProjection continuityProjection = new ContinuityProjection(continuousLevelSet.Basis, DGLevelSet.Basis, gridData, ContinuityProjectionOption.ConstrainedDG);

            continuityProjection.MakeContinuous(DGLevelSet, continuousLevelSet, narrowBand, posMask);

            Console.WriteLine("finished");

            return(continuousLevelSet);
        }
Esempio n. 3
0
        /// <summary>
        /// setUp for the Level set initialization (Level-set algorithm, continuity, conservation)
        /// </summary>
        protected void InitLevelSet()
        {
            using (new FuncTrace()) {
                // check level-set
                if (this.LevSet.L2Norm() == 0)
                {
                    throw new NotSupportedException("Level set is not initialized - norm is 0.0 - ALL cells will be cut, no gradient can be defined!");
                }

                // tracker needs to be updated to get access to the cut-cell mask
                this.LsTrk.UpdateTracker(0.0);

                // ==============================
                // level-set initialization
                // ==============================

                //PlotCurrentState(0.0, new TimestepNumber(new int[] { 0, 0 }), 3);

                #region Initialize Level Set Evolution Algorithm
                switch (this.Control.Option_LevelSetEvolution)
                {
                case LevelSetEvolution.Fourier:
                    InitFourier();
                    break;

                case LevelSetEvolution.None:
                    if (this.Control.AdvancedDiscretizationOptions.SST_isotropicMode == SurfaceStressTensor_IsotropicMode.Curvature_Fourier)
                    {
                        Fourier_LevSet = FourierLevelSetFactory.Build(this.Control.FourierLevSetControl);
                        Fourier_LevSet.ProjectToDGLevelSet(this.DGLevSet.Current, this.LsTrk);
                    }
                    else
                    {
                        goto default;
                    }
                    break;

                case LevelSetEvolution.ExtensionVelocity: {
                    // Create ExtensionVelocity Motion Algorithm
                    this.DGLevSet.Current.Clear();
                    this.DGLevSet.Current.AccLaidBack(1.0, this.LevSet);
                    DGLevSetGradient.Gradient(1.0, DGLevSet.Current);
                    //VectorField<SinglePhaseField> VectorExtVel = ExtensionVelocity.Current;
                    base.RegisterField(ExtensionVelocity.Current);

                    //ReInitPDE = new EllipticReInit(this.LsTrk, this.Control.ReInitControl, DGLevSet.Current);
                    FastMarchReinitSolver = new FastMarchReinit(DGLevSet.Current.Basis);

                    // full initial reinitialization
                    //ReInitPDE.ReInitialize(Restriction: LsTrk.Regions.GetNearFieldSubgrid(1));

                    CellMask Accepted      = LsTrk.Regions.GetNearFieldMask(1);
                    CellMask ActiveField   = Accepted.Complement();
                    CellMask NegativeField = LsTrk.Regions.GetSpeciesMask("A");
                    FastMarchReinitSolver.FirstOrderReinit(DGLevSet.Current, Accepted, NegativeField, ActiveField);

                    //ReInitPDE.ReInitialize();

                    // setup extension velocity mover
                    switch (this.Control.TimeSteppingScheme)
                    {
                    case TimeSteppingScheme.RK_CrankNic:
                    case TimeSteppingScheme.CrankNicolson: {
                        //do not instantiate rksch, use bdf instead
                        bdfOrder = -1;
                        break;
                    }

                    case TimeSteppingScheme.RK_ImplicitEuler:
                    case TimeSteppingScheme.ImplicitEuler: {
                        //do not instantiate rksch, use bdf instead
                        bdfOrder = 1;
                        break;
                    }

                    default: {
                        if (this.Control.TimeSteppingScheme.ToString().StartsWith("BDF"))
                        {
                            //do not instantiate rksch, use bdf instead
                            bdfOrder = Convert.ToInt32(this.Control.TimeSteppingScheme.ToString().Substring(3));
                            break;
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                    }
                    }

                    ExtVelMover = new ExtensionVelocityBDFMover(LsTrk, DGLevSet.Current, DGLevSetGradient, new VectorField <DGField>(XDGvelocity.Velocity.ToArray()),
                                                                Control.EllipticExtVelAlgoControl, BcMap, bdfOrder, ExtensionVelocity.Current, new double[2] {
                            Control.PhysicalParameters.rho_A, Control.PhysicalParameters.rho_B
                        });


                    break;
                }

                case LevelSetEvolution.FastMarching:
                case LevelSetEvolution.Prescribed:
                case LevelSetEvolution.ScalarConvection:
                default:
                    // evolution algorithms need a signed-distance level-set:
                    // do some reinit at startup
                    //BoSSS.Solution.LevelSetTools.Advection.NarrowMarchingBand.CutCellReinit(this.LsTrk, this.DGLevSet.Current);
                    // apply only the minimal necessary change
                    this.DGLevSet.Current.Clear();
                    this.DGLevSet.Current.AccLaidBack(1.0, this.LevSet);

                    //FastMarchReinitSolver = new FastMarchReinit(DGLevSet.Current.Basis);

                    break;
                }
                //PlotCurrentState(0.0, new TimestepNumber(new int[] { 0, 1 }), 3);
                #endregion

                // =========================================
                // Enforcing the continuity of the level-set
                // =========================================

                ContinuityEnforcer = new ContinuityProjection(
                    ContBasis: this.LevSet.Basis,
                    DGBasis: this.DGLevSet.Current.Basis,
                    gridData: GridData,
                    Option: Control.LSContiProjectionMethod
                    );

                //var CC = this.LsTrk.Regions.GetCutCellMask4LevSet(0);
                var Near1 = this.LsTrk.Regions.GetNearMask4LevSet(0, 1);
                var Near  = this.LsTrk.Regions.GetNearMask4LevSet(0, this.Control.LS_TrackerWidth);
                var PosFF = this.LsTrk.Regions.GetLevelSetWing(0, +1).VolumeMask;

                if (this.Control.Option_LevelSetEvolution != LevelSetEvolution.ExtensionVelocity)
                {
                    ContinuityEnforcer.SetFarField(this.DGLevSet.Current, Near1, PosFF);
                }

                ContinuityEnforcer.MakeContinuous(this.DGLevSet.Current, this.LevSet, Near, PosFF);

                //PlotCurrentState(0.0, new TimestepNumber(new int[] { 0, 2 }), 3);

                this.LsTrk.UpdateTracker(0.0);
            }
        }