public static void SplitVectorOperations( XDGusage UseXdg, int DGOrder, MatrixShape MShape ) { Utils.TestInit((int)UseXdg, DGOrder, (int)MShape); Console.WriteLine("SplitVectorOperations({0},{1},{2})", UseXdg, DGOrder, MShape); //matrix Erzeugung wie in ExtractDiagonalCellBlocks... //Auf der HierarchieEbene, auf der Kopplung ausgesetzt wird kann Auswahl vorgenommen werden //bei var: 0 / 1, bei DG: <=1 / >1, bei spec: A / B, bei Cells: odd / even //accumulierte Teilergebnisse sind dann == fullM*fullX var mop = Utils.CreateTestMGOperator(UseXdg, DGOrder, MShape); var map = mop.Mapping; double[] Vec = Utils.GetRandomVector(mop.Mapping.LocalLength); //Arrange --- setup masking SubBlockSelector sbsA = new SubBlockSelector(map); sbsA.SetDefaultSplitSelection(MShape, true); BlockMask maskA = new BlockMask(sbsA, null); SubBlockSelector sbsB = new SubBlockSelector(map); sbsB.SetDefaultSplitSelection(MShape, false); BlockMask maskB = new BlockMask(sbsB, null); double[] VecAB = new double[Vec.Length]; //Arrange --- some time measurement Stopwatch stw = new Stopwatch(); stw.Reset(); //Act --- stw.Start(); var VecA = maskA.GetSubVec(Vec); var VecB = maskB.GetSubVec(Vec); maskA.AccSubVec(VecA, VecAB); maskB.AccSubVec(VecB, VecAB); stw.Stop(); Debug.Assert(Vec.L2Norm() != 0); double fac = ((MShape == MatrixShape.full_var || MShape == MatrixShape.diagonal_var) && UseXdg == XDGusage.none) ? -2.0 : -1.0; VecAB.AccV(fac, Vec); //Assert --- are extracted blocks and Assert.IsTrue(VecAB.L2Norm() == 0.0, String.Format("L2Norm neq 0!")); }
public static void VectorSplitOperation( [Values(XDGusage.none, XDGusage.all)] XDGusage UseXdg, [Values(2)] int DGOrder, [Values(MatrixShape.full_var_spec, MatrixShape.full_spec, MatrixShape.full)] MatrixShape MShape, [Values(4)] int Res) { Utils.TestInit((int)UseXdg, DGOrder, (int)MShape, Res); Console.WriteLine("VectorSplitOperation({0},{1},{2},{3})", UseXdg, DGOrder, MShape, Res); //Arrange --- create test matrix, MG mapping MultigridOperator mgo = Utils.CreateTestMGOperator(UseXdg, DGOrder, MShape, Res); MultigridMapping map = mgo.Mapping; BlockMsrMatrix M = mgo.OperatorMatrix; BlockMsrMatrix M_ext = BlockMask.GetAllExternalRows(map, M); double[] Vec = Utils.GetRandomVector(M_ext.RowPartitioning.LocalLength); //Arrange --- setup masking SubBlockSelector sbsA = new SubBlockSelector(map); sbsA.SetDefaultSplitSelection(MShape, true, false); BlockMask maskA = new BlockMask(sbsA, M_ext); SubBlockSelector sbsB = new SubBlockSelector(map); sbsB.SetDefaultSplitSelection(MShape, false, false); BlockMask maskB = new BlockMask(sbsB, M_ext); double[] VecAB = new double[Vec.Length]; //Arrange --- some time measurement Stopwatch stw = new Stopwatch(); stw.Reset(); //Act --- stw.Start(); var VecA = maskA.GetSubVec(Vec, new double[0]); var VecB = maskB.GetSubVec(Vec, new double[0]); maskA.AccSubVec(VecA, VecAB, new double[0]); maskB.AccSubVec(VecB, VecAB, new double[0]); stw.Stop(); Debug.Assert(Vec.L2Norm() != 0); double fac = ((MShape == MatrixShape.full_var || MShape == MatrixShape.diagonal_var) && UseXdg == XDGusage.none) ? -2.0 : -1.0; VecAB.AccV(fac, Vec); //Assert --- are extracted blocks and Assert.IsTrue(VecAB.L2Norm() == 0.0, String.Format("L2Norm neq 0!")); }
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); }