예제 #1
0
 public int i0Func(int jCell, int iVar)
 {
     if (VarIsXdg[iVar]) {
         int iSpc = m_LsRegion.GetSpeciesIndex(this.m_spId, jCell);
         return m_Map.GlobalUniqueCoordinateIndex(iVar, jCell, iSpc * NS[iVar]);
     } else {
         return m_Map.GlobalUniqueCoordinateIndex(iVar, jCell, 0);
     }
 }
예제 #2
0
        /// <summary>
        /// Accumulates an identity matrix, but only for selected variabels
        /// </summary>
        /// <param name="M">matrix to be modified (input/output)</param>
        /// <param name="factor"></param>
        /// <param name="iVar"></param>
        static public void AccEyeSp(this ISparseMatrix M, UnsetteledCoordinateMapping map, int[] iVar, double factor = 1.0)
        {
            using (new FuncTrace()) {
                if (M.RowPartitioning.LocalLength != M.ColPartition.LocalLength)
                {
                    throw new ArgumentException("supported only for quadratic matrices");
                }
                if (map.LocalLength != M.RowPartitioning.LocalLength)
                {
                    throw new ArgumentException();
                }

                int J = map.GridDat.iLogicalCells.NoOfLocalUpdatedCells;

                for (int j = 0; j < J; j++)
                {
                    foreach (int f in iVar)
                    {
                        int Np = map.BasisS[f].GetLength(j);

                        for (int n = 0; n < Np; n++)
                        {
                            int idx = map.GlobalUniqueCoordinateIndex(f, j, n);

                            M.SetDiagonalElement(idx, M.GetDiagonalElement(idx) + factor);
                        }
                    }
                }
            }
        }
예제 #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 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];
                    }
                }
            }
        }
예제 #4
0
        virtual public void GetRestrictionMatrix(BlockMsrMatrix rest, MultigridMapping mgMap, int iFld)
        {
            if (!object.ReferenceEquals(mgMap.AggBasis[iFld], this))
            {
                throw new ArgumentException();
            }

            UnsetteledCoordinateMapping fullmap = mgMap.ProblemMapping;

            int[] degree = mgMap.DgDegree;

            foreach (var b in fullmap.BasisS)
            {
                if (!b.IsSubBasis(this.DGBasis))
                {
                    throw new ArgumentException("");
                }
                if (b.MaximalLength != b.MinimalLength)
                {
                    throw new NotSupportedException();
                }
            }
            if (fullmap.BasisS.Count != degree.Length)
            {
                throw new ArgumentException();
            }
            int NoFld = degree.Length;

            int[] FullLength = fullmap.BasisS.Select(b => b.Length).ToArray();
            int[] RestLength = NoFld.ForLoop(
                l => fullmap.BasisS[l].Polynomials[0].Where(poly => poly.AbsoluteDegree <= degree[l]).Count());
            int[] RestOffset = new int[NoFld];
            for (int f = 1; f < NoFld; f++)
            {
                RestOffset[f] = RestOffset[f - 1] + RestLength[f - 1];
            }

            int NR    = RestLength.Sum();
            int JAGG  = this.AggGrid.iLogicalCells.NoOfLocalUpdatedCells;
            var ag    = this.AggGrid;
            var agCls = ag.iLogicalCells.AggregateCellToParts;


            //Partitioning RowMap = new Partitioning(JAGG * NR);
            int MpiOffset_row = rest.RowPartitioning.i0;

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

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

                    int M     = RestLength[iFld];
                    int N     = FullLength[iFld];
                    var Block = this.CompositeBasis[jagg].ExtractSubArrayShallow(new int[] { k, 0, 0 }, new int[] { k - 1, N - 1, M - 1 });

                    //for(int f = 0; f < NoFld; f++) { // loop over DG fields in mapping...

                    int i0Col = fullmap.GlobalUniqueCoordinateIndex(iFld, jCell, 0);
                    int i0Row = jagg * NR + RestOffset[iFld] + MpiOffset_row;

                    //rest.AccBlock(i0Row, i0Col, 1.0, Block);
                    for (int m = 0; m < M; m++)
                    {
                        for (int n = 0; n < N; n++)
                        {
                            rest[i0Row + m, i0Col + n] = Block[n, m];
                        }
                    }
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Tools for updating operator matrices under level-set movement, when ordering of DOFs (the mapping) changes.
        /// </summary>
        public static void OperatorLevelSetUpdate(LevelSetTracker LsTrk,
                                                  BlockMsrMatrix[] OpMtx, UnsetteledCoordinateMapping RowMap, UnsetteledCoordinateMapping ColMap)
        {
            using (new FuncTrace()) {
                BoSSS.Foundation.Grid.IGridData GridData = LsTrk.GridDat;
                int JE      = GridData.iLogicalCells.NoOfCells;
                int Jup     = GridData.iLogicalCells.NoOfLocalUpdatedCells;
                int cell_j0 = GridData.CellPartitioning.i0;

                // build index mappings
                // ====================
                int[,] _old2NewRows, _old2NewCols;
                {
                    List <Tuple <int, int> > old2NewRows    = new List <Tuple <int, int> >();
                    List <Tuple <int, int> > old2NewCols    = new List <Tuple <int, int> >();
                    List <Tuple <int, int> > old2NewColsExt = new List <Tuple <int, int> >();

                    // loop over cells
                    for (int j = 0; j < JE; j++)
                    {
                        int[] RowIdxUpdate;
                        if (j < Jup)
                        {
                            RowIdxUpdate = MappingUpdate(LsTrk, j, RowMap, false);
                        }
                        else
                        {
                            RowIdxUpdate = null;
                        }

                        int[] ColIdxUpdate = MappingUpdate(LsTrk, j, ColMap, false);

                        Debug.Assert((j >= Jup) || ((RowIdxUpdate != null) == (ColIdxUpdate != null)));
                        if (RowIdxUpdate != null)
                        {
                            //Debug.Assert(RowMap.GetBlockLen(cell_j0 + j) == RowMap.MaxTotalNoOfCoordinatesPerCell);
                            //Debug.Assert(RowIdxUpdate.Length == RowMap.GetBlockLen(cell_j0 + j));

                            int i0 = RowMap.GetBlockI0(cell_j0 + j);

                            int II = RowIdxUpdate.Length;
                            for (int ii = 0; ii < II; ii++)
                            {
                                int iOld = ii + i0;
                                int iNew = RowIdxUpdate[ii] + i0;
                                if (RowIdxUpdate[ii] >= 0)
                                {
                                    Debug.Assert(old2NewRows.Count == 0 || old2NewRows[old2NewRows.Count - 1].Item1 < iOld);
                                    old2NewRows.Add(new Tuple <int, int>(iOld, iNew));
                                }
                            }
                        }

                        if (ColIdxUpdate != null)
                        {
                            //Debug.Assert(ColMap.MinTotalNoOfCoordinatesPerCell == ColMap.MaxTotalNoOfCoordinatesPerCell);
                            //Debug.Assert(ColMap.GetBlockLen(cell_j0 + j) == ColMap.MaxTotalNoOfCoordinatesPerCell);
                            //Debug.Assert(ColIdxUpdate.Length == ColMap.GetBlockLen(cell_j0 + j));

                            // mapping is old-->new, i.e. new[IdxUpdate[k]] = old[k] for all k

                            //int i0 = ColMap.GetBlockI0(cell_j0 + j);
                            //int jLoc;
                            //if (j < Jup)
                            //    jLoc = j;
                            //else
                            //    jLoc = LsTrk.GridDat.iParallel.Global2LocalIdx[cell_j0 + j];
                            int i0 = ColMap.GlobalUniqueCoordinateIndex(0, j, 0);
                            //Debug.Assert()

                            int II = ColIdxUpdate.Length;
                            for (int ii = 0; ii < II; ii++)
                            {
                                int iOld = ii + i0;
                                int iNew = ColIdxUpdate[ii] + i0;
                                if (ColIdxUpdate[ii] >= 0)
                                {
                                    if (j < Jup)
                                    {
                                        Debug.Assert(old2NewCols.Count == 0 || old2NewCols[old2NewCols.Count - 1].Item1 < iOld);
                                        old2NewCols.Add(new Tuple <int, int>(iOld, iNew));
                                    }
                                    else
                                    {
                                        old2NewColsExt.Add(new Tuple <int, int>(iOld, iNew));
                                    }
                                }
                            }
                        }
                    }

                    // data conversion
                    int I = old2NewRows.Count;
                    _old2NewRows = new int[I, 2];
                    for (int i = 0; i < I; i++)
                    {
                        var t = old2NewRows[i];
                        _old2NewRows[i, 0] = t.Item1;
                        _old2NewRows[i, 1] = t.Item2;
                    }
                    int J = old2NewCols.Count + old2NewColsExt.Count;
                    old2NewColsExt.Sort((a, b) => a.Item1 - b.Item1);
                    _old2NewCols = new int[J, 2];
                    int ja = 0, jb = 0;
                    for (int j = 0; j < J; j++)
                    {
                        Tuple <int, int> t;
                        if (ja < old2NewCols.Count && jb < old2NewColsExt.Count)
                        {
                            Tuple <int, int> t1, t2;
                            t1 = old2NewCols[ja];
                            t2 = old2NewColsExt[jb];
                            Debug.Assert(t1.Item1 != t2.Item1);
                            if (t1.Item1 < t2.Item1)
                            {
                                t = t1;
                                ja++;
                            }
                            else
                            {
                                t = t2;
                                jb++;
                            }
                        }
                        else if (ja < old2NewCols.Count)
                        {
                            t = old2NewCols[ja];
                            ja++;
                        }
                        else
                        {
                            Debug.Assert(jb < old2NewColsExt.Count);
                            Debug.Assert(ja >= old2NewCols.Count);
                            t = old2NewColsExt[jb];
                            jb++;
                        }


                        _old2NewCols[j, 0] = t.Item1;
                        _old2NewCols[j, 1] = t.Item2;
                        Debug.Assert(j == 0 || _old2NewCols[j - 1, 0] < _old2NewCols[j, 0]);
                    }
                    Debug.Assert(ja == old2NewCols.Count);
                    Debug.Assert(jb == old2NewColsExt.Count);
                }

                // update matrices
                // ===============
                for (int iMtx = 0; iMtx < OpMtx.Length; iMtx++)
                {
                    if (OpMtx[iMtx] != null)
                    {
                        OpMtx[iMtx] = OpMtx[iMtx].RecyclePermute(RowMap, ColMap, _old2NewRows, _old2NewCols);
                    }
                }
            }
        }
예제 #6
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);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }