/// <summary> /// assigns the cell index of the aggregated cell <em>j</em> to all (fine) grid cells that /// the aggregated cell <em>j</em> consists of. /// </summary> static public void ColorDGField(this AggregationGrid ag, DGField f) { if (!object.ReferenceEquals(f.GridDat, ag.AncestorGrid)) { throw new ArgumentException("mismatch in base grid."); } f.Clear(); int J = ag.iLogicalCells.NoOfLocalUpdatedCells; for (int j = 0; j < J; j++) // loog over logical/aggregate cells { int[] Neighs = ag.iLogicalCells.CellNeighbours[j]; var NeighColors = Neighs.Select(jNeigComp => (int)Math.Round(f.GetMeanValue(ag.iLogicalCells.AggregateCellToParts[jNeigComp][0]))); int iCol = 1; for (iCol = 1; iCol < 2 * J; iCol++) { if (!NeighColors.Contains(iCol)) { break; } } foreach (int jGeom in ag.iLogicalCells.AggregateCellToParts[j]) { f.SetMeanValue(jGeom, iCol); //f.SetMeanValue(jGeom, j); } } }
/// <summary> /// Constructor. /// </summary> /// <param name="aggregationGrid"> /// Aggregation 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(AggregationGrid aggregationGrid, int[][] AggregationCells) { this.aggregationGrid = aggregationGrid; IGridData pGrid = aggregationGrid.ParentGrid.iGridData; InitializeGridData(pGrid, AggregationCells); }
static bool AreReferencesEqual(AggregationGrid A, AggregationGrid B) { //To do: Compare aggregation grid IEqualityComparer <IGrid> parentReferenceComparer = A.ParentGrid.GridSerializationHandler.ReferenceComparer; bool parentReferencesAreEqual = parentReferenceComparer.Equals(A.ParentGrid, B.ParentGrid); return(parentReferencesAreEqual); }
/// <summary> /// Clears (lots of) internal references for this object, to make sure that any attempt to use it leads to an exception. /// </summary> public void Invalidate() { this.m_GeomCellData = null; this.m_LogicalCellData = null; this.m_GeomEdgeData = null; this.m_LogEdgeData = null; this.m_ChefBasis = null; this.m_Parallel = null; this.m_VertexData = null; this.aggregationGrid = null; this.CellPartitioning = null; }
/// <summary> /// creates an initial aggregated grid which is in fact equivalent to <paramref name="g"/> /// </summary> public static AggregationGrid ZeroAggregation(GridData g) { var Cls = g.Cells; int J = Cls.NoOfLocalUpdatedCells; int D = g.SpatialDimension; int[][] AggregateCells = new int[J][]; for (int j = 0; j < J; j++) { AggregateCells[j] = new int[] { j }; } AggregationGrid ret = new AggregationGrid(g, AggregateCells); return(ret); }
/// <summary> /// creates an initial aggregated grid which is in fact equivalent to <paramref name="g"/> /// </summary> public static AggregationGrid ZeroAggregation(IGrid g) { //var Cls = g.Cells; int J = g.CellPartitioning.LocalLength; int D = g.SpatialDimension; int[][] AggregateCells = new int[J][]; for (int j = 0; j < J; j++) { AggregateCells[j] = new int[] { j }; } AggregationGrid ret = new AggregationGrid(g, AggregateCells); return(ret); }
/// <summary> /// Creates a sequence of aggregated grids, suitable for a multigrid algorithm /// </summary> /// <param name="GridDat">original grid</param> /// <param name="MaxDepth">maximum number of refinements</param> /// <param name="skip">A negative number is mapped to some default behavior.</param> /// <returns></returns> public static AggregationGrid[] CreateSequence(GridData GridDat, int MaxDepth = -1, int skip = -1) { using (new FuncTrace()) { int D = GridDat.SpatialDimension; skip = skip > 0 ? skip : D; MaxDepth = MaxDepth >= 0 ? MaxDepth : int.MaxValue; //int cutoff = MaxDepth < 0 ? int.MaxValue : MaxDepth * skip; // create sequence of aggregation multigrid grids and basises // ========================================================== List <AggregationGrid> aggGrids = new List <AggregationGrid>(); aggGrids.Add(ZeroAggregation(GridDat)); while (true) { if (aggGrids.Count >= MaxDepth) { break; } AggregationGrid grid = aggGrids.Last(); //for (int iSkip = 0; iSkip < Math.Max(1, skip); iSkip++) { grid = Coarsen(grid); //} if ((grid.iLogicalCells.NoOfLocalUpdatedCells.MPISum() >= aggGrids.Last().iLogicalCells.NoOfLocalUpdatedCells.MPISum())) { // no more refinement possible break; } aggGrids.Add(grid); #if DEBUG int iLevel = aggGrids.Count - 2; int JFine = aggGrids[iLevel].iLogicalCells.NoOfLocalUpdatedCells; int JCoarse = aggGrids[iLevel + 1].iLogicalCells.NoOfLocalUpdatedCells; // test that the coarse grid has significantly less cells than the fine grid. double dJfine = JFine; double dJcoarse = JCoarse; if (JCoarse >= 10) { Debug.Assert(dJfine * 0.8 >= dJcoarse); } // test the coarse-to-fine map bool[] testMarker = new bool[JFine]; int[][] C2F = aggGrids[iLevel + 1].jCellCoarse2jCellFine; Debug.Assert(C2F.Length == JCoarse); for (int jC = 0; jC < JCoarse; jC++) { foreach (int jF in C2F[jC]) { Debug.Assert(testMarker[jF] == false); testMarker[jF] = true; } } for (int jF = 0; jF < JFine; jF++) { Debug.Assert(testMarker[jF] == true); } // test the fine-to-coarse mapping int[] F2C = aggGrids[iLevel + 1].jCellFine2jCellCoarse; Debug.Assert(F2C.Length == JFine); for (int jF = 0; jF < JFine; jF++) { Debug.Assert(C2F[F2C[jF]].Contains(jF)); } #endif } // return return(aggGrids.ToArray()); } }
/// <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) { InitializeGridData(pGrid, AggregationCells); aggregationGrid = null; }
MultidimensionalArray CA(int _jAgg, int Np) { AggregationGrid 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--) { AggregationGrid 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 AggregationGrid) { basisLevel = ((AggregationGrid)(m_owner.ParentGrid)).m_ChefBasis; } else { basisLevel = null; } } //else { // AggIndex = null; // mgLevel = null; //} } return(R); } }
internal _BasisData(AggregationGrid o) : base(o) { m_owner = o; }
internal LogEdgeData(AggregationGrid __owner) { m_Owner = __owner; }
public AggregationGridDatabaseMethods(AggregationGrid grid) { parentGridHandler = grid.ParentGrid.GridSerializationHandler; this.grid = grid; }