/// <summary>
        /// Legacy interface, preserved as static function.
        /// </summary>
        static public void ComputeMatrixEx <M, V>(
            this XSpatialOperator xOp,
            LevelSetTracker lsTrk,
            UnsetteledCoordinateMapping DomainMap, IList <DGField> Parameters, UnsetteledCoordinateMapping CodomainMap,
            M Matrix, V AffineOffset, bool OnlyAffine,
            double time,
            bool MPIParameterExchange,
            SubGrid subGrid, params SpeciesId[] whichSpc)
            where M : IMutableMatrixEx
            where V : IList <double>  //
        {
            Console.WriteLine("Warning: Legacy interface!");
            Console.WriteLine("         Usage of XDG without an agglomerated penalty!");


            int order = xOp.GetOrderFromQuadOrderFunction(DomainMap, Parameters, CodomainMap);
            MultiphaseCellAgglomerator dummy = lsTrk.GetAgglomerator(lsTrk.SpeciesIdS.ToArray(), order, 0.0);
            Dictionary <SpeciesId, MultidimensionalArray> Idummy = dummy.XDGSpaceMetrics.CutCellMetrics.InterfaceArea;


            var bla = new Dictionary <SpeciesId, XSpatialOperator.QrSchemPair>();

            foreach (var sp in whichSpc)
            {
                bla.Add(sp, new XSpatialOperator.QrSchemPair());
            }

            ComputeMatrixEx <M, V>(
                xOp,
                lsTrk,
                DomainMap, Parameters, CodomainMap,
                Matrix, AffineOffset,
                OnlyAffine, time, MPIParameterExchange, bla,
                dummy.CellLengthScales, Idummy, SubGrid: subGrid);

            Debug.Assert(dummy.TotalNumberOfAgglomerations <= 0, "internal error");
        }
예제 #2
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());
        }