예제 #1
0
            static bool IsCellCut(int iEdge, int[,] E2C, LevelSetTracker.LevelSetRegions regions, SpeciesId mySp)
            {
                int jCell0 = E2C[iEdge, 0];

                int iSpc_cell0 = regions.GetSpeciesIndex(mySp, jCell0);

                if (iSpc_cell0 != 0)
                {
                    return(true);
                }

                int jCell1 = E2C[iEdge, 1];

                if (jCell1 >= 0)
                {
                    int iSpc_cell1 = regions.GetSpeciesIndex(mySp, jCell1);

                    if (iSpc_cell1 != 0)
                    {
                        return(true);
                    }
                }

                return(false);
            }
예제 #2
0
            public MiniMapping(UnsetteledCoordinateMapping Map, SpeciesId spId, LevelSetTracker.LevelSetRegions r)
            {
                m_Map = Map;
                m_spId = spId;
                m_LsRegion = r;

                Basis[] BS = Map.BasisS.ToArray();
                NS = new int[BS.Length];
                VarIsXdg = new bool[BS.Length];
                NoOfVars = BS.Length;

                for (int iVar = 0; iVar < BS.Length; iVar++) {
                    XDGBasis xBasis = BS[iVar] as XDGBasis;
                    if (xBasis != null) {
                        NS[iVar] = xBasis.NonX_Basis.Length;
                        //m_LsTrk = xBasis.Tracker;
                        VarIsXdg[iVar] = true;
                    } else {
                        NS[iVar] = BS[iVar].Length;
                        VarIsXdg[iVar] = false;
                    }

                    MaxDeg = Math.Max(MaxDeg, BS[iVar].Degree);
                }
            }
예제 #3
0
        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="lsTrk">level set tracker</param>
        /// <param name="spcId">species which should be framed</param>
        /// <param name="__FullMap"></param>
        /// <param name="SupportExternal">
        /// true: support also indices related to external/ghost cells
        /// </param>
        public FrameBase(LevelSetTracker.LevelSetRegions regions, SpeciesId spcId, UnsetteledCoordinateMapping __FullMap, bool SupportExternal)
        {
            m_Regions         = regions;
            m_spcId           = spcId;
            FrameMap          = CreateMap(__FullMap);
            FullMap           = __FullMap;
            m_supportExternal = SupportExternal;

            Setup_Frame2Full(); // Frame2Full is almost used every time, so we set it up immediately
            //                     (in contrast, Full2Frame is set up on demand)
        }
예제 #4
0
        /// <summary>
        /// returns global unique indices which correlate to a certain sub-set of ...
        /// <list type="bullet">
        /// <item>the mappings's basis (<paramref name="mapping"/>, <see cref="UnsetteledCoordinateMapping.BasisS"/>).</item>
        /// <item>species (<paramref name="_SpcIds"/>).</item>
        /// <item>cells (<paramref name="cm"/>).</item>
        /// </list>
        /// </summary>
        /// <param name="mapping">
        /// the mapping
        /// </param>
        /// <param name="Fields">
        /// determines which fields should be in the sub-vector-indices-list
        /// </param>
        /// <param name="_SpcIds">
        /// determines which species should be in the sub-vector-indices-list; null indicates all species.
        /// </param>
        /// <param name="cm">
        /// determines which cells should be in the sub-vector-indices-list; null indicates all cells.
        /// </param>
        /// <param name="regions">
        /// Determines which XDG-coordinate belongs to which species.
        /// </param>
        /// <param name="presenceTest">
        /// if true, cells where some species has zero measure are excluded from the sub-vector-indices-list.
        /// </param>
        /// <param name="drk">
        /// a cell-agglomeration object: if null, ignored; if provided,
        /// cells which are eliminated by the agglomeration are excluded from the sub-vector-indices-list
        /// </param>
        /// <returns>a list of global (over all MPI processes) unique indices.</returns>
        static public int[] GetSubvectorIndices(this UnsetteledCoordinateMapping mapping, LevelSetTracker.LevelSetRegions regions, int[] Fields,
                                                ICollection <SpeciesId> _SpcIds = null, CellMask cm = null, bool presenceTest = true, MultiphaseCellAgglomerator drk = null)
        {
            #region Check Arguments
            // =========
            SpeciesId[] SpcIds = null;
            if (_SpcIds == null)
            {
                // take all species, if arg is null
                SpcIds = regions.SpeciesIdS.ToArray();
            }
            else
            {
                SpcIds = _SpcIds.ToArray();
            }

            if (SpcIds.Length <= 0)
            {
                // return will be empty for no species
                return(new int[0]);
            }
            #endregion

            #region collect cells which are excluded by agglomeration
            // =================================================

            int[][] ExcludeLists;
            if (drk != null)
            {
                ExcludeLists = new int[regions.SpeciesIdS.Count][]; //  new Dictionary<SpeciesId, int[]>();
                foreach (var id in SpcIds)
                {
                    int[] ExcludeList = drk.GetAgglomerator(id).AggInfo.AgglomerationPairs.Select(pair => pair.jCellSource).ToArray();
                    Array.Sort(ExcludeList);
                    ExcludeLists[id.cntnt - LevelSetTracker.___SpeciesIDOffest] = ExcludeList;
                }
            }
            else
            {
                ExcludeLists = null;
            }
            #endregion

            #region determine over which cells we want to loop
            // ==========================================
            CellMask loopCells;
            if ((new HashSet <SpeciesId>(regions.SpeciesIdS)).SetEquals(new HashSet <SpeciesId>(SpcIds)))
            {
                if (cm == null)
                {
                    loopCells = CellMask.GetFullMask(regions.GridDat);
                }
                else
                {
                    loopCells = cm;
                }
            }
            else
            {
                loopCells = regions.GetSpeciesMask(SpcIds[0]);
                for (int i = 1; i < SpcIds.Length; i++)
                {
                    loopCells = loopCells.Intersect(regions.GetSpeciesMask(SpcIds[i]));
                }
                if (cm != null)
                {
                    loopCells = loopCells.Intersect(cm);
                }
            }
            #endregion

            #region build list
            // ==========

            var R = new List <int>();

            // which basis is XDG?
            var        _BasisS  = mapping.BasisS.ToArray();
            XDGBasis[] _XBasisS = new XDGBasis[_BasisS.Length];
            for (int i = 0; i < _BasisS.Length; i++)
            {
                _XBasisS[i] = _BasisS[i] as XDGBasis;
            }


            Tuple <int, SpeciesId>[] iSpcS = new Tuple <int, SpeciesId> [SpcIds.Length];
            int KK;
            int Len_iSpcS = iSpcS.Length;


            int[] ExcludeListsPointer = new int[regions.SpeciesIdS.Count];


            // loop over cells?
            foreach (int jCell in loopCells.ItemEnum)
            {
                int NoOfSpc = regions.GetNoOfSpecies(jCell);

                #region
                //
                // in cell 'jCell', for each species in 'SpcIds' ...
                // * is the species present in 'jCell'?
                // * what is the species index in 'jCell'?
                // * we also have to consider that due to agglomeration, the respective cut-cell for the species might have been agglomerated.
                // so we determine
                // * 'KK' is the number of species (from 'SpcIds') which is actually present and not agglomerated in 'jCell'
                // * for i in (0 ... KK-1), iSpcS[i] is a tuple of (Species-index-in-cell, SpeciesID)
                //
                // yes, the following code sucks:
                KK = 0;
                for (int k = 0; k < Len_iSpcS; k++)   // loop over all species (provided as argument)...
                {
                    SpeciesId id      = SpcIds[k];
                    int       __iSpcS = regions.GetSpeciesIndex(id, jCell);
                    if (__iSpcS >= 0)
                    {
                        // species index is non-negative, so indices for the species are allocated ...
                        if (!presenceTest || regions.IsSpeciesPresentInCell(id, jCell))
                        {
                            // species is also present (i.e. has a greater-than-zero measure ...

                            if (drk == null)
                            {
                                // no agglomeration exclution
                                iSpcS[KK] = new Tuple <int, SpeciesId>(__iSpcS, id);
                                KK++;
                            }
                            else
                            {
                                int q  = id.cntnt - LevelSetTracker.___SpeciesIDOffest;
                                var el = ExcludeLists[q];

                                while (ExcludeListsPointer[q] < el.Length &&
                                       el[ExcludeListsPointer[q]] < jCell)
                                {
                                    ExcludeListsPointer[q]++;
                                }
                                Debug.Assert(ExcludeListsPointer[q] >= el.Length || el[ExcludeListsPointer[q]] >= jCell);

                                if (ExcludeListsPointer[q] >= el.Length || el[ExcludeListsPointer[q]] != jCell)
                                {
                                    // cell is also not agglomerated ...
                                    iSpcS[KK] = new Tuple <int, SpeciesId>(__iSpcS, id);
                                    KK++;
                                }
                            }
                        }
                    }
                }
                if (KK > 1)
                {
                    Array.Sort <Tuple <int, SpeciesId> >(iSpcS, 0, KK, new ilPSP.FuncComparer <Tuple <int, SpeciesId> >((a, b) => a.Item1 - b.Item1));
                }
                // --------- esc (end of sucking code)
                #endregion

                for (int k = 0; k < KK; k++)   // loop over species in cell
                {
                    int iSpc = iSpcS[k].Item1;

                    for (int i = 0; i < Fields.Length; i++)
                    {
                        int iField = Fields[i];

                        if (_XBasisS[iField] == null)
                        {
                            int N  = _BasisS[iField].GetLength(jCell);
                            int i0 = mapping.LocalUniqueCoordinateIndex(iField, jCell, 0);
                            for (int n = 0; n < N; n++)
                            {
                                R.Add(i0 + n);
                            }
                        }
                        else
                        {
                            int N  = _XBasisS[iField].DOFperSpeciesPerCell;
                            int i0 = mapping.LocalUniqueCoordinateIndex(iField, jCell, 0) + iSpc * N;
                            for (int n = 0; n < N; n++)
                            {
                                R.Add(i0 + n);
                            }
                        }
                    }
                }
            }
            #endregion

            return(R.ToArray());
        }
예제 #5
0
        /// <summary>
        /// computes the mass matrices for a given mapping and accumulates the mass matrix to some other matrix.
        /// </summary>
        public void AccMassMatrix <T>(T M, UnsetteledCoordinateMapping mapping, IDictionary <SpeciesId, IEnumerable <double> > _alpha, bool inverse = false)
            where T : IMutableMatrixEx //
        {
            using (new FuncTrace()) {
                var _basisS = mapping.BasisS.ToArray();
                var ctx     = _basisS[0].GridDat;
                int J       = ctx.iLogicalCells.NoOfLocalUpdatedCells;

                if (!M.RowPartitioning.EqualsPartition(mapping))
                {
                    throw new ArgumentException("Mismatch in row mapping.");
                }
                if (!M.ColPartition.EqualsPartition(mapping))
                {
                    throw new ArgumentException("Mismatch in column mapping.");
                }

                if (!_alpha.Keys.IsSubsetOf(this.AvailableSpecies))
                {
                    throw new ArgumentException("trying to obtain mass matrix for species that is not supported by this factory.");
                }

                foreach (var __alpha in _alpha.Values)
                {
                    if (__alpha.Count() != _basisS.Length)
                    {
                        throw new ArgumentException("Number of alpha's must match number of variables/fields in mapping.");
                    }
                }

                LevelSetTracker.LevelSetRegions regions = null;// XDGSpaceMetrics.LevelSetRegions;


                // compute the Mass-Blocks for the cut cells...
                // --------------------------------------------
                int _MaxDeg          = _basisS.Max(b => b.Degree);
                var RequestedSpecies = _alpha.Keys;
                UpdateBlocks(_MaxDeg, RequestedSpecies);

                Dictionary <SpeciesId, MassMatrixBlockContainer>[] invBlocks = null;
                if (inverse)
                {
                    invBlocks = GetInverseMassMatrixBlocks(RequestedSpecies, mapping.BasisS.Select(b => b.Degree).ToArray());
                    //VariableAgglomerationSwitch = new bool[VariableAgglomerationSwitch.Length];
                    //VariableAgglomerationSwitch.SetAll(true); // we already took care about this in the 'GetInverseMassMatrixBlocks'
                }

                // set the matrix
                // --------------

                for (int fld = 0; fld < _basisS.Length; fld++)   // loop over Variables in mapping...

                // loop over species...
                {
                    foreach (var species in _alpha.Keys)
                    {
                        double alpha      = _alpha[species].ElementAt(fld);
                        int[]  jSub2jCell = this.MassBlocks[species].jSub2jCell;

                        if (alpha != 0.0)
                        {
                            // properties of the basis
                            XDGBasis Xbasis = _basisS[fld] as XDGBasis;
                            Basis    nonXbasis;
                            Basis    basis = _basisS[fld];
                            if (Xbasis != null)
                            {
                                nonXbasis = Xbasis.NonX_Basis;
                                regions   = Xbasis.Tracker.Regions; // compute species indices with respect to **actual** regions !!!!
                                //if (!object.ReferenceEquals(Xbasis.Tracker, this.XDGSpaceMetrics.))
                                //    throw new ArgumentException();
                            }
                            else
                            {
                                nonXbasis = _basisS[fld];
                            }
                            int N = nonXbasis.Length;

                            // get Mass-Matrix subblock
                            MultidimensionalArray Mass;
                            if (!inverse)
                            {
                                Mass = this.MassBlocks[species].MassMatrixBlocks;
                            }
                            else
                            {
                                Mass = invBlocks[fld][species].MassMatrixBlocks;
                                Debug.Assert(Mass.GetLength(1) == N);
                                Debug.Assert(Mass.GetLength(2) == N);
                            }

                            // set diagonal element 1.0 in all cells of the subgrid
                            // (later, we subtract 1.0 from the diagonal in cut cells)
                            var speciesMask = XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(species);
                            {
                                foreach (int jCell in speciesMask.ItemEnum)
                                {
                                    int iSpc = 0;
                                    if (Xbasis != null)
                                    {
                                        int NoOfSpc = regions.GetNoOfSpecies(jCell);
                                        iSpc = regions.GetSpeciesIndex(species, jCell);
                                    }

                                    int n0 = mapping.GlobalUniqueCoordinateIndex(fld, jCell, N * iSpc);

                                    for (int n = 0; n < N; n++)
                                    {
                                        M[n0 + n, n0 + n] += alpha;
                                    }
                                }
                            }

                            // now, set then Non-Identity blocks in the cut cells
                            var speciesBitMask = speciesMask.GetBitMask();
                            {
                                int JSUB = jSub2jCell.Length;

                                for (int jsub = 0; jsub < JSUB; jsub++)   // loop over cut cells

                                {
                                    int jCell = jSub2jCell[jsub];
                                    if (!speciesBitMask[jCell])
                                    {
                                        continue;
                                    }


                                    int iSpc = 0;
                                    if (Xbasis != null)
                                    {
                                        int NoOfSpc = regions.GetNoOfSpecies(jCell);
                                        iSpc = regions.GetSpeciesIndex(species, jCell);
                                    }

                                    var MassSub = Mass.ExtractSubArrayShallow(new int[] { jsub, 0, 0 }, new int[] { jsub - 1, N - 1, N - 1 });

                                    int i0 = mapping.GlobalUniqueCoordinateIndex(fld, jCell, N * iSpc);

                                    for (int n = 0; n < N; n++)     // loop over rows (within block)
                                    {
                                        for (int m = 0; m < N; m++) // loop over columns (within block)
                                        {
                                            M[i0 + n, i0 + m] += alpha * MassSub[n, m] - (m == n ? alpha : 0.0);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }