Пример #1
0
        /// <summary>
        /// assigns the cell index of the aggregated cell <em>j</em> to all (fine) grid cells that
        /// the aggregated cell <em>j</em> consists of.
        /// </summary>
        static public void ColorDGField(this AggregationGrid ag, DGField f)
        {
            if (!object.ReferenceEquals(f.GridDat, ag.AncestorGrid))
            {
                throw new ArgumentException("mismatch in base grid.");
            }


            f.Clear();
            int J = ag.iLogicalCells.NoOfLocalUpdatedCells;

            for (int j = 0; j < J; j++)  // loog over logical/aggregate cells
            {
                int[] Neighs      = ag.iLogicalCells.CellNeighbours[j];
                var   NeighColors = Neighs.Select(jNeigComp => (int)Math.Round(f.GetMeanValue(ag.iLogicalCells.AggregateCellToParts[jNeigComp][0])));
                int   iCol        = 1;
                for (iCol = 1; iCol < 2 * J; iCol++)
                {
                    if (!NeighColors.Contains(iCol))
                    {
                        break;
                    }
                }

                foreach (int jGeom in ag.iLogicalCells.AggregateCellToParts[j])
                {
                    f.SetMeanValue(jGeom, iCol);
                    //f.SetMeanValue(jGeom, j);
                }
            }
        }
Пример #2
0
        public ExtensionVelocityBDFMover(LevelSetTracker LSTrk,
                                         SinglePhaseField LevelSet,
                                         VectorField <SinglePhaseField> LevelSetGradient,
                                         VectorField <DGField> Velocity,
                                         EllipticExtVelAlgoControl Control,
                                         IncompressibleBoundaryCondMap bcMap,
                                         int BDForder,
                                         VectorField <SinglePhaseField> VectorExtension,
                                         double[] Density = null,
                                         bool AssumeDivergenceFreeVelocity = false, SubGrid subGrid = null)
        {
            this.GridDat          = LSTrk.GridDat;
            D                     = GridDat.SpatialDimension;
            this.LevelSetGradient = LevelSetGradient;
            this.LSTrk            = LSTrk;
            this.LevelSet         = LevelSet;

            this.Velocity = Velocity;
            this.OldRHS   = LevelSet.CloneAs();
            this.AdvectionSpatialOperator = CreateAdvectionSpatialOperator(bcMap);

            this.subGrid   = subGrid;
            this.nearfield = subGrid != null;

            Basis NonXVelocityBasis;

            if (Velocity == null)
            {
                throw new ArgumentException("Velocity Field not initialized!");
            }

            // Initialize Extension Velocity Algorithm
            double        PenaltyBase = Control.PenaltyMultiplierInterface * ((double)((LevelSet.Basis.Degree + 1) * (LevelSet.Basis.Degree + D))) / ((double)D);
            ILevelSetForm InterfaceFlux;



            //VectorExtension = new VectorField<SinglePhaseField>(D, Velocity[0].Basis, "ExtVel", SinglePhaseField.Factory);
            if (Velocity[0].GetType() == typeof(SinglePhaseField))
            {
                NonXVelocityBasis = ((SinglePhaseField)Velocity[0]).Basis;
                InterfaceFlux     = new SingleComponentInterfaceForm(PenaltyBase, LSTrk);
            }
            else if (Velocity[0].GetType() == typeof(XDGField))
            {
                NonXVelocityBasis = ((XDGField)Velocity[0]).Basis.NonX_Basis;
                InterfaceFlux     = new DensityWeightedExtVel(PenaltyBase, LSTrk, Density);
            }
            else
            {
                throw new ArgumentException("VelocityField must be either a SinglePhaseField or a XDGField!");
            };
            //VectorExtension = new VectorField<SinglePhaseField>(D, NonXVelocityBasis, "ExtVel", SinglePhaseField.Factory);
            this.VectorExtension = VectorExtension;



            VelocityExtender = new Extender[D];
            for (int d = 0; d < D; d++)
            {
                VelocityExtender[d] = new Extender(VectorExtension[d], LSTrk, InterfaceFlux, new List <DGField> {
                    Velocity[d]
                }, LevelSetGradient, Control);
                VelocityExtender[d].ConstructExtension(new List <DGField> {
                    Velocity[d]
                }, Control.subGridRestriction);
            }
#if DEBUG
            VectorExtension.CheckForNanOrInf();
#endif

            // Initialize Advection Algorithm
            divU = new SinglePhaseField(NonXVelocityBasis);
            divU.Identification = "Divergence";
            divU.Clear();
            divU.Divergence(1.0, VectorExtension);
            MeanVelocity = new VectorField <SinglePhaseField>(D.ForLoop(d => new SinglePhaseField(new Basis(GridDat, 0), VariableNames.Velocity0MeanVector(D)[d])));
            MeanVelocity.Clear();
            MeanVelocity.AccLaidBack(1.0, VectorExtension);
            myBDFTimestepper = new BDFTimestepper(AdvectionSpatialOperator, new List <DGField>()
            {
                LevelSet
            }, ArrayTools.Cat(VectorExtension, this.MeanVelocity, this.divU), BDForder, Control.solverFactory, false, subGrid);
        }
Пример #3
0
        /// <summary>
        /// assigns the cell index of the aggregated cell <em>j</em> to all (fine) grid cells that
        /// the aggregated cell <em>j</em> consists of.
        /// </summary>
        static public void ColorDGField(this AggregationGridData ag, DGField f)
        {
            IGridData Anc = f.GridDat;

            if (!IsAnc(Anc, ag))
            {
                throw new ArgumentException("Field 'f' must be defined on an ancestor grid of 'ag'.");
            }


            f.Clear();
            int Jag  = ag.iLogicalCells.NoOfLocalUpdatedCells;
            int Janc = Anc.iLogicalCells.NoOfLocalUpdatedCells;

            Debug.Assert(Anc.iGeomCells.Count == ag.iGeomCells.Count);

            int[] jG2jL = Anc.iGeomCells.GeomCell2LogicalCell;

            int[]    Colors = new int[Jag];
            BitArray Marked = new BitArray(Janc);

            for (int j = 0; j < Jag; j++)   // loop over logical/aggregate cells

            // determine colors of neighbor cells
            {
                int[] Neighs      = ag.iLogicalCells.CellNeighbours[j];
                var   NeighColors = Neighs.Select(jN => Colors[jN]);

                // select color for cell 'j'
                int iCol = 1;
                for (iCol = 1; iCol < 2 * Jag; iCol++)
                {
                    if (!NeighColors.Contains(iCol))
                    {
                        break;
                    }
                }
                Colors[j] = iCol;

                // color all logical cells in ancestor grid
                // idea: convert to geometrical and back to logical
                //    in this way we can e.g. skip multiple grid levels
                foreach (int jGeom in ag.iLogicalCells.AggregateCellToParts[j])
                {
                    int jLogAnc;
                    if (jG2jL != null)
                    {
                        jLogAnc = jG2jL[jGeom];
                    }
                    else
                    {
                        jLogAnc = jGeom;
                    }
                    if (!Marked[jLogAnc])
                    {
                        f.SetMeanValue(jLogAnc, iCol);
                        Marked[jLogAnc] = true;
                    }
                    else
                    {
                        // nop
                    }
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Loads the DG coordinates after grid adaptation.
        /// </summary>
        /// <param name="f"></param>
        /// <param name="Reference">
        /// Unique string reference under which data has been stored before grid-redistribution.
        /// </param>
        public override void RestoreDGField(DGField f, string Reference)
        {
            using (new FuncTrace()) {
                //if(f.Identification == "TestData") {
                //    Console.WriteLine("using oasch");
                //    Oasch = true;
                //} else {
                //    Oasch = false;
                //}



                int      newJ    = this.m_newJ;
                GridData NewGrid = (GridData)m_NewGrid;
                int      pDeg    = f.Basis.Degree; //  Refined_TestData.Basis.Degree;

                if (!object.ReferenceEquals(NewGrid, f.Basis.GridDat))
                {
                    throw new ArgumentException("DG field must be assigned to new grid.");
                }

                f.Clear();

                int[][]      TargMappingIdx = m_Old2NewCorr.GetTargetMappingIndex(NewGrid.CellPartitioning);
                double[][][] ReDistDGCoords = m_newDGFieldData_GridAdapta[Reference];
                Debug.Assert(ReDistDGCoords.Length == newJ);

                if (f is ConventionalDGField)
                {
                    // +++++++++++++++
                    // normal DG field
                    // +++++++++++++++

                    int Np = f.Basis.Length;

                    double[] temp = new double[Np];
                    double[] acc  = new double[Np];

                    for (int j = 0; j < newJ; j++)
                    {
                        if (TargMappingIdx[j] == null)
                        {
                            // unchanged cell
                            Debug.Assert(ReDistDGCoords[j].Length == 1);
                            double[] Coord = ReDistDGCoords[j][0];
                            Debug.Assert(Coord.Length == Np);

                            BckTrafo(Coord, Np, 0, NewGrid, j, pDeg, 1.0);

                            f.Coordinates.SetRow(j, Coord);
                        }
                        else
                        {
                            int L = ReDistDGCoords[j].Length;
                            for (int l = 0; l < L; l++)
                            {
                                DoCellj(j, f, NewGrid, pDeg, TargMappingIdx[j], ReDistDGCoords[j], l, m_Old2NewCorr, 0, 0, Np, temp, acc);
                            }
                        }
                    }
                }
                else if (f is XDGField)
                {
                    // +++++++++++++++++++++++
                    // treatment of XDG fields
                    // +++++++++++++++++++++++

                    // (as always, more difficult)

                    XDGField        xf    = f as XDGField;
                    LevelSetTracker lsTrk = xf.Basis.Tracker;
                    int             Np    = xf.Basis.NonX_Basis.Length;
                    double[]        temp  = new double[Np];
                    double[]        acc   = new double[Np];

                    if (!object.ReferenceEquals(m_NewTracker, lsTrk))
                    {
                        throw new ArgumentException("LevelSetTracker seems duplicate, or something.");
                    }

                    for (int j = 0; j < newJ; j++)
                    {
                        int NoOfSpc = lsTrk.Regions.GetNoOfSpecies(j);
                        f.Coordinates.ClearRow(j);

                        if (TargMappingIdx[j] == null)
                        {
                            // + + + + + + + + +
                            // unchanged cell
                            // + + + + + + + + +

                            Debug.Assert(ReDistDGCoords[j].Length == 1);
                            double[] ReDistDGCoords_jl = ReDistDGCoords[j][0];
                            //Debug.Assert(ReDistDGCoords_jl.Length == NoOfSpc*Np + NoOfSpc + 1);
                            //Debug.Assert(ReDistDGCoords_jl[0] == NoOfSpc);


                            int NoOfSpcR = (int)(ReDistDGCoords_jl[0]); // Number of species received!

                            int c = 1;
                            for (int iSpcR = 0; iSpcR < NoOfSpcR; iSpcR++)  // loop over received species...
                                                                            //#if DEBUG
                                                                            //                                SpeciesId rcvSpc;
                                                                            //                                rcvSpc.cntnt = (int) ReDistDGCoords_jl[c];
                                                                            //                                Debug.Assert(rcvSpc == lsTrk.Regions.GetSpeciesIdFromIndex(j, iSpc));
                                                                            //#endif
                            {
                                SpeciesId rcvSpc;
                                rcvSpc.cntnt = (int)ReDistDGCoords_jl[c];
                                c++;
                                int iSpcTarg = lsTrk.Regions.GetSpeciesIndex(rcvSpc, j);


                                if (iSpcTarg >= 0)
                                {
                                    for (int n = 0; n < Np; n++)
                                    {
                                        f.Coordinates[j, n + Np * iSpcTarg] = ReDistDGCoords_jl[c];
                                        c++;
                                    }
                                }
                                else
                                {
                                    //double testNorm = 0;
                                    for (int n = 0; n < Np; n++)
                                    {
                                        //testNorm += ReDistDGCoords_jl[c].Pow2();
                                        c++;
                                    }
                                }
                            }
                            Debug.Assert(c == ReDistDGCoords_jl.Length);
                        }
                        else
                        {
                            // + + + + + + + + + + + + +
                            // coarsening or refinement
                            // + + + + + + + + + + + + +

                            int L = ReDistDGCoords[j].Length;
                            for (int l = 0; l < L; l++)
                            {
                                double[] ReDistDGCoords_jl = ReDistDGCoords[j][l];
                                int      NoSpcOrg          = (int)ReDistDGCoords_jl[0]; // no of species in original cells

                                int c = 1;
                                for (int iSpcRecv = 0; iSpcRecv < NoSpcOrg; iSpcRecv++)  // loop over species in original cell

                                {
                                    SpeciesId rcvSpc;
                                    rcvSpc.cntnt = (int)ReDistDGCoords_jl[c];
                                    c++;

                                    int iSpc = lsTrk.Regions.GetSpeciesIndex(rcvSpc, j); // species index in new cell
                                    //Debug.Assert(iSpcRecv == iSpc || L > 1);

                                    int N0rcv = c;
                                    c += Np;
                                    if (iSpc >= 0)
                                    {
                                        DoCellj(j, xf, NewGrid, pDeg, TargMappingIdx[j], ReDistDGCoords[j], l, m_Old2NewCorr, N0rcv, Np * iSpc, Np, temp, acc);
                                    }
                                }
                                Debug.Assert(c == ReDistDGCoords_jl.Length);
                            }
                        }
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
        }
Пример #5
0
        public void LimitFieldValues(IEnumerable <DGField> ConservativeVariables, IEnumerable <DGField> DerivedFields)
        {
            var GridData = ConservativeVariables.First().GridDat;

            // Make sure primitive fields are up-to-date
            for (int d = 0; d < CompressibleEnvironment.NumberOfDimensions; d++)
            {
                CNSVariables.Velocity[d].UpdateFunction(
                    DerivedFields.Single(f => f.Identification == CNSVariables.Velocity[d].Name),
                    CellMask.GetFullMask(GridData),
                    program);
            }
            CNSVariables.Pressure.UpdateFunction(
                DerivedFields.Single(f => f.Identification == CNSVariables.Pressure.Name),
                CellMask.GetFullMask(GridData),
                program);

            // Limit and store primitive fields
            string[]  primitiveFieldNames = { CompressibleVariables.Density, CNSVariables.Velocity.xComponent, CNSVariables.Velocity.yComponent, CNSVariables.Pressure };
            DGField[] primitiveFields     = new DGField[primitiveFieldNames.Length];
            CellMask  shockedCells        = Sensor.GetShockedCellMask(GridData, sensorLimit, cellSize, dgDegree);
            int       k = 0;

            foreach (string name in primitiveFieldNames)
            {
                DGField field = ConservativeVariables.
                                Concat(DerivedFields).
                                Where(f => f.Identification.Equals(name)).
                                Single();

                foreach (Chunk chunk in shockedCells)
                {
                    foreach (int cell in chunk.Elements)
                    {
                        for (int j = 1; j < field.Coordinates.NoOfCols; j++)
                        {
                            field.Coordinates[cell, j] = 0.0;
                        }
                    }
                }

                primitiveFields[k] = field;
                k++;
            }

            // Update conservative variables by using limited primitive variables only in shocked cells
            int D = CompressibleEnvironment.NumberOfDimensions;

            for (int d = 0; d < D; d++)
            {
                DGField mom_d = ConservativeVariables.Single(f => f.Identification == CompressibleVariables.Momentum[d].Name);
                mom_d.Clear(shockedCells);
                mom_d.ProjectFunction(
                    1.0,
                    (X, U, j) => U[0] * U[1 + d],
                    new CellQuadratureScheme(true, shockedCells),
                    primitiveFields);
            }

            // Update total energy
            DGField Energy = ConservativeVariables.Single(f => f.Identification == CompressibleVariables.Energy.Name);

            Energy.Clear(shockedCells);
            Energy.ProjectFunction(
                1.0,
                delegate(double[] X, double[] U, int jCell) {
                double K = 0.0;
                for (int d = 0; d < D; d++)
                {
                    K += U[d + 1] * U[d + 1];
                }
                return(U[D + 1] / (program.Control.EquationOfState.HeatCapacityRatio - 1.0) + 0.5 * U[0] * K);
            },
                new CellQuadratureScheme(true, shockedCells),
                primitiveFields);
        }