Пример #1
0
        /// <summary>
        /// modifies a matrix <paramref name="Mtx"/> and a right-hand-side <paramref name="rhs"/>
        /// in order to fix the pressure at some reference point
        /// </summary>
        /// <param name="map">row mapping for <paramref name="Mtx"/> as well as <paramref name="rhs"/></param>
        /// <param name="iVar">the index of the pressure variable in the mapping <paramref name="map"/>.</param>
        /// <param name="LsTrk"></param>
        /// <param name="Mtx"></param>
        /// <param name="rhs"></param>
        static public void SetPressureReferencePoint <T>(UnsetteledCoordinateMapping map, int iVar, LevelSetTracker LsTrk, BlockMsrMatrix Mtx, T rhs)
            where T : IList <double>
        {
            using (new FuncTrace()) {
                var GridDat = map.GridDat;

                if (rhs.Count != map.LocalLength)
                {
                    throw new ArgumentException();
                }
                if (!Mtx.RowPartitioning.EqualsPartition(map) || !Mtx.ColPartition.EqualsPartition(map))
                {
                    throw new ArgumentException();
                }

                Basis PressureBasis = (Basis)map.BasisS[iVar];
                int   D             = GridDat.SpatialDimension;

                long GlobalID, GlobalCellIndex;
                bool IsInside, onthisProc;
                GridDat.LocatePoint(new double[D], out GlobalID, out GlobalCellIndex, out IsInside, out onthisProc, LsTrk.Regions.GetCutCellSubGrid().VolumeMask.Complement());

                int iRowGl = -111;
                if (onthisProc)
                {
                    int jCell = (int)GlobalCellIndex - GridDat.CellPartitioning.i0;


                    NodeSet CenterNode = new NodeSet(GridDat.iGeomCells.GetRefElement(jCell), new double[D]);
                    MultidimensionalArray LevSetValues = LsTrk.DataHistories[0].Current.GetLevSetValues(CenterNode, jCell, 1);;


                    MultidimensionalArray CenterNodeGlobal = MultidimensionalArray.Create(1, D);
                    GridDat.TransformLocal2Global(CenterNode, CenterNodeGlobal, jCell);
                    //Console.WriteLine("Pressure Ref Point @( {0:0.###E-00} | {1:0.###E-00} )", CenterNodeGlobal[0,0], CenterNodeGlobal[0,1]);


                    LevelSetSignCode  scode = LevelSetSignCode.ComputeLevelSetBytecode(LevSetValues[0, 0]);
                    ReducedRegionCode rrc;
                    int No   = LsTrk.Regions.GetNoOfSpecies(jCell, out rrc);
                    int iSpc = LsTrk.GetSpeciesIndex(rrc, scode);

                    iRowGl = (int)map.GlobalUniqueCoordinateIndex_FromGlobal(iVar, GlobalCellIndex, 0);
                }
                iRowGl = iRowGl.MPIMax();


                // clear row
                // ---------
                if (onthisProc)
                {
                    // ref. cell is on local MPI process
                    int jCell = (int)GlobalCellIndex - GridDat.CellPartitioning.i0;

                    ReducedRegionCode rrc;
                    int NoOfSpc = LsTrk.Regions.GetNoOfSpecies(jCell, out rrc);

                    // set matrix row to identity
                    Mtx.ClearRow(iRowGl);
                    Mtx.SetDiagonalElement(iRowGl, 1.0);


                    // clear RHS
                    int iRow = iRowGl - Mtx.RowPartitioning.i0;
                    rhs[iRow] = 0;
                }

                // clear column
                // ------------
                {
                    for (int i = Mtx.RowPartitioning.i0; i < Mtx.RowPartitioning.iE; i++)
                    {
                        if (i != iRowGl)
                        {
                            Mtx[i, iRowGl] = 0;
                        }
                    }
                }
            }
        }
Пример #2
0
Файл: ILU.cs Проект: xyuan/BoSSS
        public void Solve <P, Q>(P X, Q B)
            where P : IList <double>
            where Q : IList <double>
        {
            int    n   = Mtx.NoOfCols;
            double sum = 0;

            var tempMtx = Mtx;

            // Zeros on diagonal elements because of saddle point structure
            for (int bla = 0; bla < n; bla++)
            {
                if (Mtx.GetDiagonalElement(bla) == 0)
                {
                    throw new Exception("One or more diagonal elements are zero, ILU cannot work");
                }
                Mtx.SetDiagonalElement(bla, 1);
            }


            // ILU decomposition of matrix
            for (int k = 0; k < n - 1; k++)
            {
                for (int i = k; i < n; i++)
                {
                    if (tempMtx[i, k] == 0)
                    {
                        i = n;
                    }
                    else
                    {
                        Mtx[i, k] = Mtx[i, k] / Mtx[k, k];
                        for (int j = k + 1; j < n; j++)
                        {
                            if (tempMtx[i, j] == 0)
                            {
                                j = n;
                            }
                            else
                            {
                                Mtx[i, j] = Mtx[i, j] - Mtx[i, k] * Mtx[k, j];
                            }
                        }
                    }
                }
            }


            // LU decomposition of matrix
            //for (int i = 0; i < n; i++) {
            //    for (int j = i; j < n; j++) {
            //        sum = 0;
            //        for (int k = 0; k < i; k++)
            //            sum += Mtx[i, k] * Mtx[k, j];
            //        Mtx[i, j] = tempMtx[i, j] - sum;
            //    }
            //    for (int j = i + 1; j < n; j++) {
            //        sum = 0;
            //        for (int k = 0; k < i; k++)
            //            sum += Mtx[j, k] * Mtx[k, i];
            //        Mtx[j, i] = (1 / Mtx[i, i]) * (tempMtx[j, i] - sum);
            //    }
            //}

            // find solution of Ly = b
            double[] y = new double[n];
            for (int i = 0; i < n; i++)
            {
                sum = 0;
                for (int k = 0; k < i; k++)
                {
                    sum += Mtx[i, k] * y[k];
                }
                y[i] = B[i] - sum;
            }
            // find solution of Ux = y
            for (int i = n - 1; i >= 0; i--)
            {
                sum = 0;
                for (int k = i + 1; k < n; k++)
                {
                    sum += Mtx[i, k] * X[k];
                }
                X[i] = (1 / Mtx[i, i]) * (y[i] - sum);
            }
        }