Пример #1
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);
                    }
                }
            }
        }