/// <summary> /// Reload of some operator after before grid-redistribution. /// </summary> /// <param name="Mtx_new"> /// Output, matrix which should be restored. /// </param> /// <param name="Reference"> /// Unique string reference under which data has been stored before grid-redistribution. /// </param> /// <param name="RowMapping"> /// Coordinate mapping to correlate the matrix rows with cells of the computational grid. /// </param> /// <param name="ColMapping"> /// Coordinate mapping to correlate the matrix columns with cells of the computational grid. /// </param> public void RestoreMatrix(BlockMsrMatrix Mtx_new, string Reference, UnsetteledCoordinateMapping RowMapping, UnsetteledCoordinateMapping ColMapping) { int J = m_NewGrid.iLogicalCells.NoOfLocalUpdatedCells; CheckMatrix(Mtx_new, RowMapping, ColMapping, J); BlockMsrMatrix Mtx_old = m_Matrices[Reference].Item3; int[] RowHash = GetDGBasisHash(RowMapping.BasisS); int[] ColHash = GetDGBasisHash(ColMapping.BasisS); if (!ArrayTools.AreEqual(RowHash, m_Matrices[Reference].Item1)) { throw new ApplicationException(); } if (!ArrayTools.AreEqual(ColHash, m_Matrices[Reference].Item2)) { throw new ApplicationException(); } BlockMsrMatrix P_Row = GetRowPermutationMatrix(Mtx_new, Mtx_old, RowHash); BlockMsrMatrix P_Col = GetColPermutationMatrix(Mtx_new, Mtx_old, ColHash); Debug.Assert(Mtx_new._RowPartitioning.LocalNoOfBlocks == m_newJ); Debug.Assert(Mtx_new._ColPartitioning.LocalNoOfBlocks == m_newJ); Debug.Assert(Mtx_old._RowPartitioning.LocalNoOfBlocks == m_oldJ); Debug.Assert(Mtx_old._ColPartitioning.LocalNoOfBlocks == m_oldJ); Debug.Assert(P_Row._RowPartitioning.LocalNoOfBlocks == m_newJ); Debug.Assert(P_Row._ColPartitioning.LocalNoOfBlocks == m_oldJ); Debug.Assert(P_Col._RowPartitioning.LocalNoOfBlocks == m_oldJ); Debug.Assert(P_Col._ColPartitioning.LocalNoOfBlocks == m_newJ); BlockMsrMatrix.Multiply(Mtx_new, BlockMsrMatrix.Multiply(P_Row, Mtx_old), P_Col); }
/// <summary> /// If all exponents and coefficients are the same, two polynomials are equal. /// </summary> /// <param name="obj"></param> /// <returns></returns> public override bool Equals(object obj) { Polynomial other = obj as Polynomial; if (other == null) { return(false); } int L = this.Coeff.Length; int D = this.SpatialDimension; Debug.Assert(this.Coeff.Length == this.Exponents.GetLength(0)); Debug.Assert(other.Coeff.Length == other.Exponents.GetLength(0)); if (L != other.Coeff.Length) { return(false); } if (D != other.SpatialDimension) { return(false); } if (!ArrayTools.AreEqual(this.Exponents, other.Exponents)) { return(false); } if (!ArrayTools.AreEqual(this.Coeff, other.Coeff)) { return(false); } return(true); }
public void UpdateDomain(CellMask cm, bool RestrictToCellMask = true) { var GridDat = m_bInput.GridDat; int J = GridDat.iLogicalCells.NoOfLocalUpdatedCells; this.Domain = cm; int[][] newStencils = new int[J][]; var Mask = cm.GetBitMaskWithExternal(); foreach (int jCell in cm.ItemEnum) { int[] NeighCells, dummy; GridDat.GetCellNeighbours(jCell, GetCellNeighbours_Mode.ViaVertices, out NeighCells, out dummy); if (RestrictToCellMask == true) { NeighCells = NeighCells.Where(j => Mask[j]).ToArray(); } Array.Sort(NeighCells); int[] newStencil = ArrayTools.Cat(new int[] { jCell }, NeighCells); if (this.Stencils == null || this.Stencils[jCell] == null && newStencil.Length > 0 || !ArrayTools.AreEqual(this.Stencils[jCell], newStencil)) { // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // a re-computation of the aggregate cell basis is necessary // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ComputeAggregateBasis(jCell, NeighCells); } newStencils[jCell] = newStencil; } for (int j = 0; j < J; j++) { if (newStencils[j] == null && this.AggregateBasisTrafo[j] != null) { this.AggregateBasisTrafo[j] = null; } Debug.Assert((newStencils[j] == null) == (this.AggregateBasisTrafo[j] == null)); if (newStencils[j] != null) { Debug.Assert(newStencils[j].Length == this.AggregateBasisTrafo[j].GetLength(0)); } } this.Stencils = newStencils; }
/// <summary> /// Updates all columns related to convergence plots /// </summary> public void Update() { // Get all sessions which are successfully terminated // ================================================== var SuccSessions = owner.Sessions.Where(sess => sess.SuccessfulTermination == true).ToArray(); // Group the sessions according to polynomial degree // ================================================= System.Func <int[], int[], bool> eqFunc = (A, B) => ArrayTools.AreEqual(A, B); var comp = eqFunc.ToEqualityComparer(); var SessionGroups = SuccSessions.GroupBy(GetDGDegreeKey, comp).ToArray(); // Spatial convergence for each session group // ========================================== // intermediate result storage // 1st key: Field name // 2nd key: session name // value: error norm var Errors = new Dictionary <string, Dictionary <Guid, double> >(); foreach (IEnumerable <ISessionInfo> spatialSeries in SessionGroups) { if (spatialSeries.Count() <= 1) { continue; } ITimestepInfo[] tsiS = spatialSeries.Select(sess => sess.Timesteps.Last()).ToArray(); // find DG field identifications which are present in _all_ timesteps var commonFieldIds = new HashSet <string>(); foreach (var fi in tsiS[0].FieldInitializers) { string id = fi.Identification; bool containedInOthers = true; foreach (var tsi in tsiS.Skip(1)) { if (tsi.FieldInitializers.Where(fii => fii.Identification == id).Count() <= 0) { containedInOthers = false; } } if (containedInOthers) { commonFieldIds.Add(id); } } string[] fieldIds = commonFieldIds.ToArray(); // compute L2-errors DGFieldComparison.ComputeErrors(fieldIds, tsiS, out double[] hS, out var DOFs, out var ERRs, out var tsiIdS); // record errors foreach (var id in fieldIds) { Dictionary <Guid, double> err_id; if (!Errors.TryGetValue(id, out err_id)) { err_id = new Dictionary <Guid, double>(); Errors.Add(id, err_id); } for (int iGrd = 0; iGrd < hS.Length; iGrd++) { ITimestepInfo tsi = tsiS.Single(t => t.ID == tsiIdS[iGrd]); ISessionInfo sess = tsi.Session; err_id.Add(sess.ID, ERRs[id][iGrd]); } } } // Set L2 error columns in session table // ===================================== foreach (string fieldName in Errors.Keys) { string colName = "L2Error_" + fieldName; if (owner.AdditionalSessionTableColums.ContainsKey(colName)) { owner.AdditionalSessionTableColums.Remove(colName); } var ErrorsCol = Errors[fieldName]; owner.AdditionalSessionTableColums.Add(colName, delegate(ISessionInfo s) { object ret = 0.0; if (ErrorsCol.ContainsKey(s.ID)) { ret = ErrorsCol[s.ID]; } return(ret); }); } }
/// <summary> /// Permutation matrix from an old to a new partitioning. /// </summary> /// <param name="RowPart">Row partitioning, i.e. new data partitioning.</param> /// <param name="ColPart">Column partitioning, i.e. old data partitioning.</param> /// <param name="tau"> /// Permutation from new to old Indices. /// </param> /// <returns></returns> static BlockMsrMatrix GetRowPermutationMatrix(IBlockPartitioning RowPart, IBlockPartitioning ColPart, Permutation tau) { BlockMsrMatrix P = new BlockMsrMatrix(RowPart, ColPart); //if (RowPart.LocalNoOfBlocks != tau.LocalLength) // throw new ArgumentException(); if (RowPart.TotalNoOfBlocks != tau.TotalLength) { throw new ArgumentException(); } if (!RowPart.AllBlockSizesEqual) { throw new NotSupportedException("unable to perform redistribution for variable size blocking (unable to compute offsets for variable size blocking)."); } if (!ColPart.AllBlockSizesEqual) { throw new NotSupportedException("unable to perform redistribution for variable size blocking (unable to compute offsets for variable size blocking)."); } if (RowPart.TotalLength != ColPart.TotalLength) { throw new ArgumentException(); } int IBlock = RowPart.GetBlockLen(RowPart.FirstBlock); if (ColPart.GetBlockLen(ColPart.FirstBlock) != IBlock) { throw new ArgumentException(); } int J = RowPart.LocalNoOfBlocks; long FB = RowPart.FirstBlock; long[] LocalBlockIdxS = J.ForLoop(i => i + FB); long[] TargetBlockIdxS = new long[LocalBlockIdxS.Length]; tau.EvaluatePermutation(LocalBlockIdxS, TargetBlockIdxS); MultidimensionalArray TempBlock = MultidimensionalArray.Create(IBlock, IBlock); for (int jSrc_Loc = 0; jSrc_Loc < J; jSrc_Loc++) // loop over cells resp. local block-indices { int jSrcGlob = jSrc_Loc + RowPart.FirstBlock; // block-row index int jDstGlob = (int)TargetBlockIdxS[jSrc_Loc]; // block-column index Debug.Assert(RowPart.IsLocalBlock(jSrcGlob)); int i0 = RowPart.GetBlockI0(jSrcGlob); int BT = RowPart.GetBlockType(jSrcGlob); int[] _i0 = RowPart.GetSubblk_i0(BT); int[] Len = RowPart.GetSubblkLen(BT); Debug.Assert(IBlock == RowPart.GetBlockLen(jSrcGlob)); int j0 = IBlock * jDstGlob; // this would not work for variable size blocking #if DEBUG if (ColPart.IsLocalBlock(jDstGlob)) { // column block corresponds to some cell Debug.Assert(IBlock == ColPart.GetBlockLen(jDstGlob)); Debug.Assert(j0 == ColPart.GetBlockI0(jDstGlob)); int CBT = ColPart.GetBlockType(jDstGlob); Debug.Assert(ArrayTools.AreEqual(_i0, ColPart.GetSubblk_i0(CBT))); Debug.Assert(ArrayTools.AreEqual(Len, ColPart.GetSubblkLen(CBT))); } #endif Debug.Assert(_i0.Length == Len.Length); int K = _i0.Length; for (int i = 0; i < IBlock; i++) { TempBlock[i, i] = 0.0; } for (int k = 0; k < K; k++) { int A = _i0[k]; int E = Len[k] + A; for (int i = A; i < E; i++) { TempBlock[i, i] = 1; } } P.AccBlock(i0, j0, 1.0, TempBlock); } return(P); }