示例#1
0
        public static void CellBlockVectorOperations(
            [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
            )
        {
            //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

            Utils.TestInit((int)UseXdg, DGOrder, (int)MShape);
            Console.WriteLine("CellBlockVectorOperations({0},{1},{2})", UseXdg, DGOrder, MShape);

            var mop = Utils.CreateTestMGOperator(UseXdg, DGOrder, MShape);
            var map = mop.Mapping;

            double[] Vec = Utils.GetRandomVector(mop.Mapping.LocalLength);

            //Arrange --- setup masking
            SubBlockSelector SBS = new SubBlockSelector(map);

            BlockMask mask = new BlockMask(SBS, null);

            //Arrange --- some time measurement
            Stopwatch stw = new Stopwatch();

            stw.Reset();

            //Assert --- all diagonal blocks are extracted
            //Assert.IsTrue(blocks.Length == map.LocalNoOfBlocks);

            double[] Vec_col = new double[map.LocalLength];

            for (int i = 0; i < map.LocalNoOfBlocks; i++)
            {
                stw.Start();
                double[] Vec_i = mask.GetSubVecOfCell(Vec, i);
                mask.AccSubVecOfCell(Vec_i, i, Vec_col);
                stw.Stop();
            }
            Vec_col.AccV(-1.0, Vec);

            //Assert --- are extracted blocks and
            Assert.IsTrue(Vec_col.L2Norm() == 0.0, String.Format("L2Norm neq 0!"));
        }
示例#2
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);
        }