Esempio n. 1
0
        void BlockSol <V1, V2>(BlockMsrMatrix M, V1 X, V2 B)
            where V1 : IList <double>
            where V2 : IList <double> //
        {
            int i0 = M.RowPartitioning.i0;
            int iE = M.RowPartitioning.iE;

            var Part = M.RowPartitioning;

            Debug.Assert(Part.EqualsPartition(this.CurrentStateMapping));

            int J = m_LsTrk.GridDat.Cells.NoOfLocalUpdatedCells;

            double[] MtxVals = null;
            int[]    Indices = null;

            MultidimensionalArray Block = null;

            double[] x = null, b = null;
            for (int j = 0; j < J; j++)
            {
                int bS = this.CurrentStateMapping.LocalUniqueCoordinateIndex(0, j, 0);
                int Nj = this.CurrentStateMapping.GetTotalNoOfCoordinatesPerCell(j);

                if (Block == null || Block.NoOfRows != Nj)
                {
                    Block = MultidimensionalArray.Create(Nj, Nj);
                    x     = new double[Nj];
                    b     = new double[Nj];
                }
                else
                {
                    Block.Clear();
                }


                // extract block and part of RHS
                for (int iRow = 0; iRow < Nj; iRow++)
                {
                    bool ZeroRow = true;
                    //MsrMatrix.MatrixEntry[] row = M.GetRow(iRow + bS + i0);
                    int LR = M.GetRow(iRow + bS + i0, ref Indices, ref MtxVals);

                    //foreach (var entry in row) {
                    for (int lr = 0; lr < LR; lr++)
                    {
                        int    ColIndex = Indices[lr];
                        double Value    = MtxVals[lr];

                        Block[iRow, ColIndex - (bS + i0)] = Value;
                        if (Value != 0.0)
                        {
                            ZeroRow = false;
                        }
                    }
                    b[iRow] = B[iRow + bS];

                    if (ZeroRow)
                    {
                        if (b[iRow] != 0.0)
                        {
                            throw new ArithmeticException();
                        }
                        else
                        {
                            Block[iRow, iRow] = 1.0;
                        }
                    }
                }

                // solve
                Block.SolveSymmetric(x, b);

                // store solution
                for (int iRow = 0; iRow < Nj; iRow++)
                {
                    X[iRow + bS] = x[iRow];
                }
            }
        }