/// <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, AggregationGrid ag, MultidimensionalArray[] inj) : base(xb.NonX_Basis, parentBasis, ag, inj) // { using (new FuncTrace()) { this.XDGBasis = xb; this.XCompositeBasis = new MultidimensionalArray[base.AggGrid.iLogicalCells.NoOfLocalUpdatedCells][]; } }
public XdgAggregationBasis(XDGBasis xb, AggregationGrid ag) : base(xb.NonX_Basis, ag) // { using (new FuncTrace()) { this.XDGBasis = xb; this.XCompositeBasis = new MultidimensionalArray[base.AggGrid.iLogicalCells.NoOfLocalUpdatedCells][]; } }
/// <summary> /// Returns the multigrid blocking. /// </summary> internal override IEnumerable <List <int> > GetBlocking(MultigridOperator op) { AggregationGrid thisLevel = op.Mapping.AggGrid; List <AggregationGrid> blockLevelS = new List <AggregationGrid>(); blockLevelS.Add(thisLevel); MultigridOperator blokOp = op; for (int i = 0; i < this.Depth; i++) { if (blokOp.CoarserLevel == null) { throw new NotSupportedException("Not enough multigrid levels set to support a depth of " + m_Depht + "."); } blokOp = blokOp.CoarserLevel; blockLevelS.Add(blokOp.Mapping.AggGrid); } AggregationGrid blckLevel = blockLevelS.Last(); // the cells of this level form the additive-Schwarz blocks int NoBlocks = blckLevel.iLogicalCells.NoOfLocalUpdatedCells; // each cell of 'blckLevel' forms a block List <int>[] Blocks = NoBlocks.ForLoop(l => new List <int>()); #if DEBUG bool[] checkOnce = new bool[thisLevel.iLogicalCells.NoOfLocalUpdatedCells]; #endif for (int iBlk = 0; iBlk < NoBlocks; iBlk++) { if (blockLevelS.Count == 0) { Blocks[iBlk].Add(iBlk); // the cell itself is the multigrid block (either Depth is 0, or no more MG level available). } else { int[] CoarseCell = blckLevel.jCellCoarse2jCellFine[iBlk]; CollectBlock(Blocks[iBlk], blockLevelS, 0, CoarseCell); } #if DEBUG foreach (int j in Blocks[iBlk]) { Debug.Assert(j >= 0); Debug.Assert(j < checkOnce.Length); Debug.Assert(checkOnce[j] == false); checkOnce[j] = true; } #endif } #if DEBUG for (int j = 0; j < checkOnce.Length; j++) { Debug.Assert(checkOnce[j] == true); } #endif return(Blocks); }
public static void Plot(AggregationGrid grid) { EdgeMask boundaryEdges = EdgeMask.GetFullMask(grid.iGridData, MaskType.Logical); boundaryEdges.SaveToTextFile( "edges.txt", false, (double[] CoordGlobal, int LogicalItemIndex, int GeomItemIndex) => grid.iGridData.iGeomEdges.EdgeTags[GeomItemIndex]); AggregatedTecplot plt1 = new AggregatedTecplot(grid.GridData, 2); Basis b = new Basis(grid.iGridData, 3); SinglePhaseField field = new SinglePhaseField(b, "u"); plt1.PlotFields("grid", 0, field); }
static GridData GetGridData(AggregationGrid ag) { if (ag.ParentGrid is GridData) { return((GridData)ag.ParentGrid); } else if (ag.ParentGrid is AggregationGrid) { return(GetGridData((AggregationGrid)ag.ParentGrid)); } else { throw new NotSupportedException(); } }
void CollectBlock(List <int> output, List <AggregationGrid> blockLevelS, int RecDepth, int[] CoarseCell) { if (RecDepth == blockLevelS.Count - 2) { #if DEBUG foreach (int jFine in CoarseCell) { Debug.Assert(output.Contains(jFine) == false); } #endif output.AddRange(CoarseCell); } else { AggregationGrid blockLevel = blockLevelS[blockLevelS.Count - 2 - RecDepth]; int[][] C2F = blockLevel.jCellCoarse2jCellFine; foreach (int jFine in CoarseCell) { CollectBlock(output, blockLevelS, RecDepth + 1, C2F[jFine]); } } }
public AggregationGridBasis(Basis b, AggregationGrid ag) { using (new FuncTrace()) { if (!object.ReferenceEquals(b.GridDat, GetGridData(ag))) { throw new ArgumentException("mismatch in grid data object."); } this.DGBasis = b; this.AggGrid = ag; int N = b.Length; int JAGG = ag.iLogicalCells.NoOfLocalUpdatedCells; CompositeBasis = new MultidimensionalArray[JAGG]; for (int jAgg = 0; jAgg < JAGG; jAgg++) // loop over agglomerated cells... { var compCell = ag.iLogicalCells.AggregateCellToParts[jAgg]; if (compCell.Length == 1) { CompositeBasis[jAgg] = MultidimensionalArray.Create(1, N, N); for (int n = 0; n < N; n++) { CompositeBasis[jAgg][0, n, n] = 1.0; } } else { // compute extrapolation basis // =========================== int I = compCell.Length - 1; int[,] CellPairs = new int[I, 2]; for (int i = 0; i < I; i++) { CellPairs[i, 0] = compCell[0]; CellPairs[i, 1] = compCell[i + 1]; } var ExpolMtx = MultidimensionalArray.Create(I + 1, N, N); b.GetExtrapolationMatrices(CellPairs, ExpolMtx.ExtractSubArrayShallow(new int[] { 1, 0, 0 }, new int[] { I, N - 1, N - 1 })); for (int n = 0; n < N; n++) { ExpolMtx[0, n, n] = 1.0; } // compute mass matrix // =================== var MassMatrix = MultidimensionalArray.Create(N, N); MassMatrix.Multiply(1.0, ExpolMtx, ExpolMtx, 0.0, "lm", "kim", "kil"); // change to orthonormal basis // =========================== MultidimensionalArray B = MultidimensionalArray.Create(N, N); MassMatrix.SymmetricLDLInversion(B, default(double[])); CompositeBasis[jAgg] = MultidimensionalArray.Create(ExpolMtx.Lengths); CompositeBasis[jAgg].Multiply(1.0, ExpolMtx, B, 0.0, "imn", "imk", "kn"); // check // ===== #if DEBUG MassMatrix.Clear(); for (int k = 0; k <= I; k++) { for (int l = 0; l < N; l++) // over rows of mass matrix ... { for (int m = 0; m < N; m++) // over columns of mass matrix ... { double mass_lm = 0.0; for (int i = 0; i < N; i++) { mass_lm += CompositeBasis[jAgg][k, i, m] * CompositeBasis[jAgg][k, i, l]; } MassMatrix[l, m] += mass_lm; } } } MassMatrix.AccEye(-1.0); Debug.Assert(MassMatrix.InfNorm() < 1.0e-9); #endif } } } }