Example #1
0
        public IBMAdamsBashforthLTS(SpatialOperator standardOperator, SpatialOperator boundaryOperator, CoordinateMapping fieldsMap, CoordinateMapping boundaryParameterMap, ISpeciesMap ibmSpeciesMap, IBMControl control, IList <TimeStepConstraint> timeStepConstraints, int reclusteringInterval, bool fluxCorrection)
            : base(standardOperator, fieldsMap, boundaryParameterMap, control.ExplicitOrder, control.NumberOfSubGrids, true, timeStepConstraints, reclusteringInterval: reclusteringInterval, fluxCorrection: fluxCorrection, subGrid: ibmSpeciesMap.SubGrid)
        {
            this.speciesMap = ibmSpeciesMap as ImmersedSpeciesMap;
            if (this.speciesMap == null)
            {
                throw new ArgumentException(
                          "Only supported for species maps of type 'ImmersedSpeciesMap'",
                          "speciesMap");
            }
            this.standardOperator     = standardOperator;
            this.boundaryOperator     = boundaryOperator;
            this.boundaryParameterMap = boundaryParameterMap;
            this.fieldsMap            = fieldsMap;
            this.control = control;

            agglomerationPatternHasChanged = true;

            cutCells          = speciesMap.Tracker.Regions.GetCutCellMask();
            cutAndTargetCells = cutCells.Union(speciesMap.Agglomerator.AggInfo.TargetCells);

            // Normal LTS constructor
            NumberOfLocalTimeSteps = new List <int>(control.NumberOfSubGrids);

            clusterer = new Clusterer(this.gridData, this.TimeStepConstraints);

            CurrentClustering = clusterer.CreateClustering(control.NumberOfSubGrids, speciesMap.SubGrid);
            CurrentClustering = CalculateNumberOfLocalTS(CurrentClustering); // Might remove sub-grids when time step sizes are too similar

            ABevolver = new IBMABevolve[CurrentClustering.NumberOfClusters];

            for (int i = 0; i < ABevolver.Length; i++)
            {
                ABevolver[i] = new IBMABevolve(standardOperator, boundaryOperator, fieldsMap, boundaryParameterMap, speciesMap, control.ExplicitOrder, control.LevelSetQuadratureOrder, control.CutCellQuadratureType, sgrd: CurrentClustering.Clusters[i], adaptive: this.adaptive);
                ABevolver[i].OnBeforeComputeChangeRate += (t1, t2) => this.RaiseOnBeforeComputechangeRate(t1, t2);
            }

            GetBoundaryTopology();

#if DEBUG
            for (int i = 0; i < CurrentClustering.NumberOfClusters; i++)
            {
                Console.WriteLine("IBM AB LTS ctor: id=" + i + " -> sub-steps=" + NumberOfLocalTimeSteps[i] + " and elements=" + CurrentClustering.Clusters[i].GlobalNoOfCells);
            }
#endif

            // Start-up phase needs an IBM Runge-Kutta time stepper
            RungeKuttaScheme = new IBMSplitRungeKutta(standardOperator, boundaryOperator, fieldsMap, boundaryParameterMap, speciesMap, timeStepConstraints);
        }
Example #2
0
        internal void BuildEvaluatorsAndMasks()
        {
            CellMask fluidCells = speciesMap.SubGrid.VolumeMask.Intersect(ABSubGrid.VolumeMask);

            cutCells          = speciesMap.Tracker.Regions.GetCutCellMask().Intersect(ABSubGrid.VolumeMask);
            cutAndTargetCells = cutCells.Union(speciesMap.Agglomerator.AggInfo.TargetCells).Intersect(ABSubGrid.VolumeMask);


            IBMControl control = speciesMap.Control;
            SpeciesId  species = speciesMap.Tracker.GetSpeciesId(control.FluidSpeciesName);

            CellQuadratureScheme volumeScheme = speciesMap.QuadSchemeHelper.GetVolumeQuadScheme(
                species, true, fluidCells, control.LevelSetQuadratureOrder);


            // Does _not_ include agglomerated edges
            EdgeMask nonVoidEdges = speciesMap.QuadSchemeHelper.GetEdgeMask(species);

            nonVoidEdges = nonVoidEdges.Intersect(ABSubGrid.AllEdgesMask.ToGeometicalMask());
            EdgeQuadratureScheme edgeScheme = speciesMap.QuadSchemeHelper.GetEdgeQuadScheme(
                species, true, nonVoidEdges, control.LevelSetQuadratureOrder);

            this.m_Evaluator = new Lazy <IEvaluatorNonLin>(delegate() {
                this.Operator.EdgeQuadraturSchemeProvider   = g => edgeScheme;
                this.Operator.VolumeQuadraturSchemeProvider = g => volumeScheme;

                var opi = this.Operator.GetEvaluatorEx(
                    Mapping,
                    boundaryParameterMap,
                    Mapping);
                opi.ActivateSubgridBoundary(ABSubGrid.VolumeMask, subGridBoundaryTreatment: SubGridBoundaryModes.InnerEdgeLTS);
                return(opi);
            });

            // Evaluator for boundary conditions at level set zero contour
            CellQuadratureScheme boundaryVolumeScheme = speciesMap.QuadSchemeHelper.GetLevelSetquadScheme(
                0, cutCells, control.LevelSetQuadratureOrder);

            this.boundaryEvaluator = new Lazy <IEvaluatorNonLin>(delegate() {
                boundaryOperator.EdgeQuadraturSchemeProvider   = g => null; // Contains no boundary terms --> PROBLEM??????????
                boundaryOperator.VolumeQuadraturSchemeProvider = g => boundaryVolumeScheme;
                return(boundaryOperator.GetEvaluatorEx(
                           Mapping,
                           boundaryParameterMap,
                           Mapping));
            });
        }
Example #3
0
        internal void BuildEvaluatorsAndMasks()
        {
            CellMask fluidCells = speciesMap.SubGrid.VolumeMask.Intersect(ABSubGrid.VolumeMask);

            cutCells          = speciesMap.Tracker.Regions.GetCutCellMask().Intersect(ABSubGrid.VolumeMask);
            cutAndTargetCells = cutCells.Union(speciesMap.Agglomerator.AggInfo.TargetCells).Intersect(ABSubGrid.VolumeMask);


            IBMControl control = speciesMap.Control;
            SpeciesId  species = speciesMap.Tracker.GetSpeciesId(control.FluidSpeciesName);

            CellQuadratureScheme volumeScheme = speciesMap.QuadSchemeHelper.GetVolumeQuadScheme(
                species, true, fluidCells, control.LevelSetQuadratureOrder);


            // Does _not_ include agglomerated edges
            EdgeMask nonVoidEdges = speciesMap.QuadSchemeHelper.GetEdgeMask(species);

            nonVoidEdges = nonVoidEdges.Intersect(ABSubGrid.AllEdgesMask);
            EdgeQuadratureScheme edgeScheme = speciesMap.QuadSchemeHelper.GetEdgeQuadScheme(
                species, true, nonVoidEdges, control.LevelSetQuadratureOrder);

            this.m_Evaluator = new Lazy <SpatialOperator.Evaluator>(() =>
                                                                    this.Operator.GetEvaluatorEx(
                                                                        Mapping,
                                                                        boundaryParameterMap,
                                                                        Mapping,
                                                                        edgeScheme,
                                                                        volumeScheme,
                                                                        ABSubGrid,
                                                                        subGridBoundaryTreatment: SpatialOperator.SubGridBoundaryModes.InnerEdgeLTS));

            // Evaluator for boundary conditions at level set zero contour
            CellQuadratureScheme boundaryVolumeScheme = speciesMap.QuadSchemeHelper.GetLevelSetquadScheme(
                0, cutCells, control.LevelSetQuadratureOrder);

            this.boundaryEvaluator = new Lazy <SpatialOperator.Evaluator>(() =>
                                                                          boundaryOperator.GetEvaluatorEx(
                                                                              Mapping,
                                                                              boundaryParameterMap,
                                                                              Mapping,
                                                                              null, // Contains no boundary terms --> PROBLEM??????????
                                                                              boundaryVolumeScheme));
        }
        private void BuildEvaluatorsAndMasks()
        {
            CellMask fluidCells = speciesMap.SubGrid.VolumeMask;

            cutCells          = speciesMap.Tracker.Regions.GetCutCellMask();
            cutAndTargetCells = cutCells.Union(speciesMap.Agglomerator.AggInfo.TargetCells);

            IBMControl control = speciesMap.Control;
            SpeciesId  species = speciesMap.Tracker.GetSpeciesId(control.FluidSpeciesName);

            CellQuadratureScheme volumeScheme = speciesMap.QuadSchemeHelper.GetVolumeQuadScheme(
                species, true, fluidCells, control.LevelSetQuadratureOrder);

            // Does _not_ include agglomerated edges
            EdgeMask             nonVoidEdges = speciesMap.QuadSchemeHelper.GetEdgeMask(species);
            EdgeQuadratureScheme edgeScheme   = speciesMap.QuadSchemeHelper.GetEdgeQuadScheme(
                species, true, nonVoidEdges, control.LevelSetQuadratureOrder);

            this.m_Evaluator = new Lazy <IEvaluatorNonLin>(delegate() {
                this.Operator.EdgeQuadraturSchemeProvider   = g => edgeScheme;
                this.Operator.VolumeQuadraturSchemeProvider = g => volumeScheme;
                var opi = this.Operator.GetEvaluatorEx(
                    Mapping,
                    null, // TO DO: I SIMPLY REMOVE PARAMETERMAP HERE; MAKE THIS MORE PRETTY
                          //this.boundaryParameterMap, // TO DO: I SIMPLY REMOVE PARAMETERMAP HERE; MAKE THIS MORE PRETTY
                    Mapping);
                opi.ActivateSubgridBoundary(volumeScheme.Domain, subGridBoundaryTreatment: SubGridBoundaryModes.InnerEdgeLTS);
                //opi.ActivateSubgridBoundary(fluidCells, subGridBoundaryTreatment: SubGridBoundaryModes.InnerEdgeLTS);
                return(opi);
            });

            // Evaluator for boundary conditions at level set zero contour
            CellQuadratureScheme boundaryVolumeScheme = speciesMap.QuadSchemeHelper.GetLevelSetquadScheme(
                0, cutCells, control.LevelSetQuadratureOrder);

            this.boundaryEvaluator = new Lazy <IEvaluatorNonLin>(delegate() {
                boundaryOperator.EdgeQuadraturSchemeProvider   = g => null; // Contains no boundary terms
                boundaryOperator.VolumeQuadraturSchemeProvider = g => boundaryVolumeScheme;
                return(boundaryOperator.GetEvaluatorEx(
                           Mapping,
                           boundaryParameterMap,
                           Mapping));
            });
        }
Example #5
0
        protected void UpdateEvaluatorsAndMasks()
        {
            CellMask fluidCells = speciesMap.SubGrid.VolumeMask;

            cutCells          = speciesMap.Tracker.Regions.GetCutCellMask();
            cutAndTargetCells = cutCells.Union(speciesMap.Agglomerator.AggInfo.TargetCells);

            IBMControl control = speciesMap.Control;
            SpeciesId  species = speciesMap.Tracker.GetSpeciesId(control.FluidSpeciesName);

            CellQuadratureScheme volumeScheme = speciesMap.QuadSchemeHelper.GetVolumeQuadScheme(
                species, true, fluidCells, control.LevelSetQuadratureOrder);

            // Does _not_ include agglomerated edges
            EdgeMask             nonVoidEdges = speciesMap.QuadSchemeHelper.GetEdgeMask(species);
            EdgeQuadratureScheme edgeScheme   = speciesMap.QuadSchemeHelper.GetEdgeQuadScheme(
                species, true, nonVoidEdges, control.LevelSetQuadratureOrder);

            this.m_Evaluator = new Lazy <IEvaluatorNonLin>(delegate() {
                var opi = this.Operator.GetEvaluatorEx(
                    Mapping,
                    boundaryParameterMap,
                    Mapping,
                    edgeScheme,
                    volumeScheme);
                opi.ActivateSubgridBoundary(volumeScheme.Domain.ToLogicalMask(), subGridBoundaryTreatment: SpatialOperator.SubGridBoundaryModes.InnerEdgeLTS);
                return(opi);
            });

            // Evaluator for boundary conditions at level set zero contour
            CellQuadratureScheme boundaryVolumeScheme = speciesMap.QuadSchemeHelper.GetLevelSetquadScheme(
                0, cutCells, control.LevelSetQuadratureOrder);

            this.boundaryEvaluator = new Lazy <IEvaluatorNonLin>(() =>
                                                                 boundaryOperator.GetEvaluatorEx(
                                                                     Mapping,
                                                                     boundaryParameterMap,
                                                                     Mapping,
                                                                     null, // Contains no boundary terms
                                                                     boundaryVolumeScheme));
        }
Example #6
0
        /// <summary>
        /// compiles a cell mask from all cells with a specific color and their direct neighbors
        /// </summary>
        /// <param name="gridData">
        /// the grid that this mask will be associated with
        /// </param>
        /// <param name="ColoredCellsSorted">
        /// a list of all cells sorted by color
        /// </param>
        /// <param name="CurrentColor">
        /// the color which is associated with the Cell Mask
        /// </param>
        /// /// <param name="J">
        /// the number of locally updated cells
        /// </param>
        internal CellMask CellsOneColor(IGridData gridData, List <int[]> ColoredCellsSorted, int CurrentColor, int J, bool FindNeighbours = true)
        {
            int[]    CellIDCurrentColor = FindCellIDs(ColoredCellsSorted, CurrentColor);
            BitArray ColoredCells       = new BitArray(J);

            for (int i = 0; i < CellIDCurrentColor.Length; i++)
            {
                if (CellIDCurrentColor[i] < J)
                {
                    ColoredCells[CellIDCurrentColor[i]] = true;
                }
            }
            CellMask ColoredCellMask = new CellMask(gridData, ColoredCells);

            if (FindNeighbours)
            {
                CellMask ColoredCellMaskNeighbour = ColoredCellMask.AllNeighbourCells();
                ColoredCellMask = ColoredCellMask.Union(ColoredCellMaskNeighbour);
            }
            return(ColoredCellMask);
        }
Example #7
0
        protected void MoveLevelSetTo(double time)
        {
            LevelSet levelSet = speciesMap.Tracker.LevelSets[0].As <LevelSet>();

            levelSet.Clear();
            levelSet.ProjectField(X => speciesMap.Control.LevelSetFunction(X, time));
            speciesMap.Tracker.UpdateTracker();

            cutCells          = speciesMap.Tracker.Regions.GetCutCellMask();
            cutAndTargetCells = cutCells.Union(speciesMap.Agglomerator.AggInfo.TargetCells);

            // EVIL HACK SINCE UPDATE OF GRADIENT ONLY HAPPENS AFTER TIME-STEP SO FAR
            foreach (var gradientField in boundaryParameterMap.Fields)
            {
                int d = int.Parse(gradientField.Identification.Last().ToString());

                gradientField.Clear();
                gradientField.Derivative(
                    -1.0,
                    levelSet,
                    d,
                    cutCells);
            }
        }
Example #8
0
        /// <summary>
        /// Computes the new level set field at time <paramref name="Phystime"/> + <paramref name="dt"/>.
        /// This is a 'driver function' which provides a universal interface to the various level set evolution algorithms.
        /// It also acts as a callback to the time stepper (see <see cref="m_BDF_Timestepper"/> resp. <see cref="m_RK_Timestepper"/>),
        /// i.e. it matches the signature of
        /// <see cref="BoSSS.Solution.XdgTimestepping.DelUpdateLevelset"/>.
        /// </summary>
        /// <param name="Phystime"></param>
        /// <param name="dt"></param>
        /// <param name="CurrentState">
        /// The current solution (velocity and pressure), since the complete solution is provided by the time stepper,
        /// only the velocity components(supposed to be at the beginning) are used.
        /// </param>
        /// <param name="underrelax">
        /// </param>
        public double DelUpdateLevelSet(DGField[] CurrentState, double Phystime, double dt, double underrelax, bool incremental)
        {
            using (new FuncTrace()) {
                //dt *= underrelax;
                int       D           = base.Grid.SpatialDimension;
                int       iTimestep   = hack_TimestepIndex;
                DGField[] EvoVelocity = CurrentState.GetSubVector(0, D);


                // ========================================================
                // Backup old level-set, in order to compute the residual
                // ========================================================

                SinglePhaseField LsBkUp = new SinglePhaseField(this.LevSet.Basis);
                LsBkUp.Acc(1.0, this.LevSet);
                CellMask oldCC = LsTrk.Regions.GetCutCellMask();

                // ====================================================
                // set evolution velocity, but only on the CUT-cells
                // ====================================================

                #region Calculate density averaged Velocity for each cell

                ConventionalDGField[] meanVelocity = GetMeanVelocityFromXDGField(EvoVelocity);

                #endregion


                // ===================================================================
                // backup interface properties (mass conservation, surface changerate)
                // ===================================================================

                #region backup interface props

                double oldSurfVolume  = 0.0;
                double oldSurfLength  = 0.0;
                double SurfChangerate = 0.0;
                if (this.Control.CheckInterfaceProps)
                {
                    oldSurfVolume  = XNSEUtils.GetSpeciesArea(this.LsTrk, LsTrk.GetSpeciesId("A"));
                    oldSurfLength  = XNSEUtils.GetInterfaceLength(this.LsTrk);
                    SurfChangerate = EnergyUtils.GetSurfaceChangerate(this.LsTrk, meanVelocity, this.m_HMForder);
                }

                #endregion

                // ====================================================
                // perform level-set evolution
                // ====================================================

                #region level-set evolution

                // set up for Strang splitting
                SinglePhaseField DGLevSet_old;
                if (incremental)
                {
                    DGLevSet_old = this.DGLevSet.Current.CloneAs();
                }
                else
                {
                    DGLevSet_old = this.DGLevSet[0].CloneAs();
                }


                // set up for underrelaxation
                SinglePhaseField DGLevSet_oldIter = this.DGLevSet.Current.CloneAs();

                //PlotCurrentState(hack_Phystime, new TimestepNumber(new int[] { hack_TimestepIndex, 0 }), 2);

                // actual evolution
                switch (this.Control.Option_LevelSetEvolution)
                {
                case LevelSetEvolution.None:
                    throw new ArgumentException("illegal call");

                case LevelSetEvolution.FastMarching: {
                    NarrowMarchingBand.Evolve_Mk2(
                        dt, this.LsTrk, DGLevSet_old, this.DGLevSet.Current, this.DGLevSetGradient,
                        meanVelocity, this.ExtensionVelocity.Current.ToArray(),      //new DGField[] { LevSetSrc },
                        this.m_HMForder, iTimestep);

                    //FastMarchReinitSolver = new FastMarchReinit(DGLevSet.Current.Basis);
                    //CellMask Accepted = LsTrk.Regions.GetCutCellMask();
                    //CellMask ActiveField = LsTrk.Regions.GetNearFieldMask(1);
                    //CellMask NegativeField = LsTrk.Regions.GetSpeciesMask("A");
                    //FastMarchReinitSolver.FirstOrderReinit(DGLevSet.Current, Accepted, NegativeField, ActiveField);

                    break;
                }

                case LevelSetEvolution.Fourier: {
                    Fourier_Timestepper.moveLevelSet(dt, meanVelocity);
                    if (incremental)
                    {
                        Fourier_Timestepper.updateFourierLevSet();
                    }
                    Fourier_LevSet.ProjectToDGLevelSet(this.DGLevSet.Current, this.LsTrk);
                    break;
                }

                case LevelSetEvolution.Prescribed: {
                    this.DGLevSet.Current.Clear();
                    this.DGLevSet.Current.ProjectField(1.0, this.Control.Phi.Vectorize(Phystime + dt));
                    break;
                }

                case LevelSetEvolution.ScalarConvection: {
                    var LSM = new LevelSetMover(EvoVelocity,
                                                this.ExtensionVelocity,
                                                this.LsTrk,
                                                XVelocityProjection.CutCellVelocityProjectiontype.L2_plain,
                                                this.DGLevSet,
                                                this.BcMap);

                    int check1 = this.ExtensionVelocity.PushCount;
                    int check2 = this.DGLevSet.PushCount;

                    this.DGLevSet[1].Clear();
                    this.DGLevSet[1].Acc(1.0, DGLevSet_old);
                    LSM.Advect(dt);

                    if (check1 != this.ExtensionVelocity.PushCount)
                    {
                        throw new ApplicationException();
                    }
                    if (check2 != this.DGLevSet.PushCount)
                    {
                        throw new ApplicationException();
                    }

                    break;
                }

                case LevelSetEvolution.ExtensionVelocity: {
                    DGLevSetGradient.Clear();
                    DGLevSetGradient.Gradient(1.0, DGLevSet.Current);

                    ExtVelMover.Advect(dt);

                    // Fast Marching: Specify the Domains first
                    // Perform Fast Marching only on the Far Field
                    if (this.Control.AdaptiveMeshRefinement)
                    {
                        int      NoCells = ((GridData)this.GridData).Cells.Count;
                        BitArray Refined = new BitArray(NoCells);
                        for (int j = 0; j < NoCells; j++)
                        {
                            if (((GridData)this.GridData).Cells.GetCell(j).RefinementLevel > 0)
                            {
                                Refined[j] = true;
                            }
                        }
                        CellMask Accepted      = new CellMask(this.GridData, Refined);
                        CellMask AcceptedNeigh = Accepted.AllNeighbourCells();

                        Accepted = Accepted.Union(AcceptedNeigh);
                        CellMask ActiveField   = Accepted.Complement();
                        CellMask NegativeField = LsTrk.Regions.GetSpeciesMask("A");
                        FastMarchReinitSolver.FirstOrderReinit(DGLevSet.Current, Accepted, NegativeField, ActiveField);
                    }
                    else
                    {
                        CellMask Accepted      = LsTrk.Regions.GetNearFieldMask(1);
                        CellMask ActiveField   = Accepted.Complement();
                        CellMask NegativeField = LsTrk.Regions.GetSpeciesMask("A");
                        FastMarchReinitSolver.FirstOrderReinit(DGLevSet.Current, Accepted, NegativeField, ActiveField);
                    }
                    //SubGrid AcceptedGrid = new SubGrid(Accepted);
                    //ReInitPDE.ReInitialize(Restriction: AcceptedGrid);

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

                    //ReInitPDE.ReInitialize();

                    break;
                }

                default:
                    throw new ApplicationException();
                }


                // performing underrelaxation
                if (underrelax < 1.0)
                {
                    this.DGLevSet.Current.Scale(underrelax);
                    this.DGLevSet.Current.Acc((1.0 - underrelax), DGLevSet_oldIter);
                }

                //PlotCurrentState(hack_Phystime, new TimestepNumber(new int[] { hack_TimestepIndex, 1 }), 2);


                #endregion


                // ======================
                // postprocessing
                // =======================

                if (this.Control.ReInitPeriod > 0 && hack_TimestepIndex % this.Control.ReInitPeriod == 0)
                {
                    Console.WriteLine("Filtering DG-LevSet");
                    SinglePhaseField FiltLevSet = new SinglePhaseField(DGLevSet.Current.Basis);
                    FiltLevSet.AccLaidBack(1.0, DGLevSet.Current);
                    Filter(FiltLevSet, 2, oldCC);
                    DGLevSet.Current.Clear();
                    DGLevSet.Current.Acc(1.0, FiltLevSet);

                    Console.WriteLine("FastMarchReInit performing FirstOrderReInit");
                    FastMarchReinitSolver = new FastMarchReinit(DGLevSet.Current.Basis);
                    CellMask Accepted      = LsTrk.Regions.GetCutCellMask();
                    CellMask ActiveField   = LsTrk.Regions.GetNearFieldMask(1);
                    CellMask NegativeField = LsTrk.Regions.GetSpeciesMask("A");
                    FastMarchReinitSolver.FirstOrderReinit(DGLevSet.Current, Accepted, NegativeField, ActiveField);
                }

                #region ensure continuity

                // make level set continuous
                CellMask CC    = LsTrk.Regions.GetCutCellMask4LevSet(0);
                CellMask Near1 = LsTrk.Regions.GetNearMask4LevSet(0, 1);
                CellMask PosFF = LsTrk.Regions.GetLevelSetWing(0, +1).VolumeMask;
                ContinuityEnforcer.MakeContinuous(this.DGLevSet.Current, this.LevSet, Near1, PosFF);

                if (this.Control.Option_LevelSetEvolution == LevelSetEvolution.FastMarching)
                {
                    CellMask Nearband = Near1.Union(CC);
                    this.DGLevSet.Current.Clear(Nearband);
                    this.DGLevSet.Current.AccLaidBack(1.0, this.LevSet, Nearband);
                    //ContinuityEnforcer.SetFarField(this.DGLevSet.Current, Near1, PosFF);
                }

                //PlotCurrentState(hack_Phystime, new TimestepNumber(new int[] { hack_TimestepIndex, 2 }), 2);

                #endregion


                for (int d = 0; d < D; d++)
                {
                    this.XDGvelocity.Velocity[d].UpdateBehaviour = BehaveUnder_LevSetMoovement.AutoExtrapolate;
                }



                // ===============
                // tracker update
                // ===============

                this.LsTrk.UpdateTracker(Phystime + dt, incremental: true);

                // update near field (in case of adaptive mesh refinement)
                if (this.Control.AdaptiveMeshRefinement && this.Control.Option_LevelSetEvolution == LevelSetEvolution.FastMarching)
                {
                    Near1 = LsTrk.Regions.GetNearMask4LevSet(0, 1);
                    PosFF = LsTrk.Regions.GetLevelSetWing(0, +1).VolumeMask;
                    ContinuityEnforcer.SetFarField(this.DGLevSet.Current, Near1, PosFF);
                    ContinuityEnforcer.SetFarField(this.LevSet, Near1, PosFF);
                }


                // ==================================================================
                // check interface properties (mass conservation, surface changerate)
                // ==================================================================

                if (this.Control.CheckInterfaceProps)
                {
                    double currentSurfVolume = XNSEUtils.GetSpeciesArea(this.LsTrk, LsTrk.GetSpeciesId("A"));
                    double massChange        = ((currentSurfVolume - oldSurfVolume) / oldSurfVolume) * 100;
                    Console.WriteLine("Change of mass = {0}%", massChange);

                    double currentSurfLength    = XNSEUtils.GetInterfaceLength(this.LsTrk);
                    double actualSurfChangerate = (currentSurfLength - oldSurfLength) / dt;
                    Console.WriteLine("Interface divergence = {0}", SurfChangerate);
                    Console.WriteLine("actual surface changerate = {0}", actualSurfChangerate);
                }


                // ==================
                // compute residual
                // ==================

                var newCC = LsTrk.Regions.GetCutCellMask();
                LsBkUp.Acc(-1.0, this.LevSet);
                double LevSetResidual = LsBkUp.L2Norm(newCC.Union(oldCC));

                return(LevSetResidual);
            }
        }
Example #9
0
        /// <summary>
        /// Computes Cell-volumes and edge areas before agglomeration.
        /// </summary>
        void ComputeNonAgglomeratedMetrics()
        {
            var gd = XDGSpaceMetrics.GridDat;
            int JE = gd.Cells.NoOfCells;
            int J  = gd.Cells.NoOfLocalUpdatedCells;
            int D  = gd.SpatialDimension;
            int EE = gd.Edges.Count;

            SpeciesId[] species = this.SpeciesList.ToArray();
            int         NoSpc   = species.Count();

            int[,] E2C = gd.Edges.CellIndices;

            var schH = new XQuadSchemeHelper(XDGSpaceMetrics);

            double[] vec_cellMetrics = new double[JE * NoSpc * 2];

            // collect all per-cell-metrics in the same MultidimArry, for MPI-exchange
            // 1st index: cell
            // 2nd index: species
            // 3rd index: 0 for interface surface per cell, 1 for cut-cell-volume
            MultidimensionalArray cellMetrics = MultidimensionalArray.CreateWrapper(vec_cellMetrics, JE, NoSpc, 2);

            this.CutEdgeAreas   = new Dictionary <SpeciesId, MultidimensionalArray>();
            this.CutCellVolumes = new Dictionary <SpeciesId, MultidimensionalArray>();
            this.InterfaceArea  = new Dictionary <SpeciesId, MultidimensionalArray>();

            //var schS = new List<CellQuadratureScheme>();
            //var rulz = new List<ICompositeQuadRule<QuadRule>>();


            // edges and volumes
            // =================
            for (int iSpc = 0; iSpc < species.Length; iSpc++)
            {
                var cellVol = cellMetrics.ExtractSubArrayShallow(-1, iSpc, 1);
                var spc     = species[iSpc];

                MultidimensionalArray edgArea = MultidimensionalArray.Create(EE);
                this.CutEdgeAreas.Add(spc, edgArea);

                // compute cut edge area
                // ---------------------

                var edgeScheme = schH.GetEdgeQuadScheme(spc);
                var edgeRule   = edgeScheme.Compile(gd, this.CutCellQuadratureOrder);

                BoSSS.Foundation.Quadrature.EdgeQuadrature.GetQuadrature(
                    new int[] { 1 }, gd,
                    edgeRule,
                    _Evaluate : delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) //
                {
                    EvalResult.SetAll(1.0);
                },
                    _SaveIntegrationResults : delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) //
                {
                    for (int i = 0; i < Length; i++)
                    {
                        int iEdge = i + i0;
                        Debug.Assert(edgArea[iEdge] == 0);
                        edgArea[iEdge] = ResultsOfIntegration[i, 0];
                        Debug.Assert(!(double.IsNaN(edgArea[iEdge]) || double.IsInfinity(edgArea[iEdge])));
                    }
                }).Execute();

                // compute cut cell volumes
                // ------------------------

                var volScheme = schH.GetVolumeQuadScheme(spc);
                var volRule   = volScheme.Compile(gd, this.CutCellQuadratureOrder);

                //schS.Add(volScheme);
                //rulz.Add(volRule);

                BoSSS.Foundation.Quadrature.CellQuadrature.GetQuadrature(
                    new int[] { 1 }, gd,
                    volRule,
                    _Evaluate : delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) //
                {
                    EvalResult.SetAll(1.0);
                },
                    _SaveIntegrationResults : delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) //
                {
                    for (int i = 0; i < Length; i++)
                    {
                        int jCell = i + i0;
                        Debug.Assert(cellVol[jCell] == 0);
                        cellVol[jCell] = ResultsOfIntegration[i, 0];
                        Debug.Assert(!(double.IsNaN(cellVol[jCell]) || double.IsInfinity(cellVol[jCell])));
                    }
                }).Execute();
            }


            // interface surface
            // =================

            // loop over all possible pairs of species

            /*
             * for (int iSpcA = 0; iSpcA < species.Length; iSpcA++) {
             *  var SpeciesA = species[iSpcA];
             *  var SpeciesADom = lsTrk.GetSpeciesMask(SpeciesA);
             *  if (SpeciesADom.NoOfItemsLocally <= 0)
             *      continue;
             *
             *  for (int iSpcB = iSpcA + 1; iSpcB < species.Length; iSpcB++) {
             *      var SpeciesB = species[iSpcB];
             *      var SpeciesBDom = lsTrk.GetSpeciesMask(SpeciesB);
             *      if (SpeciesBDom.NoOfItemsLocally <= 0)
             *          continue;
             *
             *      var SpeciesCommonDom = SpeciesADom.Intersect(SpeciesBDom);
             *      if (SpeciesCommonDom.NoOfItemsLocally <= 0)
             *          continue;
             *
             *      // loop over level-sets
             *      int NoOfLs = lsTrk.LevelSets.Count;
             *      for (int iLevSet = 0; iLevSet < NoOfLs; iLevSet++) {
             *
             *
             *          var LsDom = lsTrk.GetCutCellMask4LevSet(iLevSet);
             *          var IntegrationDom = LsDom.Intersect(SpeciesCommonDom);
             *
             *          if (IntegrationDom.NoOfItemsLocally > 0) {
             *              CellQuadratureScheme SurfIntegration = schH.GetLevelSetquadScheme(iLevSet, IntegrationDom);
             *              var rule = SurfIntegration.Compile(gd, this.HMForder);
             *
             *
             *              BoSSS.Foundation.Quadrature.CellQuadrature.GetQuadrature(
             *                  new int[] { 1 }, gd,
             *                  rule,
             *                  _Evaluate: delegate (int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) //
             *                  {
             *                      EvalResult.SetAll(1.0);
             *                  },
             *                  _SaveIntegrationResults: delegate (int i0, int Length, MultidimensionalArray ResultsOfIntegration) //
             *                  {
             *                      for (int i = 0; i < Length; i++) {
             *                          int jCell = i + i0;
             *                          if (cellMetrics[jCell, iSpcA, 0] != 0.0)
             *                              throw new NotSupportedException("More than one zero-level-set per cell is not supported yet.");
             *                          if (cellMetrics[jCell, iSpcB, 0] != 0.0)
             *                              throw new NotSupportedException("More than one zero-level-set per cell is not supported yet.");
             *
             *                          cellMetrics[jCell, iSpcA, 0] = ResultsOfIntegration[i, 0];
             *                          cellMetrics[jCell, iSpcB, 0] = ResultsOfIntegration[i, 0];
             *                      }
             *                  }).Execute();
             *          }
             *      }
             *  }
             * }*/

            // loop over level-sets
            if (species.Length > 0)
            {
                // find domain of all species:
                CellMask SpeciesCommonDom = XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(species[0]);
                for (int iSpc = 1; iSpc < species.Length; iSpc++)
                {
                    SpeciesCommonDom = SpeciesCommonDom.Union(XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(species[iSpc]));
                }
                BitArray[] SpeciesBitMask = species.Select(spc => XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(spc).GetBitMask()).ToArray();

                int NoOfLs  = XDGSpaceMetrics.NoOfLevelSets;
                int NoOfSpc = species.Length;
                for (int iLevSet = 0; iLevSet < NoOfLs; iLevSet++)
                {
                    var LsDom          = XDGSpaceMetrics.LevelSetRegions.GetCutCellMask4LevSet(iLevSet);
                    var IntegrationDom = LsDom.Intersect(SpeciesCommonDom);

                    //if (IntegrationDom.NoOfItemsLocally > 0) { -> Doesn't work if Bjoerns HMF is used, eds up in an mpi dead lock
                    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                    // this level-set is actually relevant for someone in 'species'
                    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                    CellQuadratureScheme SurfIntegration = schH.GetLevelSetquadScheme(iLevSet, IntegrationDom);
                    var rule = SurfIntegration.Compile(gd, this.CutCellQuadratureOrder);

                    BoSSS.Foundation.Quadrature.CellQuadrature.GetQuadrature(
                        new int[] { 1 }, gd,
                        rule,
                        _Evaluate : delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) {
                        EvalResult.SetAll(1.0);
                    },
                        _SaveIntegrationResults : delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) {
                        for (int i = 0; i < Length; i++)
                        {
                            int jCell = i + i0;



                            //if (cellMetrics[jCell, iSpcA, 0] != 0.0)
                            //    throw new NotSupportedException("More than one zero-level-set per cell is not supported yet.");
                            //if (cellMetrics[jCell, iSpcB, 0] != 0.0)
                            //    throw new NotSupportedException("More than one zero-level-set per cell is not supported yet.");

                            //cellMetrics[jCell, iSpcA, 0] = ResultsOfIntegration[i, 0];
                            //cellMetrics[jCell, iSpcB, 0] = ResultsOfIntegration[i, 0];


                            for (int iSpc = 0; iSpc < NoOfSpc; iSpc++)
                            {
                                if (SpeciesBitMask[iSpc][jCell])
                                {
                                    cellMetrics[jCell, iSpc, 0] += ResultsOfIntegration[i, 0];
                                    Debug.Assert(!(double.IsNaN(cellMetrics[jCell, iSpc, 0]) || double.IsInfinity(cellMetrics[jCell, iSpc, 0])));
                                }
                            }
                        }
                    }).Execute();
                    //}
                }
            }

            // MPI exchange & store
            // ====================

            if (species.Length > 0)
            {
                vec_cellMetrics.MPIExchange(gd);
            }

            for (int iSpc = 0; iSpc < species.Length; iSpc++)
            {
                var spc = species[iSpc];
                this.InterfaceArea.Add(spc, cellMetrics.ExtractSubArrayShallow(-1, iSpc, 0).CloneAs());
                this.CutCellVolumes.Add(spc, cellMetrics.ExtractSubArrayShallow(-1, iSpc, 1).CloneAs());
            }

            //Console.WriteLine("Erinn - debug code.");
            //for(int j = 0; j < J; j++) {
            //    double totVol = gd.Cells.GetCellVolume(j);

            //    double blaVol = 0;
            //    for(int iSpc = 0; iSpc < species.Length; iSpc++) {
            //        var spc = species[iSpc];
            //        var cellVolS = this.CutCellVolumes[spc][j];
            //        blaVol += cellVolS;
            //    }

            //    Debug.Assert(Math.Abs(totVol - blaVol) / totVol < 1.0e-8);

            //}
        }
Example #10
0
        /// <summary>
        /// Computes Cell-volumes and edge areas before agglomeration.
        /// </summary>
        void ComputeNonAgglomeratedMetrics()
        {
            using (new FuncTrace()) {
                MPICollectiveWatchDog.Watch();
                var         gd      = XDGSpaceMetrics.GridDat;
                int         JE      = gd.iLogicalCells.Count;
                int         J       = gd.iLogicalCells.NoOfLocalUpdatedCells;
                int         D       = gd.SpatialDimension;
                int         EE      = gd.Edges.Count;
                SpeciesId[] species = this.SpeciesList.ToArray();
                int         NoSpc   = species.Count();
                int[,] E2C = gd.iLogicalEdges.CellIndices;

                var schH = new XQuadSchemeHelper(XDGSpaceMetrics);


                // collect all per-cell-metrics in the same MultidimArry, for MPI-exchange (only 1 exchange instead of three, saving some overhead)
                // 1st index: cell
                // 2nd index: species
                // 3rd index: 0 for interface surface per cell, 1 for cut-cell-volume, 2 for cut-cell surface
                double[] vec_cellMetrics          = new double[JE * NoSpc * 3];
                MultidimensionalArray cellMetrics = MultidimensionalArray.CreateWrapper(vec_cellMetrics, JE, NoSpc, 3);

                this.CutEdgeAreas   = new Dictionary <SpeciesId, MultidimensionalArray>();
                this.CutCellVolumes = new Dictionary <SpeciesId, MultidimensionalArray>();
                this.InterfaceArea  = new Dictionary <SpeciesId, MultidimensionalArray>();
                this.CellSurface    = new Dictionary <SpeciesId, MultidimensionalArray>();

                //var schS = new List<CellQuadratureScheme>();
                //var rulz = new List<ICompositeQuadRule<QuadRule>>();


                // edges and volumes
                // =================
                for (int iSpc = 0; iSpc < species.Length; iSpc++)
                {
                    var cellVol = cellMetrics.ExtractSubArrayShallow(-1, iSpc, 1);
                    var spc     = species[iSpc];


                    // compute cut edge area
                    // ---------------------
                    MultidimensionalArray edgArea = MultidimensionalArray.Create(EE);
                    this.CutEdgeAreas.Add(spc, edgArea);

                    var edgeScheme = schH.GetEdgeQuadScheme(spc);
                    var edgeRule   = edgeScheme.Compile(gd, this.CutCellQuadratureOrder);

                    BoSSS.Foundation.Quadrature.EdgeQuadrature.GetQuadrature(
                        new int[] { 1 }, gd,
                        edgeRule,
                        _Evaluate : delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) //
                    {
                        EvalResult.SetAll(1.0);
                    },
                        _SaveIntegrationResults : delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) //
                    {
                        for (int i = 0; i < Length; i++)
                        {
                            int iEdge = i + i0;
                            Debug.Assert(edgArea[iEdge] == 0);
                            edgArea[iEdge] = ResultsOfIntegration[i, 0];
                            Debug.Assert(!(double.IsNaN(edgArea[iEdge]) || double.IsInfinity(edgArea[iEdge])));
                        }
                    }).Execute();

                    // sum up edges for surface
                    // ------------------------

                    var cellSurf = cellMetrics.ExtractSubArrayShallow(-1, iSpc, 2);

                    for (int e = 0; e < EE; e++)
                    {
                        double a      = edgArea[e];
                        int    jCell0 = E2C[e, 0];
                        int    jCell2 = E2C[e, 1];
                        cellSurf[jCell0] += a;
                        if (jCell2 >= 0)
                        {
                            cellSurf[jCell2] += a;
                        }
                    }

                    // compute cut cell volumes
                    // ------------------------

                    var volScheme = schH.GetVolumeQuadScheme(spc);
                    var volRule   = volScheme.Compile(gd, this.CutCellQuadratureOrder);

                    BoSSS.Foundation.Quadrature.CellQuadrature.GetQuadrature(
                        new int[] { 1 }, gd,
                        volRule,
                        _Evaluate : delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) //
                    {
                        EvalResult.SetAll(1.0);
                    },
                        _SaveIntegrationResults : delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) //
                    {
                        for (int i = 0; i < Length; i++)
                        {
                            int jCell = i + i0;
                            Debug.Assert(cellVol[jCell] == 0);
                            cellVol[jCell] = ResultsOfIntegration[i, 0];
                            Debug.Assert(!(double.IsNaN(cellVol[jCell]) || double.IsInfinity(cellVol[jCell])));
                        }
                    }).Execute();
                }


                // interface surface
                // =================

                // loop over level-sets
                if (species.Length > 0)
                {
                    // find domain of all species:
                    CellMask SpeciesCommonDom = XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(species[0]);
                    for (int iSpc = 1; iSpc < species.Length; iSpc++)
                    {
                        SpeciesCommonDom = SpeciesCommonDom.Union(XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(species[iSpc]));
                    }
                    BitArray[] SpeciesBitMask = species.Select(spc => XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(spc).GetBitMask()).ToArray();

                    int NoOfLs  = XDGSpaceMetrics.NoOfLevelSets;
                    int NoOfSpc = species.Length;
                    for (int iLevSet = 0; iLevSet < NoOfLs; iLevSet++)
                    {
                        var LsDom          = XDGSpaceMetrics.LevelSetRegions.GetCutCellMask4LevSet(iLevSet);
                        var IntegrationDom = LsDom.Intersect(SpeciesCommonDom);

                        //if (IntegrationDom.NoOfItemsLocally > 0) { -> Doesn't work if Bjoerns HMF is used, eds up in an mpi dead lock
                        // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                        // this level-set is actually relevant for someone in 'species'
                        // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                        CellQuadratureScheme SurfIntegration = schH.GetLevelSetquadScheme(iLevSet, IntegrationDom);
                        var rule = SurfIntegration.Compile(gd, this.CutCellQuadratureOrder);

                        BoSSS.Foundation.Quadrature.CellQuadrature.GetQuadrature(
                            new int[] { 1 }, gd,
                            rule,
                            _Evaluate : delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) {
                            EvalResult.SetAll(1.0);
                        },
                            _SaveIntegrationResults : delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) {
                            for (int i = 0; i < Length; i++)
                            {
                                int jCell = i + i0;



                                //if (cellMetrics[jCell, iSpcA, 0] != 0.0)
                                //    throw new NotSupportedException("More than one zero-level-set per cell is not supported yet.");
                                //if (cellMetrics[jCell, iSpcB, 0] != 0.0)
                                //    throw new NotSupportedException("More than one zero-level-set per cell is not supported yet.");

                                //cellMetrics[jCell, iSpcA, 0] = ResultsOfIntegration[i, 0];
                                //cellMetrics[jCell, iSpcB, 0] = ResultsOfIntegration[i, 0];


                                for (int iSpc = 0; iSpc < NoOfSpc; iSpc++)
                                {
                                    if (SpeciesBitMask[iSpc][jCell])
                                    {
                                        cellMetrics[jCell, iSpc, 0] += ResultsOfIntegration[i, 0];
                                        Debug.Assert(!(double.IsNaN(cellMetrics[jCell, iSpc, 0]) || double.IsInfinity(cellMetrics[jCell, iSpc, 0])));
                                    }
                                }
                            }
                        }).Execute();
                        //}
                    }
                }

                // MPI exchange & store
                // ====================

                if (species.Length > 0)
                {
#if DEBUG
                    int NoOfSpc       = species.Length;
                    var cellMetricsB4 = cellMetrics.ExtractSubArrayShallow(new[] { 0, 0, 0 }, new[] { J - 1, NoOfSpc - 1, 1 }).CloneAs();
#endif
                    vec_cellMetrics.MPIExchange(gd);
#if DEBUG
                    var cellMetricsComp = cellMetrics.ExtractSubArrayShallow(new[] { 0, 0, 0 }, new[] { J - 1, NoOfSpc - 1, 1 }).CloneAs();
                    cellMetricsComp.Acc(-1.0, cellMetricsB4);
                    Debug.Assert(cellMetricsComp.L2Norm() == 0.0);
#endif
                }
                for (int iSpc = 0; iSpc < species.Length; iSpc++)
                {
                    var spc = species[iSpc];
                    this.InterfaceArea.Add(spc, cellMetrics.ExtractSubArrayShallow(-1, iSpc, 0).CloneAs());
                    this.CutCellVolumes.Add(spc, cellMetrics.ExtractSubArrayShallow(-1, iSpc, 1).CloneAs());
                    this.CellSurface.Add(spc, cellMetrics.ExtractSubArrayShallow(-1, iSpc, 2).CloneAs());

                    this.CellSurface[spc].Acc(1.0, this.InterfaceArea[spc]);
                }
            }
        }