public static void CellwiseSubSelection( [Values(SelectionType.all_combined, SelectionType.degrees, SelectionType.species, SelectionType.variables)] SelectionType SType ) { Utils.TestInit((int)SType); Console.WriteLine("SubSelection({0})", SType); //Arrange --- extracts entries of matrix according to hardcoded selection int DGdegree = 2; int GridResolution = 4; var mgo = Utils.CreateTestMGOperator(XDGusage.all, DGdegree, MatrixShape.full_var_spec, GridResolution); int sampleCellA = Utils.GetIdxOfFirstBlockWith(mgo.Mapping, false); //1 species int sampleCellB = Utils.GetIdxOfFirstBlockWith(mgo.Mapping, true); //2 species BlockMsrMatrix compA = Utils.GetCellCompMatrix(SType, mgo, sampleCellA); BlockMsrMatrix compB = Utils.GetCellCompMatrix(SType, mgo, sampleCellB); int iBlock = sampleCellB + mgo.Mapping.AggGrid.CellPartitioning.i0; int i0 = mgo.Mapping.GetBlockI0(iBlock); var block = MultidimensionalArray.Create(mgo.Mapping.GetBlockLen(iBlock), mgo.Mapping.GetBlockLen(iBlock)); mgo.OperatorMatrix.ReadBlock(i0, i0, block); //Arrange --- setup masking, which correspond to hardcoded SubBlockSelector sbsA = new SubBlockSelector(mgo.Mapping); sbsA.GetDefaultSelection(SType, sampleCellA); // single spec BlockMask maskA = new BlockMask(sbsA, null); SubBlockSelector sbsB = new SubBlockSelector(mgo.Mapping); sbsB.GetDefaultSelection(SType, sampleCellB); // double spec BlockMask maskB = new BlockMask(sbsB, null); //Arrange --- some time measurement Stopwatch stw = new Stopwatch(); stw.Reset(); //Act --- subblock extraction stw.Start(); var blocksA = maskA.GetDiagonalBlocks(mgo.OperatorMatrix, false, false); var blocksB = maskB.GetDiagonalBlocks(mgo.OperatorMatrix, false, false); stw.Stop(); //Assert --- Assert.IsTrue(blocksA.Length == 1); Assert.IsTrue(blocksB.Length == 1); Assert.IsTrue(compA.RowPartitioning.LocalLength == blocksA[0].GetLength(0)); Assert.IsTrue(compB.RowPartitioning.LocalLength == blocksB[0].GetLength(0)); //Assert --- compare masking of single spec cell Debug.Assert(compA.InfNorm() != 0.0); compA.AccBlock(0, 0, -1.0, blocksA[0]); Assert.IsTrue(compA.InfNorm() == 0.0); //Assert --- compare masking of double spec cell Debug.Assert(compB.InfNorm() != 0.0); compB.AccBlock(0, 0, -1.0, blocksB[0]); Assert.IsTrue(compB.InfNorm() == 0.0, String.Format("proc{0}: not fulfilled at block {1}", mgo.Mapping.MpiRank, sampleCellB)); }
/// <summary> /// Local condition number for the block formed by each cell. /// </summary> /// <returns> /// one value per cell: /// - index: local cell index /// - content: condition number (one norm) of the local stencil /// </returns> public double[] BlockCondNumbers() { int J = m_map.LocalNoOfBlocks; Debug.Assert(J == m_map.GridDat.iLogicalCells.NoOfLocalUpdatedCells); var Mtx = m_MultigridOp.OperatorMatrix; Debug.Assert(Mtx._ColPartitioning.LocalNoOfBlocks == J); Debug.Assert(Mtx._RowPartitioning.LocalNoOfBlocks == J); var Sel = new SubBlockSelector(m_MultigridOp.Mapping); Sel.VariableSelector(this.VarGroup); var Mask = new BlockMask(Sel); MultidimensionalArray[] Blocks = Mask.GetDiagonalBlocks(Mtx, ignoreSpecCoupling: false, ignoreVarCoupling: false); Debug.Assert(Blocks.Length == J); double[] BCN = new double[J]; for (int j = 0; j < J; j++) { #if DEBUG int N = this.VarGroup.Sum(iVar => m_MultigridOp.Mapping.AggBasis[iVar].GetLength(j, m_MultigridOp.Degrees[iVar])); Debug.Assert(Blocks[j].NoOfCols == N); Debug.Assert(Blocks[j].NoOfRows == N); int i0 = m_MultigridOp.Mapping.GlobalUniqueIndex(this.VarGroup.Min(), j, 0); Debug.Assert(Mtx[i0, i0] == Blocks[j][0, 0]); #endif BCN[j] = Blocks[j].Cond(); } return(BCN); }
public static void SubBlockExtractionWithCoupling( [Values(XDGusage.none, XDGusage.all)] XDGusage UseXdg, [Values(2)] int DGOrder, [Values(MatrixShape.diagonal, MatrixShape.diagonal_var, MatrixShape.diagonal_spec, MatrixShape.diagonal_var_spec)] MatrixShape MShape ) { Utils.TestInit((int)UseXdg, DGOrder, (int)MShape); Console.WriteLine("ExtractDiagonalBlocks({0},{1},{2})", UseXdg, DGOrder, MShape); //Arrange --- get multigridoperator MultigridOperator MGOp = Utils.CreateTestMGOperator(UseXdg, DGOrder, MShape); BlockMsrMatrix M = MGOp.OperatorMatrix; MultigridMapping map = MGOp.Mapping; //Arrange --- setup masking SubBlockSelector SBS = new SubBlockSelector(map); BlockMask mask = new BlockMask(SBS, null); bool[] coupling = Utils.SetCoupling(MShape); //Arrange --- some time measurement Stopwatch stw = new Stopwatch(); stw.Reset(); //Arrange --- setup auxiliary matrix //this will show us if more is extracted, than it should ... var Mprep = new BlockMsrMatrix(map); Mprep.Acc(1.0, M); //Act --- diagonal subblock extraction stw.Start(); var blocks = mask.GetDiagonalBlocks(Mprep, coupling[0], coupling[1]); stw.Stop(); //Assert --- all diagonal blocks are extracted Assert.IsTrue(blocks.Length == map.LocalNoOfBlocks); for (int i = 0; i < map.LocalNoOfBlocks; i++) { //Arrange --- get ith diagonal block of M: M_i int iBlock = i + map.AggGrid.CellPartitioning.i0; int L = map.GetBlockLen(iBlock); int i0 = map.GetBlockI0(iBlock); var Mblock = MultidimensionalArray.Create(L, L); M.ReadBlock(i0, i0, Mblock); //Act --- M_i-Mones_i Mblock.Acc(-1.0, blocks[i]); //Assert --- are extracted blocks and Assert.IsTrue(Mblock.InfNorm() == 0.0, String.Format("infNorm of block {0} neq 0!", i)); } //BlockMsrMatrix all1; //all1.SetAll(1); //Generate broken diagonal matrix, die zur Maske passt: M //M+all1=M_prep //Wende Extraction auf M_prep an, Man sollte nun M bekommen //Test: M_prep-extract(M_prep)=all1 //Test-crit: Result.SumEntries=DOF^2 oder Result.Max()==Result.Min()==1 //oder (besser) //Test: M-extract(M_prep)=zeros //Test-crit: Result.InfNorm()==0 //Der Test kann für ExtractSubMatrix mit ignore coupling wiederholt werden //eventuell: Testmatrix finden mit brauchbaren Nebendiagonalen für einen Fall //Was wird getestet: funktioniert ignorecoupling richtig? }
public static void VectorCellwiseOperation( [Values(XDGusage.none, XDGusage.all)] XDGusage UseXdg, [Values(2)] int DGOrder, [Values(MatrixShape.diagonal_var_spec, MatrixShape.diagonal_spec, MatrixShape.diagonal_var, MatrixShape.diagonal)] MatrixShape MShape, [Values(4)] int Res ) { Utils.TestInit((int)UseXdg, DGOrder, (int)MShape); Console.WriteLine("SubMatrixIgnoreCoupling({0},{1},{2})", UseXdg, DGOrder, MShape); //Arrange --- create test matrix, MG mapping MultigridOperator mgo = Utils.CreateTestMGOperator(UseXdg, DGOrder, MShape, Res); MultigridMapping map = mgo.Mapping; BlockMsrMatrix M = mgo.OperatorMatrix; //Arrange --- masking and subblock extraction of external cells var sbs = new SubBlockSelector(map); sbs.AllExternalCellsSelection(); var M_ext = BlockMask.GetAllExternalRows(map, M); var mask = new BlockMask(sbs, M_ext); var eblocks = mask.GetDiagonalBlocks(M, false, false); //Dictionary<int, int[]> Didc = Utils.GetDictOfAllExtCellIdc(map); //Arrange --- generate rnd vector and distribute it double[] vec = new double[map.LocalLength]; vec = Utils.GetRandomVector(map.LocalLength); var vec_ex = new MPIexchange <double[]>(map, vec); vec_ex.TransceiveStartImReturn(); vec_ex.TransceiveFinish(0.0); Debug.Assert(vec_ex.Vector_Ext.L2Norm() != 0); //Arrange --- stopwatch var stw = new Stopwatch(); stw.Reset(); //Arrange --- get extended (loc+external cells) vector double[] Vec_ext = new double[vec.Length + vec_ex.Vector_Ext.Length]; mask.AccSubVec(vec_ex.Vector_Ext, Vec_ext); bool test = eblocks.Length.MPIEquals(); Debug.Assert(test); //Act --- calculate blockwise result: M_i*vec_i=Res_i double[] Res_ext = new double[Vec_ext.Length]; stw.Start(); for (int i = 0; i < eblocks.Length; i++) { //int iBlock = i + map.AggGrid.iLogicalCells.NoOfLocalUpdatedCells; double[] vec_i = mask.GetSubVecOfCell(Vec_ext, i); double[] Res_i = new double[vec_i.Length]; eblocks[i].MatVecMul(1.0, vec_i, 0.0, Res_i); mask.AccSubVecOfCell(Res_i, i, Res_ext); if (map.MpiRank == 0) { eblocks[i].ConvertToMsr().SaveToTextFileSparseDebug(String.Format("block_{0}_{1}", i, map.MpiRank)); vec_i.SaveToTextFileDebug(String.Format("vec_{0}_{1}", i, map.MpiRank)); Res_i.SaveToTextFileDebug(String.Format("Res_{0}_{1}", i, map.MpiRank)); } } stw.Stop(); //Act --- project Res_i onto Res_g and Res_g=M_ext*vec_ext-Res_g double[] Res_g = mask.GetSubVec(Res_ext); var qM_ext = M_ext.ConvertToQuadraticBMsr(mask.GlobalIList_External.ToArray(), false); qM_ext.SpMV(1.0, vec_ex.Vector_Ext, -1.0, Res_g); if (map.MpiRank == 0) { vec_ex.Vector_Ext.SaveToTextFileDebug("vec_g"); Res_g.SaveToTextFileDebug("Res_g"); M_ext.SaveToTextFileSparseDebug("M_ext"); qM_ext.SaveToTextFileSparseDebug("qM_ext"); } //Assert --- |Res_g| should be at least near to zero Assert.IsTrue(Res_g.L2Norm() == 0.0); }
public static void SubBlockExtraction( [Values(XDGusage.none, XDGusage.all)] XDGusage UseXdg, [Values(2)] int DGOrder, [Values(MatrixShape.diagonal_var_spec, MatrixShape.diagonal_spec, MatrixShape.diagonal_var, MatrixShape.diagonal)] MatrixShape MShape, [Values(4)] int Res ) { Utils.TestInit((int)UseXdg, DGOrder, (int)MShape); Console.WriteLine("SubMatrixIgnoreCoupling({0},{1},{2})", UseXdg, DGOrder, MShape); //Arrange --- create test matrix and MG mapping MultigridOperator mgo = Utils.CreateTestMGOperator(UseXdg, DGOrder, MShape, Res); MultigridMapping map = mgo.Mapping; BlockMsrMatrix M = mgo.OperatorMatrix; //Arrange --- masking of all external cells var sbs = new SubBlockSelector(map); sbs.AllExternalCellsSelection(); var M_ext = BlockMask.GetAllExternalRows(map, M); var mask = new BlockMask(sbs, M_ext); //bool[] coup = Utils.SetCoupling(MShape); //Arrange --- get index dictonary of all external cell indices Dictionary <int, int[]> Didc = Utils.GetDictOfAllExtCellIdc(map); //Arrange --- stopwatch var stw = new Stopwatch(); stw.Reset(); //Act --- Extract subblocks stw.Start(); //var eblocks = mask.GetSubBlocks(M,coup[0],coup[1],coup[2]); var eblocks = mask.GetDiagonalBlocks(M, false, false); stw.Stop(); //Assert --- same number of blocks? Assert.IsTrue(eblocks.Length == M_ext._RowPartitioning.LocalNoOfBlocks); bool test = eblocks.Length.MPIEquals(); Debug.Assert(test); for (int iBlock = 0; iBlock < eblocks.Length; iBlock++) { var infNorm = MultidimensionalArray.Create(4, 1); int rank = map.MpiRank; int ExtBlockIdx = iBlock + map.AggGrid.iLogicalCells.NoOfLocalUpdatedCells; Didc.TryGetValue(ExtBlockIdx, out int[] idc); using (BatchmodeConnector matlab = new BatchmodeConnector()) { double[] GlobIdx = idc.Count().ForLoop(i => (double)idc[i] + 1.0); Assert.IsTrue(GlobIdx.Length == eblocks[iBlock].Lengths[0]); MsrMatrix M_sub = eblocks[iBlock].ConvertToMsr(); matlab.PutSparseMatrix(M, "M"); // note: M_sub lives on Comm_Self, therefore we have to distinguish between procs ... matlab.PutSparseMatrixRankExclusive(M_sub, "M_sub"); matlab.PutVectorRankExclusive(GlobIdx, "Idx"); matlab.Cmd("M_0 = full(M(Idx_0, Idx_0));"); matlab.Cmd("M_1 = full(M(Idx_1, Idx_1));"); matlab.Cmd("M_2 = full(M(Idx_2, Idx_2));"); matlab.Cmd("M_3 = full(M(Idx_3, Idx_3));"); matlab.Cmd("n=[0; 0; 0; 0];"); matlab.Cmd("n(1,1)=norm(M_0-M_sub_0,inf);"); matlab.Cmd("n(2,1)=norm(M_1-M_sub_1,inf);"); matlab.Cmd("n(3,1)=norm(M_2-M_sub_2,inf);"); matlab.Cmd("n(4,1)=norm(M_3-M_sub_3,inf);"); matlab.GetMatrix(infNorm, "n"); matlab.Execute(); } Assert.IsTrue(infNorm[rank, 0] == 0.0); // } }