コード例 #1
0
ファイル: MultigridMapping.cs プロジェクト: xyuan/BoSSS
        /// <summary>
        /// Prolongation or Restriction from *any* other level to this level.
        /// </summary>
        /// <param name="otherLevel">
        /// Other level, from which one wants to prolongate/restrict.
        /// </param>
        /// <returns>
        /// A matrix, where
        /// - row correspond to this mapping
        /// - columns correspond to <paramref name="otherLevel"/>
        /// If the other level is coarser, this is a prolongation; if the other level is finer, it is the restriction in the L2-sense,
        /// for standard DG; for XDG, in some other norm  determined by the cut-cell shape.
        /// </returns>
        public BlockMsrMatrix FromOtherLevelMatrix(MultigridMapping otherLevel)
        {
            using (new FuncTrace()) {
                BlockMsrMatrix PrlgMtx;
                {
                    PrlgMtx = new BlockMsrMatrix(otherLevel, otherLevel.ProblemMapping);
                    for (int ifld = 0; ifld < otherLevel.AggBasis.Length; ifld++)
                    {
                        otherLevel.AggBasis[ifld].GetRestrictionMatrix(PrlgMtx, otherLevel, ifld);  // prolongate from the other level to the full grid
                    }
                    PrlgMtx = PrlgMtx.Transpose();
                }

                BlockMsrMatrix RestMtx;
                {
                    RestMtx = new BlockMsrMatrix(this, this.ProblemMapping);
                    for (int ifld = 0; ifld < this.AggBasis.Length; ifld++)
                    {
                        this.AggBasis[ifld].GetRestrictionMatrix(RestMtx, this, ifld);  //     ... and restrict to this level
                    }
                }
                var result = BlockMsrMatrix.Multiply(RestMtx, PrlgMtx);
#if DEBUG
                {
                    var            resultT = result.Transpose();
                    BlockMsrMatrix ShoudBeId;
                    if (result.RowPartitioning.TotalLength < result.ColPartition.TotalLength)
                    {
                        ShoudBeId = BlockMsrMatrix.Multiply(result, resultT);
                    }
                    else
                    {
                        ShoudBeId = BlockMsrMatrix.Multiply(resultT, result);
                    }

                    ShoudBeId.AccEyeSp(-1.0);

                    double ShouldBeID_Norm = ShoudBeId.InfNorm();
                    Debug.Assert(ShouldBeID_Norm < 1.0e-8);
                    //Console.WriteLine("Id norm {0} \t (level {1})", ShouldBeID_Norm, this.AggGrid.MgLevel);
                }
#endif
                return(result);
            }
        }
コード例 #2
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];
                        }
                    }
                }
            }
        }
コード例 #3
0
ファイル: XdgAggregationBasis.cs プロジェクト: leyel/BoSSS
        public override void GetRestrictionMatrix(BlockMsrMatrix RST, MultigridMapping mgMap, int iF)
        {
            if (!object.ReferenceEquals(mgMap.AggBasis[iF], this))
            {
                throw new ArgumentException();
            }

            //MsrMatrix RST = new MsrMatrix(mgMap.Partitioning, mgMap.ProblemMapping);
            int JAGG = this.AggGrid.iLogicalCells.NoOfLocalUpdatedCells;

            int[] degrees = mgMap.DgDegree;
            int   NoFld   = degrees.Length;

            int N_rest; // = new int[NoFld];
            int N_full; // = new int[NoFld];
            {
                BoSSS.Foundation.Basis b   = mgMap.ProblemMapping.BasisS[iF];
                BoSSS.Foundation.Basis NxB = (b is BoSSS.Foundation.XDG.XDGBasis) ? ((BoSSS.Foundation.XDG.XDGBasis)b).NonX_Basis : b;
                N_rest = NxB.Polynomials[0].Where(poly => poly.AbsoluteDegree <= degrees[iF]).Count();
                N_full = NxB.Length;
            }


            int mgMap_Offset = mgMap.Partitioning.i0;

            for (int jAgg = 0; jAgg < JAGG; jAgg++)
            {
                int[] AgCell = this.AggGrid.iLogicalCells.AggregateCellToParts[jAgg];
                int   K      = AgCell.Length;


                int NoSpc_Agg = this.NoOfSpecies[jAgg];                  // number of species in aggregate cell
                for (int iSpc_Agg = 0; iSpc_Agg < NoSpc_Agg; iSpc_Agg++) // loop over all species in aggregate cell
                {
                    {                                                    // loop over DG fields in the mapping
                        int NROW = N_rest;
                        int NCOL = N_full;
                        Debug.Assert(mgMap.AggBasis[iF].GetLength(jAgg, degrees[iF]) == N_rest * NoSpc_Agg);
                        int i0Agg_Loc = mgMap.LocalUniqueIndex(iF, jAgg, N_rest * iSpc_Agg);
                        int i0Agg     = i0Agg_Loc + mgMap_Offset;
                        Debug.Assert(i0Agg >= mgMap.Partitioning.i0);
                        Debug.Assert(i0Agg < mgMap.Partitioning.iE);

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


                            // default branch:
                            // use restriction/prolongation from un-cut basis
                            // +++++++++++++++++++++++++++++++++++++++++++++

                            MultidimensionalArray Trf = base.CompositeBasis[jAgg];

                            for (int k = 0; k < K; k++)  // loop over the cells which form the aggregated cell...
                            {
                                int jCell  = AgCell[k];
                                int i0Full = mgMap.ProblemMapping.GlobalUniqueCoordinateIndex(iF, jCell, 0);
                                var Block  = Trf.ExtractSubArrayShallow(k, -1, -1);


                                for (int nRow = 0; nRow < NROW; nRow++)
                                {
                                    for (int nCol = 0; nCol < NCOL; nCol++)
                                    {
                                        RST[i0Agg + nRow, i0Full + nCol] = Block[nCol, nRow];
                                    }
                                }
                            }
                        }
                        else
                        {
                            int NoSpc = this.NoOfSpecies[jAgg];
                            int[,] sim = SpeciesIndexMapping[jAgg];
                            Debug.Assert(sim.GetLength(0) == NoSpc);
                            Debug.Assert(sim.GetLength(1) == K);

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

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

                                if (iSpcBase < 0)
                                {
                                    //for(int n = 0; n < N; n++)
                                    //    FulCoords[k, n] = 0;
                                }
                                else
                                {
                                    int i0Full = mgMap.ProblemMapping.GlobalUniqueCoordinateIndex(iF, jCell, iSpcBase * N_full);
                                    var Block  = Trf.ExtractSubArrayShallow(k, -1, -1);

                                    for (int nRow = 0; nRow < NROW; nRow++)
                                    {
                                        for (int nCol = 0; nCol < NCOL; nCol++)
                                        {
                                            RST[i0Agg + nRow, i0Full + nCol] = Block[nCol, nRow];
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            //return RST;
        }
コード例 #4
0
ファイル: MultigridMapping.cs プロジェクト: xyuan/BoSSS
        /// <summary>
        /// Prolongation/Injection operator to finer grid level.
        /// </summary>
        public BlockMsrMatrix GetProlongationOperator(MultigridMapping finerLevel)
        {
            using (new FuncTrace()) {
                // Argument checking
                // =================

                if (!object.ReferenceEquals(finerLevel.AggGrid, this.AggGrid.ParentGrid))
                {
                    throw new ArgumentException("Only prolongation/injection to next level is supported.");
                }
                if (finerLevel.AggBasis.Length != this.AggBasis.Length)
                {
                    throw new ArgumentException("");
                }
                int NoOfVar = this.AggBasis.Length;

                MultidimensionalArray[][] InjOp = new MultidimensionalArray[NoOfVar][];
                AggregationGridBasis[]    B     = new AggregationGridBasis[NoOfVar];
                bool[] useX        = new bool[NoOfVar];
                int[]  DegreeS     = new int[NoOfVar];
                int[]  DegreeSfine = new int[NoOfVar];

                for (int iVar = 0; iVar < NoOfVar; iVar++)
                {
                    InjOp[iVar]       = this.AggBasis[iVar].InjectionOperator;
                    B[iVar]           = AggBasis[iVar];
                    DegreeS[iVar]     = this.DgDegree[iVar];
                    DegreeSfine[iVar] = finerLevel.DgDegree[iVar];
                    if (DegreeSfine[iVar] < DegreeS[iVar])
                    {
                        throw new ArgumentException("Lower DG degree on finer grid is not supported by this method ");
                    }
                    useX[iVar] = this.AggBasis[iVar] is XdgAggregationBasis;
                    if (useX[iVar] != (finerLevel.AggBasis[iVar] is XdgAggregationBasis))
                    {
                        throw new ArgumentException("XDG / DG mismatch between this and finer level for " + iVar + "-th variable.");
                    }
                }

                XdgAggregationBasis XB  = null;
                XdgAggregationBasis XBf = null;
                int[][,] spcIdxMap = null;
                SpeciesId[][] spc = null;
                //SpeciesId[][] spcf = null;
                for (int iVar = 0; iVar < NoOfVar; iVar++)
                {
                    if (useX[iVar])
                    {
                        XB        = (XdgAggregationBasis)(B[iVar]);
                        XBf       = (XdgAggregationBasis)(finerLevel.AggBasis[iVar]);
                        spcIdxMap = XB.SpeciesIndexMapping;
                        spc       = XB.AggCellsSpecies;
                        //spcf = XBf.AggCellsSpecies;
                        break;
                    }
                }

                int[] Np      = this.AggBasis[0].GetNp();
                int[] Np_fine = finerLevel.AggBasis[0].GetNp();



                // create matrix
                // =============

                // init retval
                var PrlgMtx = new BlockMsrMatrix(finerLevel, this);

                int[][] C2F     = this.AggGrid.jCellCoarse2jCellFine;
                int     JCoarse = this.AggGrid.iLogicalCells.NoOfLocalUpdatedCells;
                //Debug.Assert((JCoarse == C2F.Length) || ());
                for (int jc = 0; jc < JCoarse; jc++)  // loop over coarse cells...
                {
                    int[] AggCell = C2F[jc];
                    int   I       = AggCell.Length;

                    for (int iVar = 0; iVar < NoOfVar; iVar++)
                    {
                        int DgDeg  = DegreeS[iVar];
                        int DgDegF = DegreeSfine[iVar];
                        MultidimensionalArray Inj_iVar_jc = InjOp[iVar][jc];
                        Debug.Assert(Inj_iVar_jc.GetLength(0) == I);

                        bool useX_iVar = false;
                        if (useX[iVar])
                        {
                            if (spcIdxMap[jc] != null)
                            {
                                useX_iVar = true;
                            }
                        }


                        if (useX_iVar)
                        {
                            //throw new NotImplementedException("todo");

                            int NoOfSpc = XB.GetNoOfSpecies(jc);
                            int Np_col  = Np[DgDeg];
                            Debug.Assert(Np_col * NoOfSpc == B[iVar].GetLength(jc, DgDeg));

                            for (int iSpc = 0; iSpc < NoOfSpc; iSpc++)  // loop over species
                            {
                                SpeciesId spc_jc_i = spc[jc][iSpc];

                                int Col0 = this.GlobalUniqueIndex(iVar, jc, Np_col * iSpc);


                                for (int i = 0; i < I; i++)   // loop over finer cells
                                {
                                    int jf = AggCell[i];

                                    int iSpc_Row = XBf.GetSpeciesIndex(jf, spc_jc_i);
                                    if (iSpc_Row < 0)
                                    {
                                        // nothing to do
                                        continue;
                                    }

                                    int Np_row = Np_fine[DgDegF];
                                    Debug.Assert(Np_row * XBf.GetNoOfSpecies(jf) == finerLevel.AggBasis[iVar].GetLength(jf, DgDegF));

                                    int Row0 = finerLevel.GlobalUniqueIndex(iVar, jf, Np_row * iSpc_Row);

                                    //if(Row0 <= 12 &&  12 < Row0 + Np_row) {
                                    //    if(Col0 <= 3 && 3 < Col0 + Np_col) {
                                    //        Debugger.Break();
                                    //    }
                                    //}
                                    PrlgMtx.AccBlock(Row0, Col0, 1.0, Inj_iVar_jc.ExtractSubArrayShallow(new[] { i, 0, 0 }, new[] { i - 1, Np_row - 1, Np_col - 1 }));
                                }
                            }
                        }
                        else
                        {
                            // ++++++++++++++++++
                            // standard DG branch
                            // ++++++++++++++++++

                            int Np_col = Np[DgDeg];
                            Debug.Assert(Np_col == B[iVar].GetLength(jc, DgDeg));
                            int Col0 = this.GlobalUniqueIndex(iVar, jc, 0);

                            for (int i = 0; i < I; i++)  // loop over finer cells
                            {
                                int jf     = AggCell[i];
                                int Np_row = Np_fine[DgDegF];
                                Debug.Assert(Np_row == finerLevel.AggBasis[iVar].GetLength(jf, DgDegF));

                                int Row0 = finerLevel.GlobalUniqueIndex(iVar, jf, 0);

                                PrlgMtx.AccBlock(Row0, Col0, 1.0, Inj_iVar_jc.ExtractSubArrayShallow(new[] { i, 0, 0 }, new[] { i - 1, Np_row - 1, Np_col - 1 }));
                                //if(Row0 <= 12 &&  12 < Row0 + Np_row) {
                                //        if(Col0 <= 3 && 3 < Col0 + Np_col) {
                                //            Debugger.Break();
                                //        }
                                //    }
                            }
                        }
                    }
                }


                // return
                // ======

                return(PrlgMtx);
            }
        }
コード例 #5
0
ファイル: MPIexchange.cs プロジェクト: xyuan/BoSSS
        /// <summary>
        /// ctor.
        /// </summary>
        public MPIexchange(MultigridMapping map, T vector)
        {
            // misc init
            // =========

            IGridData master = map.AggGrid;
            int       J      = master.iLogicalCells.Count;

            if (vector.Count != map.LocalLength)
            {
                throw new ArgumentException("wrong length of input vector.");
            }


            m_vector = vector;
            m_master = master;
            m_map    = map;

            var Para    = m_master.iParallel;
            var rvcProc = Para.ProcessesToReceiveFrom;
            var sndProc = Para.ProcessesToSendTo;

            rqst = new MPI_Request[sndProc.Length + rvcProc.Length];

            // allocate send buffers
            // =====================
            {
                SendBuffers = new double[sndProc.Length][];
                for (int i = 0; i < SendBuffers.Length; i++)
                {
                    int p = sndProc[i];

                    // compute length of send list
                    int L = 0;
                    foreach (int jCell in Para.SendCommLists[p])
                    {
                        Debug.Assert(map.IsLocalBlock(jCell + map.FirstBlock));
                        Debug.Assert(map.GetLength(jCell) == map.GetBlockLen(jCell + map.FirstBlock));
                        L += map.GetLength(jCell);
                    }

                    // alloc send buffer
                    SendBuffers[i] = new double[L];
                }
                SendBufferPin = new GCHandle[sndProc.Length];
            }

            // allocate receive buffers
            // ========================

            {
                int totL = 0;
                RcvBuffer = new double[rvcProc.Length][];
                for (int i = 0; i < RcvBuffer.Length; i++)
                {
                    int p = rvcProc[i];

                    // compute length of receive list
                    int L  = 0;
                    int J0 = Para.RcvCommListsInsertIndex[p];
                    int JE = Para.RcvCommListsNoOfItems[p] + J0;
                    for (int jCell = J0; jCell < JE; jCell++)
                    {
                        Debug.Assert(jCell >= map.LocalNoOfBlocks);
                        L += map.GetLength(jCell);
                    }
                    totL += L;

                    // alloc internal receive buffer
                    RcvBuffer[i] = new double[L];
                }
                RcvBufferPin = new GCHandle[RcvBuffer.Length];

                m_Vector_Ext = new double[totL];
            }
        }