Beispiel #1
0
        /// <summary>
        /// Updates the XDG component of an aggregation basis according to the new aggomeration.
        /// </summary>
        public static void UpdateXdgAggregationBasis(this AggregationGridBasis[][] MultigridBasis, MultiphaseCellAgglomerator CurrentAgglomeration)
        {
            bool useX = false;
            var  _XdgAggregationBasis = new XdgAggregationBasis[MultigridBasis.Length];

            for (int iLevel = 0; iLevel < MultigridBasis.Length; iLevel++)
            {
                XdgAggregationBasis[] xab = MultigridBasis[iLevel].Where(b => b is XdgAggregationBasis).Select(b => ((XdgAggregationBasis)b)).ToArray();
                if (xab != null && xab.Length > 0)
                {
                    for (int ib = 1; ib < xab.Length; ib++)
                    {
                        if (!(object.ReferenceEquals(xab[ib].DGBasis.GridDat, CurrentAgglomeration.Tracker.GridDat)))
                        {
                            throw new ApplicationException();
                        }
                        if (!object.ReferenceEquals(xab[0], xab[ib]))
                        {
                            throw new ArgumentException("One should only use one XDG aggregation basis per multigrid level.");
                        }
                    }
                    _XdgAggregationBasis[iLevel] = xab[0];
                    useX = true;
                }
            }

            if (useX)
            {
                foreach (var xmgb in _XdgAggregationBasis)
                {
                    xmgb.Update(CurrentAgglomeration);
                }
            }
        }
Beispiel #2
0
 /// <summary>
 /// ctor.
 /// </summary>
 /// <param name="xb">
 /// XDG basis on original grid
 /// </param>
 /// <param name="parentBasis">
 /// basis on parent grid
 /// </param>
 /// <param name="ag">
 /// aggregation grid level.
 /// </param>
 /// <param name="inj">
 /// injection operators.
 /// </param>
 internal XdgAggregationBasis(XDGBasis xb, XdgAggregationBasis parentBasis, AggregationGridData ag, MultidimensionalArray[] inj)
     : base(xb.NonX_Basis, parentBasis, ag, inj) //
 {
     using (new FuncTrace()) {
         this.XDGBasis        = xb;
         this.XCompositeBasis = new MultidimensionalArray[base.AggGrid.iLogicalCells.NoOfLocalUpdatedCells][];
     }
 }
Beispiel #3
0
        /// <summary>
        /// Returns global unique indices which correlate to a certain species and basises.
        /// </summary>
        /// <param name="Fields">
        /// Indices into <see cref="BasisS"/>
        /// </param>
        /// <param name="map">
        /// </param>
        /// <returns>a list of global (over all MPI processes) unique indices.</returns>
        public int[] GetSubvectorIndices(Foundation.XDG.SpeciesId Species, params int[] Fields)
        {
            var map = this.ProblemMapping;

            var _BasisS = map.BasisS.ToArray();

            //XdgAggregationBasis XaggBasis;
            //if(this.AggBasis is XdgAggregationBasis) {
            //    // super-quick and super-dirty fix
            //    XaggBasis = (XdgAggregationBasis)(this.AggBasis);

            //    foreach(var b in _BasisS) {
            //        if(!b.IsSubBasis(XaggBasis.XDGBasis))
            //            throw new ArgumentException();
            //    }
            //} else {
            //    throw new NotSupportedException();
            //}
            XdgAggregationBasis[] XaggBasis = new XdgAggregationBasis[_BasisS.Length];
            for (int iVar = 0; iVar < _BasisS.Length; iVar++)
            {
                Basis b = _BasisS[iVar];

                if (b is BoSSS.Foundation.XDG.XDGBasis)
                {
                    if (!b.IsSubBasis(((XdgAggregationBasis)(this.AggBasis[iVar])).XDGBasis))
                    {
                        throw new ArgumentException();
                    }
                    XaggBasis[iVar] = ((XdgAggregationBasis)(this.AggBasis[iVar]));
                }
                else
                {
                    //if(!b.IsSubBasis(this.AggBasis[iVar].DGBasis))
                    //    throw new ArgumentException();
                    throw new NotSupportedException();
                }
            }

            var          ag         = this.AggGrid;
            int          JAGG       = ag.iLogicalCells.NoOfLocalUpdatedCells;
            Partitioning p          = new Partitioning(JAGG);
            List <int>   R          = new List <int>();
            int          j0_aggCell = p.i0;

            {
                int Nofields = this.m_DgDegree.Length;

                int[] Nfld = new int[Nofields];
                int[] Ofst = new int[Nofields];

                int i0 = this.Partitioning.i0;

                for (int jAgg = 0; jAgg < JAGG; jAgg++)
                {
                    for (int ifld = 0; ifld < Nofields; ifld++)
                    {
                        int pField = this.m_DgDegree[ifld];
                        Nfld[ifld] = this.AggBasis[ifld].GetLength(jAgg, pField);
                        if (ifld > 0)
                        {
                            Ofst[ifld] = Ofst[ifld - 1] + Nfld[ifld - 1];
                        }
                    }
                    int Ncell = Ofst[Nofields - 1] + Nfld[Nofields - 1];

                    for (int i = 0; i < Fields.Length; i++)
                    {
                        int iSpc = XaggBasis[i].GetSpeciesIndex(jAgg, Species);
                        if (iSpc >= 0)
                        {
                            int NoSpc = XaggBasis[i].GetNoOfSpecies(jAgg);

                            int iField = Fields[i];
                            int pField = this.m_DgDegree[iField];

                            int N_iField = Nfld[iField];
                            int N0       = Ofst[iField];

                            int N_Spc = N_iField / NoSpc;
                            Debug.Assert(N_iField % NoSpc == 0);


                            for (int n = 0; n < N_Spc; n++)
                            {
                                int iX = i0 + n + N0 + N_Spc * iSpc;
                                R.Add(iX);
                                Debug.Assert(this.Partitioning.IsInLocalRange(iX));
                                Debug.Assert(iX - j0_aggCell == this.LocalUniqueIndex(iField, jAgg, n + N_Spc * iSpc));
                            }
                        }
                    }
                    i0 += Ncell;
                }
            }

            return(R.ToArray());
        }
Beispiel #4
0
        /// <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);
            }
        }