예제 #1
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="pGrid">
        /// Parent grid.
        /// </param>
        /// <param name="AggregationCells">
        /// Coarse cells which build up the fine cells.
        /// - 1st index: coarse (i.e. this) grid cell index
        /// - 2nd index: enumeration
        /// - content: local cell index into the parent grid <paramref name="pGrid"/>.
        /// </param>
        public AggregationGridData(IGridData pGrid, int[][] AggregationCells)
        {
            ParentGrid = pGrid;

            int JlocFine  = pGrid.iLogicalCells.NoOfLocalUpdatedCells;
            int JElocFine = pGrid.iLogicalCells.Count;

            m_GeomCellData = new GeomCellData()
            {
                m_Owner = this
            };
            m_LogicalCellData = new LogicalCellData()
            {
                m_Owner = this
            };
            m_GeomEdgeData = new GeomEdgeData()
            {
                m_Owner = this
            };
            m_LogEdgeData = new LogEdgeData(this);
            m_VertexData  = new VertexData();
            m_Parallel    = new Parallelization()
            {
                m_owner = this
            };

            CellPartitioning = new Partitioning(AggregationCells.Length, pGrid.CellPartitioning.MPI_Comm);

            int j0Coarse = CellPartitioning.i0;

            BuildNeighborship(AggregationCells);
            DefineCellParts();
            CollectEdges();
            m_GeomEdgeData.CollectGeomEdges2logCells();

            m_ChefBasis = new _BasisData(this);
        }
            MultidimensionalArray CA(int _jAgg, int Np)
            {
                AggregationGridData ag = this.m_owner;
                var compCell           = ag.iLogicalCells.AggregateCellToParts[_jAgg];
                int thisMgLevel        = ag.MgLevel;


                var scl = m_owner.AncestorGrid.ChefBasis.Scaling;


                var R = MultidimensionalArray.Create(compCell.Length, Np, Np);

                for (int i = 0; i < compCell.Length; i++)
                {
                    int jG = compCell[i];
                    if (!m_owner.AncestorGrid.Cells.IsCellAffineLinear(jG))
                    {
                        throw new NotImplementedException("nonlin cell -- todo");
                    }
                    for (int n = 0; n < Np; n++)
                    {
                        R[i, n, n] = scl[jG];
                    }
                }

#if DEBUG
                bool[] btouch = new bool[compCell.Length];
#endif

                int[]      AggIndex   = new int[] { _jAgg };
                _BasisData basisLevel = this;
                for (int mgLevelIdx = thisMgLevel; mgLevelIdx >= 0; mgLevelIdx--)
                {
                    AggregationGridData mgLevel          = basisLevel.m_owner;
                    int[][]             agg2part_parrent = mgLevel.ParentGrid.iLogicalCells.AggregateCellToParts;
#if DEBUG
                    btouch.Clear();
#endif

                    foreach (int jAgg in AggIndex)
                    {
                        //MultidimensionalArray Inj_j;
                        //if (mgLevelIdx > 0) {
                        var Inj_j = basisLevel.Injectors[jAgg];
                        //} else {
                        //    Inj_j = MultidimensionalArray.Create(1, Np, Np);
                        //    for (int n = 0; n < Np; n++) {
                        //        m_CompositeBasis[jAgg][0, n, n] = 1.0;
                        //    }
                        //}


                        int[] FineAgg = mgLevel.jCellCoarse2jCellFine[jAgg];
                        Debug.Assert(FineAgg.Length == Inj_j.GetLength(0));

                        for (int iSrc = 0; iSrc < FineAgg.Length; iSrc++)   // loop over finer level cells
                        {
                            int jAgg_fine = FineAgg[iSrc];
                            // Inj_j[iSrc,-,-] is injector
                            //   from cell 'jAgg' on level 'mgLevelIdx'      (coarse level)
                            //   to cell 'jAgg_fine' on level 'mgLevelIdx - 1' (fine level)

                            var Inj_j_iSrc = Inj_j.ExtractSubArrayShallow(iSrc, -1, -1);

                            int[] TargCells;// = mgLevel.ParentGrid.iLogicalCells.AggregateCellToParts[jAgg_fine];
                            if (agg2part_parrent != null)
                            {
                                TargCells = agg2part_parrent[jAgg_fine];
                            }
                            else
                            {
                                TargCells = new int[] { jAgg_fine }
                            };

                            foreach (int j in TargCells)
                            {
                                int iTarg = Array.IndexOf(compCell, j);
                                if (iTarg < 0)
                                {
                                    throw new ApplicationException("error in alg");
                                }
#if DEBUG
                                if (btouch[iTarg] == true)
                                {
                                    throw new ApplicationException();
                                }
                                btouch[iTarg] = true;
#endif
                                var R_iTarg = R.ExtractSubArrayShallow(iTarg, -1, -1);

                                R_iTarg.Multiply(1.0, Inj_j_iSrc, R_iTarg.CloneAs(), 0.0, "nm", "nk", "km");

                                //if (thisMgLevel == 1 && Np == 10) {
                                //    var check = MultidimensionalArray.Create(Np, Np);
                                //    check.GEMM(1.0, R_iTarg, R_iTarg.Transpose(), 0.0);
                                //    check.AccEye(-1.0);
                                //    var bla = check.InfNorm();
                                //    Console.WriteLine("Check norm: " + bla);
                                //}
                            }
                        }
                    }


                    // Rekursions-Scheisse:
                    // - - - - - - - - - - -
                    //if (mgLevelIdx > 0) {
                    {
                        List <int> nextAggIndex = new List <int>();
                        foreach (int jAgg in AggIndex)
                        {
                            int[] NextLevel = mgLevel.jCellCoarse2jCellFine[jAgg];
#if DEBUG
                            foreach (int i in NextLevel)
                            {
                                Debug.Assert(nextAggIndex.Contains(i) == false);
                            }
#endif
                            nextAggIndex.AddRange(NextLevel);
                        }
                        AggIndex = nextAggIndex.ToArray();
                        if (m_owner.ParentGrid is AggregationGridData)
                        {
                            basisLevel = ((AggregationGridData)(m_owner.ParentGrid)).m_ChefBasis;
                        }
                        else
                        {
                            basisLevel = null;
                        }
                    }
                    //else {
                    //    AggIndex = null;
                    //    mgLevel = null;
                    //}
                }

                return(R);
            }
        }