예제 #1
0
        static private void CompOffsets(int i0, int L, int[] offset, UnsetteledCoordinateMapping Map)
        {
            int DELTA = offset.Length;

            Debug.Assert(DELTA == Map.BasisS.Count);

            int _o0 = Map.LocalUniqueCoordinateIndex(0, i0, 0);

            for (int delta = 0; delta < offset.Length; delta++)
            {
                offset[delta] = Map.LocalUniqueCoordinateIndex(delta, i0, 0) - _o0;
            }

#if DEBUG
            int[] Ns = new int[DELTA];
            for (int delta = 0; delta < DELTA; delta++)
            {
                Ns[delta] = Map.BasisS[delta].GetLength(i0);
            }
            for (int i = 1; i < L; i++)
            {
                for (int delta = 0; delta < DELTA; delta++)
                {
                    Debug.Assert(Ns[delta] == Map.BasisS[delta].GetLength(i0 + i));
                }
            }
#endif
        }
예제 #2
0
        /// <summary>
        /// computes a local unique coordinate index ("local" means local on this processor);
        /// this index is unique over all fields (in this mapping), over all cells, over all basis functions,
        /// but it's only locally (on this processor) valid.
        /// A local index in the update range (smaller than <see cref="NUpdate"/>) can be converted into
        /// a global index by adding <see cref="Partitioning.i0"/>.
        /// </summary>
        /// <param name="find">
        /// the field or basis index (see <see cref="BasisS"/>);
        /// </param>
        /// <param name="j">local cell index</param>
        /// <param name="n">DG mode index</param>
        /// <param name="lsTrk"></param>
        /// <param name="map"></param>
        /// <param name="spcIdx">species index</param>
        public static int LocalUniqueCoordinateIndex(this UnsetteledCoordinateMapping map, LevelSetTracker lsTrk, int find, int j, int spcIdx, int n)
        {
            //;

            int NoOfSpc = lsTrk.Regions.GetNoOfSpecies(j, out var rrc);

            if (spcIdx < 0 || spcIdx >= NoOfSpc)
            {
                throw new IndexOutOfRangeException($"Species index out of range (species index is {spcIdx}, Number of species is {NoOfSpc}, cell {j})");
            }

            Basis    b  = map.BasisS[find];
            XDGBasis xb = b as XDGBasis;

            if (xb == null)
            {
                return(map.LocalUniqueCoordinateIndex(find, j, n));
            }
            else
            {
                int i0 = map.LocalUniqueCoordinateIndex(find, j, 0);
                int Ns = xb.NonX_Basis.GetLength(j);
                if (n < 0 || n >= Ns)
                {
                    throw new IndexOutOfRangeException($"DG mode index (within species) of range (DG mode index is {n}, but non-XDG basis length is {Ns}, cell {j})");
                }

                return(i0 + Ns * spcIdx + n);
            }
        }
예제 #3
0
        /// <summary>
        /// writes the dammed result of the integration to the sparse matrix
        /// </summary>
        protected override void SaveIntegrationResults(int i0, int Length, MultidimensionalArray ResultsOfIntegration)
        {
            int Nmax = m_CodomainMap.MaxTotalNoOfCoordinatesPerCell;

            //int[] _i0 = new int[] { int.MaxValue, 0, 1 };
            //int[] _iE = new int[] { -1, Nmax - 1, _i0[2] + Mmax - 1 };

            int[] _i0aff = new int[] { int.MaxValue, 0 };
            int[] _iEaff = new int[] { -1, Nmax - 1 };


            // loop over cells...
            for (int i = 0; i < Length; i++)
            {
                int jCell  = i + i0;
                int Row0   = m_CodomainMap.LocalUniqueCoordinateIndex(0, jCell, 0);
                int Row0_g = m_CodomainMap.i0 + Row0;

                _i0aff[0] = i;
                _iEaff[0] = -1;

                var BlockRes = ResultsOfIntegration.ExtractSubArrayShallow(_i0aff, _iEaff);

                for (int r = BlockRes.GetLength(0) - 1; r >= 0; r--)
                {
                    ResultVector[Row0 + r] += BlockRes[r];
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Computes the permutation for the given <paramref name="RowMap"/>
        /// </summary>
        /// <param name="RowMap"></param>
        /// <param name="grd"></param>
        /// <returns></returns>
        public static int[] ComputePermutation(UnsetteledCoordinateMapping RowMap, GridData grd)
        {
            int J = grd.Grid.NoOfUpdateCells;

            int[] N         = RowMap.BasisS.Select(x => x.MaximalLength).ToArray();
            int   NT        = N.Sum();
            int   Gamma     = RowMap.BasisS.Count;
            var   GlobalIDs = grd.CurrentGlobalIdPermutation.Values;

            int[] PermutationTable;
            PermutationTable = new int[RowMap.LocalLength];
            Debug.Assert(PermutationTable.Length == J * NT);
            for (int j = 0; j < J; j++)
            {
                int gid    = (int)GlobalIDs[j];
                int iTarg0 = gid * NT;

                int i0 = (int)RowMap.LocalUniqueCoordinateIndex(0, j, 0);
                for (int f = 0; f < Gamma; f++)
                {
                    for (int n = 0; n < N[f]; n++)
                    {
                        int i     = (int)RowMap.LocalUniqueCoordinateIndex(f, j, n);
                        int iTarg = iTarg0 + (i - i0);
                        PermutationTable[i] = iTarg;
                    }
                }
            }


            int[] globalPermutationTable = new int[grd.Grid.NumberOfCells * NT];
            unsafe {
                int[] displ  = RowMap.GetI0s().Select(x => (int)x).ToArray();
                int[] rcvCnt = new int[RowMap.MpiSize];
                for (int i = 0; i < RowMap.MpiSize; i++)
                    rcvCnt[i] = displ[i + 1] - displ[i];

                fixed(int *pSnd = PermutationTable, pRcv = globalPermutationTable, pDispl = displ, pRcvCnt = rcvCnt)
                {
                    csMPI.Raw.Allgatherv((IntPtr)pSnd, PermutationTable.Length, csMPI.Raw._DATATYPE.INT,
                                         (IntPtr)pRcv, (IntPtr)pRcvCnt, (IntPtr)pDispl, csMPI.Raw._DATATYPE.INT,
                                         csMPI.Raw._COMM.WORLD);
                }
            }

            return(globalPermutationTable);
        }
예제 #5
0
        /// <summary>
        /// Prolongates/injects a vector from the full grid (<see cref="BoSSS.Foundation.Grid.GridData"/>)
        /// to the aggregated grid (<see cref="AggGrid"/>).
        /// </summary>
        /// <param name="FullGridVector">output;</param>
        /// <param name="AggGridVector">input;</param>
        virtual public void ProlongateToFullGrid <T, V>(T FullGridVector, V AggGridVector)
            where T : IList <double>
            where V : IList <double> //
        {
            var fullMapping = new UnsetteledCoordinateMapping(this.DGBasis);

            if (FullGridVector.Count != fullMapping.LocalLength)
            {
                throw new ArgumentException("mismatch in vector length", "FullGridVector");
            }
            int L = this.LocalDim;

            if (AggGridVector.Count != L)
            {
                throw new ArgumentException("mismatch in vector length", "AggGridVector");
            }


            var ag    = this.AggGrid;
            var agCls = ag.iLogicalCells.AggregateCellToParts;
            int JAGG  = ag.iLogicalCells.NoOfLocalUpdatedCells;
            int N     = this.DGBasis.Length;

            var FulCoords = new double[N];
            var AggCoords = new double[N];

            //MultidimensionalArray Trf = MultidimensionalArray.Create(N, N);

            for (int jAgg = 0; jAgg < JAGG; jAgg++)
            {
                int[] agCl = agCls[jAgg];
                int   K    = agCl.Length;

                int i0 = jAgg * N;
                for (int n = 0; n < N; n++)
                {
                    AggCoords[n] = AggGridVector[n + i0];
                }

                for (int k = 0; k < K; k++)  // loop over the cells wich form the aggregated cell...
                {
                    int jCell = agCl[k];
                    int j0    = fullMapping.LocalUniqueCoordinateIndex(0, jCell, 0);

                    //Trf.Clear();
                    //Trf.Acc(1.0, this.CompositeBasis[jAgg].ExtractSubArrayShallow(k, -1, -1));
                    var Trf = this.CompositeBasis[jAgg].ExtractSubArrayShallow(k, -1, -1);

                    //Trf.Solve(FulCoords, AggCoords);
                    Trf.gemv(1.0, AggCoords, 0.0, FulCoords);

                    for (int n = 0; n < N; n++)
                    {
                        FullGridVector[j0 + n] = FulCoords[n];
                    }
                }
            }
        }
예제 #6
0
        /// <summary>
        /// restricts/projects a vector from the full grid (<see cref="BoSSS.Foundation.Grid.Classic.GridData"/>)
        /// to the aggregated grid (<see cref="AggGrid"/>).
        /// </summary>
        /// <param name="FullGridVector">input;</param>
        /// <param name="AggGridVector">output;</param>
        virtual public void RestictFromFullGrid <T, V>(T FullGridVector, V AggGridVector)
            where T : IList <double>
            where V : IList <double> //
        {
            var fullMapping = new UnsetteledCoordinateMapping(this.DGBasis);

            if (FullGridVector.Count != fullMapping.LocalLength)
            {
                throw new ArgumentException("mismatch in vector length", "FullGridVector");
            }
            int L = this.LocalDim;

            if (AggGridVector.Count != L)
            {
                throw new ArgumentException("mismatch in vector length", "AggGridVector");
            }

            var ag    = this.AggGrid;
            var agCls = ag.iLogicalCells.AggregateCellToParts;
            int JAGG  = ag.iLogicalCells.NoOfLocalUpdatedCells;
            int N     = this.DGBasis.Length;

            var Buffer    = MultidimensionalArray.Create(agCls.Max(cc => cc.Length), N);
            var Aggcoords = MultidimensionalArray.Create(N);

            for (int jAgg = 0; jAgg < JAGG; jAgg++)   // loop over all aggregated cells...
            {
                int[] agCl = agCls[jAgg];
                int   K    = agCl.Length;

                MultidimensionalArray coords = (K * N == Buffer.GetLength(0)) ? Buffer : Buffer.ExtractSubArrayShallow(new int[] { 0, 0 }, new int[] { K - 1, N - 1 });

                for (int k = 0; k < K; k++)   // loop over the cells which form the aggregated cell...
                {
                    int jCell = agCl[k];
                    int j0    = fullMapping.LocalUniqueCoordinateIndex(0, jCell, 0);
                    for (int n = 0; n < N; n++)
                    {
                        coords[k, n] = FullGridVector[n + j0];
                    }
                }

                Aggcoords.Clear();
                Aggcoords.Multiply(1.0, this.CompositeBasis[jAgg], coords, 0.0, "n", "kmn", "km");

                int i0 = jAgg * N;
                for (int n = 0; n < N; n++)
                {
                    AggGridVector[n + i0] = Aggcoords[n];
                }
            }
        }
예제 #7
0
        /// <summary>
        /// writes the dammed result of the integration to the sparse matrix
        /// </summary>
        protected override void SaveIntegrationResults(int i0, int Length, MultidimensionalArray ResultsOfIntegration)
        {
            int Mmax = m_ColMap.MaxTotalNoOfCoordinatesPerCell;
            int Nmax = m_RowMap.MaxTotalNoOfCoordinatesPerCell;

            int[] _i0 = new int[] { int.MaxValue, 0, 1 };
            int[] _iE = new int[] { -1, Nmax - 1, _i0[2] + Mmax - 1 };

            int[] _i0aff = new int[] { int.MaxValue, 0, 0 };
            int[] _iEaff = new int[] { -1, Nmax - 1, -1 };

            bool saveMtx = this.OperatorMatrix != null;
            bool saveAff = this.OperatorAffine != null;

            // loop over cells...
            for (int i = 0; i < Length; i++)
            {
                int jCell  = i + i0;
                int Row0   = m_RowMap.LocalUniqueCoordinateIndex(0, jCell, 0);
                int Row0_g = m_RowMap.i0 + Row0;

                if (saveMtx)
                {
                    _i0[0] = i;
                    _iE[0] = -1;

                    var BlockRes = ResultsOfIntegration.ExtractSubArrayShallow(_i0, _iE);

                    int Col0_g = m_ColMap.GlobalUniqueCoordinateIndex(0, jCell, 0);


                    //for (int r = BlockRes.NoOfRows - 1; r >= 0; r--)
                    //    for (int c = BlockRes.NoOfCols - 1; c >= 0; c--)
                    //        OperatorMatrix[Row0_g + r, Col0_g + c] += BlockRes[r, c];
                    OperatorMatrix.AccBlock(Row0_g, Col0_g, 1.0, BlockRes);
                }

                if (saveAff)
                {
                    _i0aff[0] = i;
                    _iEaff[0] = -1;

                    var BlockRes = ResultsOfIntegration.ExtractSubArrayShallow(_i0aff, _iEaff);

                    for (int r = BlockRes.GetLength(0) - 1; r >= 0; r--)
                    {
                        OperatorAffine[Row0 + r] += BlockRes[r];
                    }
                }
            }
        }
예제 #8
0
        /// <summary>
        /// writes the dammed result of the integration to the sparse matrix
        /// </summary>
        protected override void SaveIntegrationResults(int i0, int Length, MultidimensionalArray ResultsOfIntegration)
        {
            int GAMMA = this.m_CodomainMap.BasisS.Count;  // GAMMA: number of codom/row/test variables

            LECQuadratureLevelSet <IMutableMatrixEx, double[]> .CompOffsets(i0, Length, out int[] offsetRow, out int[] RowNonxN, m_CodomainMap);

            SpeciesId[] spcS = new[] { this.SpeciesA, this.SpeciesB };

            int[] _i0aff = new int[2];
            int[] _iEaff = new int[2];

            // loop over cells...
            for (int i = 0; i < Length; i++)
            {
                int jCell = i + i0;
#if DEBUG
                Debug.Assert(RowNonxN.ListEquals(m_CodomainMap.GetNonXBasisLengths(jCell)));
#endif

                _i0aff[0] = i;
                _iEaff[0] = -1;

                for (int gamma = 0; gamma < GAMMA; gamma++) // loop over rows...
                {
                    for (int cr = 0; cr < 2; cr++)          // loop over neg/pos species row...
                    {
                        SpeciesId rowSpc = spcS[cr];
                        int       Row0   = m_CodomainMap.LocalUniqueCoordinateIndex(m_lsTrk, gamma, jCell, rowSpc, 0);

                        _i0aff[1] = offsetRow[gamma] + RowNonxN[gamma] * cr; // the 'RowXbSw' is 0 for non-xdg, so both species will be added
                        _iEaff[1] = _i0aff[1] + RowNonxN[gamma] - 1;


                        var BlockRes = ResultsOfIntegration.ExtractSubArrayShallow(_i0aff, _iEaff);

                        for (int r = BlockRes.GetLength(0) - 1; r >= 0; r--)
                        {
                            ResultVector[Row0 + r] += BlockRes[r];
                        }
                    }
                }
            }
        }
예제 #9
0
        public override void RestictFromFullGrid <T, V>(T FullGridVector, V AggGridVector)
        {
            var fullMapping = new UnsetteledCoordinateMapping(this.XDGBasis);

            if (FullGridVector.Count != fullMapping.LocalLength)
            {
                throw new ArgumentException("mismatch in vector length", "FullGridVector");
            }
            int L = this.LocalDim;

            if (AggGridVector.Count != L)
            {
                throw new ArgumentException("mismatch in vector length", "AggGridVector");
            }


            var ag    = this.AggGrid;
            var agCls = ag.iLogicalCells.AggregateCellToParts;
            int JAGG  = ag.iLogicalCells.NoOfLocalUpdatedCells;
            int Nmax  = this.XDGBasis.MaximalLength;
            int N     = this.DGBasis.Length;

            Debug.Assert(Nmax % N == 0);


            var Buffer    = MultidimensionalArray.Create(agCls.Max(cc => cc.Length), N);
            var AggCoords = MultidimensionalArray.Create(N);



            for (int jAgg = 0; jAgg < JAGG; jAgg++)  // loop over all composite cells...
            {
                int[] agCl = agCls[jAgg];
                int   K    = agCl.Length;

                MultidimensionalArray FulCoords = (K * N == Buffer.GetLength(0)) ? Buffer : Buffer.ExtractSubArrayShallow(new int[] { 0, 0 }, new int[] { K - 1, N - 1 });

                int i0Agg = jAgg * Nmax, i0Full;


                if (this.SpeciesIndexMapping[jAgg] == null)
                {
                    // default branch:
                    // use restiction/prolongation from un-cut basis
                    // +++++++++++++++++++++++++++++++++++++++++++++

                    for (int k = 0; k < K; k++)  // loop over the cells wich form the aggregated cell...
                    {
                        int jCell = agCl[k];
                        i0Full = jCell * Nmax;
                        for (int n = 0; n < N; n++)
                        {
                            FulCoords[k, n] = FullGridVector[n + i0Full];
                        }
                    }

                    MultidimensionalArray Trf = base.CompositeBasis[jAgg];
                    AggCoords.Clear();
                    AggCoords.Multiply(1.0, Trf, FulCoords, 0.0, "n", "kmn", "km");

                    int _i0 = jAgg * N;
                    for (int n = 0; n < N; n++)
                    {
                        AggGridVector[n + i0Agg] = AggCoords[n];
                    }
                }
                else
                {
                    int NoSpc = this.NoOfSpecies[jAgg];
                    int[,] sim = SpeciesIndexMapping[jAgg];
                    Debug.Assert(sim.GetLength(0) == NoSpc);
                    Debug.Assert(sim.GetLength(1) == K);

                    for (int iSpcAgg = 0; iSpcAgg < NoSpc; iSpcAgg++)
                    {
                        for (int k = 0; k < K; k++)  // loop over the cells wich form the aggregated cell...
                        {
                            int jCell    = agCl[k];
                            int iSpcBase = sim[iSpcAgg, k];

                            if (iSpcBase < 0)
                            {
                                for (int n = 0; n < N; n++)
                                {
                                    FulCoords[k, n] = 0;
                                }
                            }
                            else
                            {
                                i0Full = fullMapping.LocalUniqueCoordinateIndex(0, jCell, iSpcBase * N);

                                for (int n = 0; n < N; n++)
                                {
                                    FulCoords[k, n] = FullGridVector[i0Full + n];
                                }
                            }
                        }

                        MultidimensionalArray Trf;
                        if (this.XCompositeBasis[jAgg] == null || this.XCompositeBasis[jAgg][iSpcAgg] == null)
                        {
                            Trf = base.CompositeBasis[jAgg];
                        }
                        else
                        {
                            Trf = this.XCompositeBasis[jAgg][iSpcAgg];
                        }

                        AggCoords.Clear();
                        AggCoords.Multiply(1.0, Trf, FulCoords, 0.0, "n", "kmn", "km");

                        for (int n = 0; n < N; n++)
                        {
                            AggGridVector[i0Agg + iSpcAgg * N + n] = AggCoords[n];
                        }
                    }
                }
            }
        }
예제 #10
0
        public override void ProlongateToFullGrid <T, V>(T FullGridVector, V AggGridVector)
        {
            var fullMapping = new UnsetteledCoordinateMapping(this.XDGBasis);

            if (FullGridVector.Count != fullMapping.LocalLength)
            {
                throw new ArgumentException("mismatch in vector length", "FullGridVector");
            }
            int L = this.LocalDim;

            if (AggGridVector.Count != L)
            {
                throw new ArgumentException("mismatch in vector length", "AggGridVector");
            }


            var ag    = this.AggGrid;
            var agCls = ag.iLogicalCells.AggregateCellToParts;
            int JAGG  = ag.iLogicalCells.NoOfLocalUpdatedCells;
            int Nmax  = this.XDGBasis.MaximalLength;
            int N     = this.DGBasis.Length;

            Debug.Assert(Nmax % N == 0);


            var FulCoords = new double[N];
            var AggCoords = new double[N];


            for (int jAgg = 0; jAgg < JAGG; jAgg++)  // loop over all composite cells...
            {
                int[] agCl = agCls[jAgg];
                int   K    = agCl.Length;


                if (this.SpeciesIndexMapping[jAgg] == null)
                {
                    Debug.Assert(this.XCompositeBasis[jAgg] == null);

                    int i0 = jAgg * Nmax; // index offset into 'AggGridVector'
                    for (int n = 0; n < N; n++)
                    {
                        AggCoords[n] = AggGridVector[n + i0];
                    }

                    for (int k = 0; k < K; k++)  // loop over the cells wich form the aggregated cell...
                    {
                        int jCell = agCl[k];
                        int j0    = fullMapping.LocalUniqueCoordinateIndex(0, jCell, 0);

                        MultidimensionalArray Trf = base.CompositeBasis[jAgg].ExtractSubArrayShallow(k, -1, -1);

                        //Trf.Solve(FulCoords, AggCoords);
                        Trf.GEMV(1.0, AggCoords, 0.0, FulCoords);

                        for (int n = 0; n < N; n++)
                        {
                            FullGridVector[j0 + n] = FulCoords[n];
                        }
                    }
                }
                else
                {
                    int NoSpc = this.NoOfSpecies[jAgg];
                    int[,] sim = SpeciesIndexMapping[jAgg];
                    Debug.Assert(sim.GetLength(0) == NoSpc);
                    Debug.Assert(sim.GetLength(1) == K);

                    for (int iSpcAgg = 0; iSpcAgg < NoSpc; iSpcAgg++)
                    {
                        int i0 = jAgg * Nmax + iSpcAgg * N; // index offset into 'AggGridVector'
                        for (int n = 0; n < N; n++)
                        {
                            AggCoords[n] = AggGridVector[n + i0];
                        }


                        for (int k = 0; k < K; k++)  // loop over the cells wich form the aggregated cell...
                        {
                            int jCell    = agCl[k];
                            int iSpcBase = sim[iSpcAgg, k];
                            if (iSpcBase < 0)
                            {
                                continue;
                            }

                            int j0 = fullMapping.LocalUniqueCoordinateIndex(0, jCell, iSpcBase * N);

                            MultidimensionalArray Trf;
                            if (this.XCompositeBasis[jAgg] == null || this.XCompositeBasis[jAgg][iSpcAgg] == null)
                            {
                                Trf = base.CompositeBasis[jAgg].ExtractSubArrayShallow(k, -1, -1);
                            }
                            else
                            {
                                Trf = this.XCompositeBasis[jAgg][iSpcAgg].ExtractSubArrayShallow(k, -1, -1);
                            }

                            Trf.GEMV(1.0, AggCoords, 0.0, FulCoords);

                            for (int n = 0; n < N; n++)
                            {
                                FullGridVector[j0 + n] = FulCoords[n];
                            }
                        }
                    }
                }
            }
        }
예제 #11
0
        /// <summary>
        /// Computes a mapping from the new, cell local DG coordinate index to the previous/old DG coordinate index, or vice-versa.
        /// </summary>
        /// <param name="jCell">
        /// Local cell index.
        /// </param>
        /// <param name="New2Old">
        /// If true, a mapping from new species index to previous/old species index is returned,
        /// if false the other way around.
        /// </param>
        /// <param name="LsTrk">
        /// </param>
        /// <param name="Map">
        /// DG coordinate mapping.
        /// </param>
        /// <returns>
        /// Null, if there is no change in species ordering in cell <paramref name="jCell"/>
        /// from the previous level-set tracker state to the actual.
        ///
        /// Otherwise, if <paramref name="New2Old"/> is true, an array of the same length
        /// as the number of degrees-of-freedom currently in cell <paramref name="jCell"/>.
        ///  - index: current DOF index in cell <paramref name="jCell"/>.
        ///  - content: index of this DOF with respect to the previous level-set-tracker state.
        /// If <paramref name="New2Old"/> false, the other way around.
        /// </returns>
        public static int[] MappingUpdate(LevelSetTracker LsTrk, int jCell, UnsetteledCoordinateMapping Map, bool New2Old)
        {
            int[] SpeciesMap = SpeciesUpdate(LsTrk, jCell, New2Old);
            if (SpeciesMap == null)
            {
                return(null);
            }

            int NoVar = Map.NoOfVariables;

            XDGBasis[] XBasiseS = new XDGBasis[NoVar];
            Basis[]    BasiseS  = new Basis[NoVar];
            int[]      Ns       = new int[NoVar];

            for (int iVar = 0; iVar < NoVar; iVar++)
            {
                Basis b = Map.BasisS[iVar];
                XBasiseS[iVar] = b as XDGBasis;
                if (XBasiseS[iVar] != null)
                {
                    BasiseS[iVar] = XBasiseS[iVar].NonX_Basis;
                }
                else
                {
                    BasiseS[iVar] = b;
                }
                Ns[iVar] = BasiseS[iVar].Length;
            }

            //List<int> oldIdx = new List<int>();
            //List<int> newIdx = new List<int>();
            int[] IdxMap = new int[Map.MaxTotalNoOfCoordinatesPerCell];
            ArrayTools.SetAll(IdxMap, int.MinValue);

            bool AnyRelocation = false;

            int i0 = Map.LocalUniqueCoordinateIndex(0, jCell, 0);

            for (int iVar = 0; iVar < NoVar; iVar++)
            {
                int i0Var  = Map.LocalUniqueCoordinateIndex(iVar, jCell, 0);
                int N      = Ns[iVar];
                int offset = i0Var - i0;

                if (XBasiseS[iVar] != null)
                {
                    // XDG-field

                    for (int i = 0; i < SpeciesMap.Length; i++)
                    {
                        int ii = SpeciesMap[i];
                        for (int n = 0; n < N; n++)
                        {
                            int idxS = offset + n + i * N;
                            int idxT = ii >= 0 ? offset + n + ii * N : int.MinValue;
                            Debug.Assert(IdxMap[idxS] < 0);
                            IdxMap[idxS] = idxT;

                            AnyRelocation |= (idxS != idxT);
                        }
                    }
                }
                else
                {
                    // single-phase-field
                    for (int n = 0; n < N; n++)
                    {
                        int idx = offset + n;
                        //oldIdx.Add(idx);
                        //newIdx.Add(idx);
                        Debug.Assert(IdxMap[idx] < 0);
                        IdxMap[idx] = idx;
                    }
                }
            }

            return(IdxMap);
            //if (AnyRelocation)
            //    return IdxMap;
            //else
            //    return null;
        }
예제 #12
0
        /// <summary>
        /// Tools for updating RHS under level-set movement, when ordering of DOFs (the mapping) changes.
        /// </summary>
        public static void OperatorLevelSetUpdate(LevelSetTracker LsTrk, double[] Affine, UnsetteledCoordinateMapping RowMap)
        {
            using (new FuncTrace()) {
                if (RowMap.LocalLength != Affine.Length)
                {
                    throw new ArgumentException();
                }
                if (!object.ReferenceEquals(LsTrk.GridDat, RowMap.GridDat))
                {
                    throw new ArgumentException();
                }

                BoSSS.Foundation.Grid.IGridData GridData = LsTrk.GridDat;


                int J     = GridData.iLogicalCells.NoOfLocalUpdatedCells;
                int GAMMA = RowMap.NoOfVariables;
                //int DELTA = ColMap.NoOfVariables;

                //int ColBlockSize = ColMap.MaxTotalNoOfCoordinatesPerCell;
                int RowBlockSize = RowMap.MaxTotalNoOfCoordinatesPerCell;

                int Gj0 = GridData.CellPartitioning.i0;

                int NoOfSpc = LsTrk.TotalNoOfSpecies;

                double[] OldAffine = new double[RowBlockSize];
                Dictionary <int, int[]> jNeighs = new Dictionary <int, int[]>(); // Key:     global cell index
                                                                                 //                                                                values:  re-sorting for species in this cell
                Tuple <int, int[], double[]>[] oldRows = new Tuple <int, int[], double[]> [RowBlockSize];

                // loop over cells
                for (int j = 0; j < J; j++)
                {
                    int[] RowIdxUpdate = MappingUpdate(LsTrk, j, RowMap, false);

                    // affine vector update
                    // --------------------
                    if (Affine != null && RowIdxUpdate != null)
                    {
                        // some update occurred
                        // +++++++++++++++++++++++

                        int i0 = RowMap.LocalUniqueCoordinateIndex(0, j, 0);
                        Debug.Assert(i0 + RowBlockSize <= RowMap.LocalLength);
                        Debug.Assert(i0 >= 0);

                        for (int i = 0; i < RowBlockSize; i++)
                        {
                            OldAffine[i]   = Affine[i + i0];
                            Affine[i + i0] = 0.0;
                        }

                        for (int i = 0; i < RowBlockSize; i++)
                        {
                            int k = RowIdxUpdate[i];

                            if (k < 0)
                            {
                                if (OldAffine[i] != 0.0)
                                {
                                    throw new ApplicationException("Cannot kill non-null entry.");
                                }
                            }
                            else
                            {
                                Affine[i0 + k] = OldAffine[i];
                            }
                        }
                    }
                }
            }
        }
예제 #13
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());
        }