Beispiel #1
0
            /// <summary>
            /// gets a mask of width <paramref name="FieldWidth"/>, around any level set
            /// </summary>
            /// <remarks>
            /// In contrast to <see cref="SubGrid"/>'s, <see cref="CellMask"/>'s are not MPI-collective, and should therefore be preferred.
            /// </remarks>
            public CellMask GetNearFieldMask(int FieldWidth)
            {
                if (FieldWidth > m_owner.NearRegionWidth)
                {
                    throw new ArgumentException("Near-" + FieldWidth + " cannot be acquired, because this tracker is set to detect at most Near-" + m_owner.NearRegionWidth + ".", "FieldWidth");
                }

                if (this.m_owner.LevelSets.Count == 1)
                {
                    // if there is only one Level Set, no need to separate between
                    // cells-cut-by-any-level-set and cells-cut-by-a-specific-level-set
                    return(GetNearMask4LevSet(0, FieldWidth));
                }

                if (m_NearMask == null)
                {
                    m_NearMask = new CellMask[m_owner.m_NearRegionWidth + 1];
                }

                if (m_NearMask[FieldWidth] == null)
                {
                    int      J  = m_owner.m_gDat.Cells.NoOfLocalUpdatedCells;
                    BitArray ba = new BitArray(J, false);
                    //int NoL = m_LevelSets.Length;

                    for (int j = 0; j < J; j++)
                    {
                        ushort code = m_LevSetRegions[j];

                        for (int levSetIdx = 0; levSetIdx < m_owner.NoOfLevelSets; levSetIdx++)
                        {
                            int dist = LevelSetTracker.DecodeLevelSetDist(code, levSetIdx);
                            if (Math.Abs(dist) <= FieldWidth)
                            {
                                ba[j] = true;
                                continue;
                            }
                        }
                    }

                    m_NearMask[FieldWidth] = new CellMask(m_owner.m_gDat, ba);
                }

                return(m_NearMask[FieldWidth]);
            }
Beispiel #2
0
            /// <summary>
            /// gets a cell-mask of width <paramref name="FieldWidth"/>, around level set No. <paramref name="levSetIdx"/>;
            /// </summary>
            /// <remarks>
            /// In contrast to <see cref="SubGrid"/>'s, <see cref="CellMask"/>'s are not MPI-collective, and should therefore be preferred.
            /// </remarks>
            public CellMask GetNearMask4LevSet(int levSetIdx, int FieldWidth)
            {
                if (FieldWidth > m_owner.m_NearRegionWidth)
                {
                    throw new ArgumentException("Near-" + FieldWidth + " cannot be acquired, because this tracker is set to detect at most Near-" + m_owner.m_NearRegionWidth + ".", "FieldWidth");
                }
                if (levSetIdx < 0 || levSetIdx >= this.m_owner.NoOfLevelSets)
                {
                    throw new IndexOutOfRangeException();
                }


                if (m_NearMask4LevelSet == null || m_NearMask4LevelSet.GetLength(1) != (m_owner.m_NearRegionWidth + 1))
                {
                    m_NearMask4LevelSet = new CellMask[m_owner.NoOfLevelSets, m_owner.m_NearRegionWidth + 1];
                }


                if (m_NearMask4LevelSet[levSetIdx, FieldWidth] == null)
                {
                    // create subgrid

                    int      J  = m_owner.m_gDat.Cells.NoOfLocalUpdatedCells;
                    BitArray ba = new BitArray(J, false);
                    //int NoL = m_LevelSets.Length;

                    for (int j = 0; j < J; j++)
                    {
                        ushort code = m_LevSetRegions[j];

                        int dist = LevelSetTracker.DecodeLevelSetDist(code, levSetIdx);
                        if (Math.Abs(dist) <= FieldWidth)
                        {
                            ba[j] = true;
                            continue;
                        }
                    }

                    m_NearMask4LevelSet[levSetIdx, FieldWidth] = new CellMask(m_owner.GridDat, ba);
                }

                return(m_NearMask4LevelSet[levSetIdx, FieldWidth]);
            }
        /// <summary>
        /// For some species <paramref name="sp"/>,
        /// this function computes on which side/wing
        /// of level-set no. <paramref name="levSetIdx"/>)
        /// the species is located.
        /// </summary>
        /// <remarks>
        /// Nur ein Provisorium, das ganze Konzept ist noch etwas unausgereift. (Habe einen Nachmittag lang darueber nachgedacht, keinen bessere Idee gehabt,
        /// und darum...).
        /// </remarks>
        public JumpTypes IdentifyWing(int levSetIdx, SpeciesId sp)
        {
            int NoOfLevSets = this.XDGSpaceMetrics.NoOfLevelSets;

            if (levSetIdx < 0 || levSetIdx > NoOfLevSets)
            {
                throw new ArgumentOutOfRangeException();
            }

            if (NoOfLevSets == 1)
            {
                string[] speciesTable = (string[])(this.XDGSpaceMetrics.LevelSetRegions.SpeciesTable);
                Debug.Assert(speciesTable.Length == 2);

                string spN = this.XDGSpaceMetrics.LevelSetRegions.GetSpeciesName(sp);

                if (spN == speciesTable[0])
                {
                    return(JumpTypes.OneMinusHeaviside);
                }
                else if (spN == speciesTable[1])
                {
                    return(JumpTypes.Heaviside);
                }
                else
                {
                    throw new Exception("should not happen.");
                }
            }
            else if (NoOfLevSets == 2)
            {
                string[,] speciesTable = (string[, ])(this.XDGSpaceMetrics.LevelSetRegions.SpeciesTable);
                Debug.Assert(speciesTable.GetLength(0) == 2);
                Debug.Assert(speciesTable.GetLength(1) == 2);

                string spN = this.XDGSpaceMetrics.LevelSetRegions.GetSpeciesName(sp);

                int[] LevSetSigns;
                bool  foundCell;
                {
                    // we need the signs of other level sets to identify the wing
                    // so we search for some cut cell of Level-Set #levSetIdx
                    // which actually contains species 'sp'

                    int   J = this.XDGSpaceMetrics.GridDat.iLogicalCells.NoOfLocalUpdatedCells;
                    int[] LenToNextchange = this.XDGSpaceMetrics.LevelSetRegions.m_LenToNextChange;
                    LevSetSigns = new int[NoOfLevSets];
                    foundCell   = false;

                    for (int j = 0; j < J; j += LenToNextchange[j])
                    {
                        ushort code = this.XDGSpaceMetrics.LevelSetRegions.m_LevSetRegions[j];

                        int dist = LevelSetTracker.DecodeLevelSetDist(code, levSetIdx);
                        if (dist != 0)
                        {
                            continue;
                        }
                        // cut by Level-Set

                        bool present = this.XDGSpaceMetrics.LevelSetRegions.IsSpeciesPresentInCell(sp, j);
                        if (!present)
                        {
                            continue;
                        }
                        // contains species 'sp'

                        var Signs = this.XDGSpaceMetrics.LevelSetRegions.GetCellSignCode(j);
                        for (int iLs = 0; iLs < NoOfLevSets; iLs++)
                        {
                            if (iLs != levSetIdx)
                            {
                                var s = Signs.GetSign(iLs);

                                if (s == LevelsetSign.Both)
                                {
                                    continue;
                                }
                                else if (s == LevelsetSign.Negative)
                                {
                                    foundCell        = true;
                                    LevSetSigns[iLs] = 0;
                                }
                                else if (s == LevelsetSign.Positive)
                                {
                                    foundCell        = true;
                                    LevSetSigns[iLs] = 1;
                                }
                                else
                                {
                                    throw new NotImplementedException();
                                }
                            }
                        }
                    }
                }
                int       cnt    = 0;
                JumpTypes jmpRet = JumpTypes.Implicit;

                /*
                 * int[] _i = new int[2];
                 * for (_i[0] = 0; _i[0] < 2; _i[0]++) { // loop over signs of level-set 0 ...
                 *  for (_i[1] = 0; _i[1] < 2; _i[1]++) { // loop over signs of level-set 1 ...
                 *      if (speciesTable[_i[0], _i[1]] == spN) {
                 *          cnt++;
                 *
                 *          if (_i[levSetIdx] == 0)
                 *              jmpRet = JumpTypes.OneMinusHeaviside;
                 *          else if (_i[levSetIdx] == 1)
                 *              jmpRet = JumpTypes.Heaviside;
                 *          else
                 *              throw new ApplicationException();
                 *      }
                 *  }
                 * }
                 */

                if (foundCell == false)
                {
                    return(JumpTypes.Heaviside); // no cell on this proc, so anyway pretty irrelevant
                }
                for (int i = 0; i < 2; i++)
                {
                    LevSetSigns[levSetIdx] = i;

                    if (speciesTable[LevSetSigns[0], LevSetSigns[1]] == spN)
                    {
                        cnt++;
                        if (LevSetSigns[levSetIdx] == 0)
                        {
                            jmpRet = JumpTypes.OneMinusHeaviside;
                        }
                        else if (LevSetSigns[levSetIdx] == 1)
                        {
                            jmpRet = JumpTypes.Heaviside;
                        }
                        else
                        {
                            throw new ApplicationException();
                        }
                    }
                }

                if (cnt != 1)
                {
                    throw new NotImplementedException("unable to identify.");
                }

                return(jmpRet);
            }
            else
            {
                throw new NotImplementedException();
            }
        }
        /// <summary>
        /// evaluation of field in cut- or near - cells;
        /// </summary>
        private void EvaluateMultiphase(int jCell, NodeSet NS, ReducedRegionCode ReducedRegionCode, int NoOfSpecies, MultidimensionalArray result, int ResultCellindexOffset, double ResultPreScale,
                                        EvaluateInternalSignature EvalFunc,
                                        ref MultidimensionalArray[] Buffer, Func <int, int[]> BufferDim,
                                        Picker p)
        {
            LevelSetTracker trk         = this.Basis.Tracker;
            int             NoOfLevSets = trk.LevelSets.Count;
            int             M           = NS.NoOfNodes;

            {
                //var resultAcc = result.ExtractSubArrayShallow(new int[] { ResultCellindexOffset + j, 0 }, new int[] { ResultCellindexOffset + j, M - 1 });

                ushort RegionCode = trk.Regions.m_LevSetRegions[jCell];

                bool OnlyOneSpecies = true;
                for (int i = 0; i < NoOfLevSets; i++)
                {
                    int dst = LevelSetTracker.DecodeLevelSetDist(RegionCode, i);
                    if (dst == 0)
                    {
                        // cut-cell with respect or levelset #i
                        // +++++++++++++++++++++++++++++++++++++

                        OnlyOneSpecies = false;
                        _levSetVals[i] = trk.DataHistories[i].Current.GetLevSetValues(NS, jCell, 1);
                    }
                    else
                    {
                        // near-cell with respect or levelset #i
                        // +++++++++++++++++++++++++++++++++++++

                        // find the species index...
                        _levSetVals[i] = null;
                        _levSetSign[i] = dst;
                    }
                    //_levSetSign2[i] = dst;
                }


                if (OnlyOneSpecies)
                {
                    // all level sets are 'NEAR'
                    // +++++++++++++++++++++++++

                    LevelSetSignCode levset_bytecode = LevelSetSignCode.ComputeLevelSetBytecode(_levSetSign);
                    int SpecInd = trk.GetSpeciesIndex(ReducedRegionCode, levset_bytecode);

                    // evaluate species ...
                    Evaluate_ithSpecies(jCell, NS, result, ResultCellindexOffset, ResultPreScale, SpecInd, EvalFunc);
                }
                else
                {
                    // at least one cell is 'CUT'
                    // ++++++++++++++++++++++++++

                    // allocate buffers/evaluate all species ...
                    if (Buffer.Length < NoOfSpecies)
                    {
                        int oldL = Buffer.Length;
                        Array.Resize(ref Buffer, NoOfSpecies);
                        for (int i = oldL; i < NoOfSpecies; i++)
                        {
                            Buffer[i] = MultidimensionalArray.Create(BufferDim(M));
                        }
                    }
                    for (int i = 0; i < NoOfSpecies; i++)
                    {
                        if (Buffer[i].Dimension > 1 && Buffer[i].GetLength(1) != M)
                        {
                            Buffer[i].Allocate(BufferDim(M));
                        }

                        this.Evaluate_ithSpecies(jCell, NS, Buffer[i], 0, 0.0, i, EvalFunc);
                    }

                    // ... and pick the right species for the Node
                    for (int m = 0; m < M; m++)   // loop over nodes


                    {
                        for (int i = 0; i < NoOfLevSets; i++)
                        {
                            if (_levSetVals[i] != null)
                            {
                                _levSetSign[i] = _levSetVals[i][0, m];
                            }
                        }

                        LevelSetSignCode levset_bytecode = LevelSetSignCode.ComputeLevelSetBytecode(_levSetSign);
                        int SpecInd = trk.GetSpeciesIndex(ReducedRegionCode, levset_bytecode);

                        p(result, ResultCellindexOffset, m, SpecInd, Buffer);
                    }
                }
            }
        }
Beispiel #5
0
            protected override void ComputeValues(NodeSet NS, int j0, int Len, MultidimensionalArray output)
            {
                Debug.Assert(CheckAll(j0, Len), "basis length must be equal for all cells from j0 to j0+Len");

                int l0  = m_Owner.GetLength(j0);
                var trk = m_Owner.Tracker;

                // evaluation of un-cut polynomials
                // ================================
                var BasisValues = NonXEval(NS, j0, Len);


                // evaluation of XDG
                // =================

                if (l0 == m_Owner.NonX_Basis.Length)
                {
                    // uncut region -> evaluation is equal to uncut basis
                    // ++++++++++++++++++++++++++++++++++++++++++++++++++

                    output.Set(BasisValues);
                }
                else
                {
                    // modulated basis polynomials
                    // +++++++++++++++++++++++++++

                    int NoOfLevSets = trk.LevelSets.Count;
                    int M           = output.GetLength(1); // number of nodes
                    output.Clear();

                    ReducedRegionCode rrc;
                    int NoOfSpecies = trk.Regions.GetNoOfSpecies(j0, out rrc);
                    int Nsep        = m_Owner.DOFperSpeciesPerCell;



                    for (int j = 0; j < Len; j++)   // loop over cells


                    {
                        int jCell = j + j0;

                        ushort RegionCode = trk.Regions.m_LevSetRegions[jCell];


                        int dist = 0;
                        for (int i = 0; i < NoOfLevSets; i++)
                        {
                            dist = LevelSetTracker.DecodeLevelSetDist(RegionCode, i);
                            if (dist == 0)
                            {
                                m_levSetVals[i] = trk.DataHistories[i].Current.GetLevSetValues(NS, jCell, 1);
                            }
                            else
                            {
                                //_levSetVals[i] = m_CCBasis.Tracker.GetLevSetValues(i, NodeSet, jCell, 1);
                                m_levSetVals[i] = null;
                                m_levSetSign[i] = dist;
                            }
                        }


                        LevelSetSignCode levset_bytecode;
                        int SpecInd;
                        if (dist != 0)
                        {
                            // near - field:
                            // Basis contains zero-entries
                            // ++++++++++++++++++++++++++++

                            levset_bytecode = LevelSetSignCode.ComputeLevelSetBytecode(m_levSetSign);
                            SpecInd         = trk.GetSpeciesIndex(rrc, levset_bytecode);
                        }
                        else
                        {
                            levset_bytecode = default(LevelSetSignCode);
                            SpecInd         = 0;
                        }


                        for (int m = 0; m < M; m++)   // loop over nodes

                        {
                            if (dist == 0)
                            {
                                // cut cells
                                // Modulation necessary
                                // +++++++++++++++++++++

                                for (int i = 0; i < NoOfLevSets; i++)
                                {
                                    if (m_levSetVals[i] != null)
                                    {
                                        m_levSetSign[i] = m_levSetVals[i][0, m];
                                    }
                                }

                                // re-compute species index
                                levset_bytecode = LevelSetSignCode.ComputeLevelSetBytecode(m_levSetSign);
                                SpecInd         = trk.GetSpeciesIndex(rrc, levset_bytecode);
                            }


                            // separate coordinates
                            {
                                int n0 = Nsep * SpecInd;
                                for (int n = 0; n < Nsep; n++)   // loop over basis polynomials
                                //output[j, m, n0 + n] = BasisValues[m, n];
                                {
                                    Operation(output, BasisValues, j, m, n0 + n, n);
                                }
                            }
                        }
                    }
                }
            }