예제 #1
0
        public void ImplicitEuler(double dt, SubGrid S, SinglePhaseField inout_Levset)
        {
            var VolMsk = S.VolumeMask;
            var EdgMsk = S.InnerEdgesMask;
            UnsetteledCoordinateMapping Map = inout_Levset.Mapping;

            if (dt <= 0.0)
            {
                throw new ArgumentOutOfRangeException("Timestep size must be greater than 0.");
            }

            MsrMatrix Pmtx = PenaltyMatrix(EdgMsk, inout_Levset.Basis, inout_Levset.Basis);

            Pmtx.Scale(-1.0);

            int[] SubVecIdx = Map.GetSubvectorIndices(S, true, new int[] { 0 });
            int   L         = SubVecIdx.Length;

            MsrMatrix SubMtx = new MsrMatrix(L, L);

            Pmtx.AccSubMatrixTo(1.0, SubMtx, SubVecIdx, default(int[]), SubVecIdx, default(int[]));

            SubMtx.AccEyeSp(1.0 / dt);

            double[] RHS = new double[L];
            double[] SOL = new double[L];

            RHS.AccV(1.0 / dt, inout_Levset.CoordinateVector, default(int[]), SubVecIdx);

            using (var solver = new PARDISOSolver()) {
                solver.DefineMatrix(SubMtx);
                solver.Solve(SOL, RHS);
            }

            inout_Levset.CoordinateVector.ClearEntries(SubVecIdx);
            inout_Levset.CoordinateVector.AccV(1.0, SOL, SubVecIdx, default(int[]));
        }
예제 #2
0
        /// <summary>
        /// Krankplätze müssen verdichtet werden
        /// -Kranführer Ronny, ProSieben Reportage
        /// </summary>
        public void Init(MultigridOperator op)
        {
            //            //System.Threading.Thread.Sleep(10000);
            //            //ilPSP.Environment.StdoutOnlyOnRank0 = false;
            m_op = op;

            if (m_CoarseLowOrder > m_op.Mapping.DgDegree.Max())
            {
                throw new ArgumentOutOfRangeException("CoarseLowOrder is higher than maximal DG degree");
            }

#if TEST
            var debugerSW = new StreamWriter(String.Concat("debug_of_", ilPSP.Environment.MPIEnv.MPI_Rank));
            Console.WriteLine("variable TEST is defined");
            //debugerSW.WriteLine("proc {0} reporting Num of Blocks {1}", ilPSP.Environment.MPIEnv.MPI_Rank, HighOrderBlocks_LUpivots.Length);
#endif

            int D = this.m_op.GridData.SpatialDimension;


            var DGlowSelect = new SubBlockSelector(op.Mapping);
            Func <int, int, int, int, bool> lowFilter = (int iCell, int iVar, int iSpec, int pDeg) => pDeg <= (iVar != D ? CoarseLowOrder : CoarseLowOrder - 1);
            DGlowSelect.ModeSelector(lowFilter);

            if (AssignXdGCellsToLowBlocks)
            {
                ModifyLowSelector(DGlowSelect, op);
            }

            lMask        = new BlockMask(DGlowSelect);
            m_lowMaskLen = lMask.GetNoOfMaskedRows;

            if (UseHiOrderSmoothing)
            {
                var DGhighSelect = new SubBlockSelector(op.Mapping);
                Func <int, int, int, int, bool> highFilter = (int iCell, int iVar, int iSpec, int pDeg) => pDeg > (iVar != D ? CoarseLowOrder : CoarseLowOrder - 1);
                DGhighSelect.ModeSelector(highFilter);

                if (AssignXdGCellsToLowBlocks)
                {
                    ModifyHighSelector(DGhighSelect, op);
                }

                hMask         = new BlockMask(DGhighSelect);
                m_highMaskLen = hMask.GetNoOfMaskedRows;

                BlockMsrMatrix P01HiMatrix = null;

                if (UseDiagonalPmg)
                {
                    HighOrderBlocks_LU = hMask.GetDiagonalBlocks(op.OperatorMatrix, false, false);
                    int NoOfBlocks = HighOrderBlocks_LU.Length;
                    HighOrderBlocks_LUpivots = new int[NoOfBlocks][];

                    for (int jLoc = 0; jLoc < NoOfBlocks; jLoc++)
                    {
                        int len = HighOrderBlocks_LU[jLoc].NoOfRows;
                        HighOrderBlocks_LUpivots[jLoc] = new int[len];
                        HighOrderBlocks_LU[jLoc].FactorizeLU(HighOrderBlocks_LUpivots[jLoc]);
                    }
                }
                else
                {
                    P01HiMatrix = hMask.GetSubBlockMatrix(op.OperatorMatrix, csMPI.Raw._COMM.SELF);

                    hiSolver = new PARDISOSolver()
                    {
                        CacheFactorization = true,
                        UseDoublePrecision = true, // keep it true, experiments showed, that this leads to fewer iterations
                        SolverVersion      = Parallelism.OMP
                    };
                    hiSolver.DefineMatrix(P01HiMatrix);
                }
            }

            var P01SubMatrix = lMask.GetSubBlockMatrix(op.OperatorMatrix, csMPI.Raw._COMM.WORLD);

            intSolver = new PARDISOSolver()
            {
                CacheFactorization = true,
                UseDoublePrecision = false, // no difference towards =true observed for XDGPoisson
                SolverVersion      = Parallelism.OMP
            };
            intSolver.DefineMatrix(P01SubMatrix);

#if TEST
            P01SubMatrix.SaveToTextFileSparseDebug("lowM");
            P01SubMatrix.SaveToTextFileSparse("lowM_full");
            if (!UseDiagonalPmg)
            {
                //P01HiMatrix.SaveToTextFileSparseDebug("hiM");
                //P01HiMatrix.SaveToTextFileSparse("hiM_full");
            }
            m_op.OperatorMatrix.SaveToTextFileSparseDebug("M");
            m_op.OperatorMatrix.SaveToTextFileSparse("M_full");
            debugerSW.Flush();
            debugerSW.Close();

            long[] bla = m_op.BaseGridProblemMapping.GridDat.CurrentGlobalIdPermutation.Values;
            bla.SaveToTextFileDebug("permutation_");

            List <int> BlockI0 = new List <int>();
            List <int> Block_N = new List <int>();
            foreach (long Block in bla)
            {
                BlockI0.Add(m_op.Mapping.GetBlockI0((int)Block));
                Block_N.Add(m_op.Mapping.GetBlockLen((int)Block));
            }
            BlockI0.SaveToTextFileDebug("BlockI0");
            Block_N.SaveToTextFileDebug("Block_N");
#endif
        }
예제 #3
0
        /// <summary>
        /// ~
        /// </summary>
        public void Init(MultigridOperator op)
        {
            //System.Threading.Thread.Sleep(10000);
            //ilPSP.Environment.StdoutOnlyOnRank0 = false;
            m_op = op;

            var Map    = op.Mapping;
            int NoVars = Map.AggBasis.Length;
            int j0     = Map.FirstBlock;
            int J      = Map.LocalNoOfBlocks;

            int[] degs = m_op.Degrees;

            for (int ideg = 0; ideg < degs.Length; ideg++)
            {
                if (degs[ideg] == 0)
                {
                    throw new ArgumentException(String.Format("DGdegree for Variable {0} is 0, p-multigrid not possible", ideg));
                }
            }

            var BS = Map.AggBasis;

            if (UseHiOrderSmoothing)
            {
                HighOrderBlocks_LU       = new MultidimensionalArray[J];
                HighOrderBlocks_LUpivots = new int[J][];
                HighOrderBlocks_indices  = new int[J][];
            }


            var GsubIdx           = new List <int>();
            var LsubIdx           = new List <int>();
            var lowLocalBlocks_i0 = new List <int>();
            var lowLocalBlocks__N = new List <int>();
            int cnt = 0;

            /*
             * var debugerSW = new StreamWriter(String.Concat("debug_of_", ilPSP.Environment.MPIEnv.MPI_Rank));
             * debugerSW.WriteLine("proc {0} reporting ...",ilPSP.Environment.MPIEnv.MPI_Rank);
             * debugerSW.WriteLine("Num of Blocks {0}",HighOrderBlocks_LUpivots.Length);
             */

            for (int jLoc = 0; jLoc < J; jLoc++)
            {
                lowLocalBlocks_i0.Add(cnt);
                lowLocalBlocks__N.Add(0);


                var LhiIdx             = new List <int>();
                var IdxHighBlockOffset = new int[NoVars][];
                var IdxHighOffset      = new int[NoVars][];

                int NpHiTot = 0;
                for (int iVar = 0; iVar < NoVars; iVar++)
                {
                    int pReq;
                    if (degs[iVar] <= 1)
                    {
                        pReq = 0;
                    }
                    else
                    {
                        pReq = CoarseLowOrder;
                    }

                    int Np1 = BS[iVar].GetLength(jLoc, pReq);
                    int Np  = BS[iVar].GetLength(jLoc, degs[iVar]);
                    lowLocalBlocks__N[jLoc] += Np1;

                    int NoOfSpc   = BS[iVar].GetNoOfSpecies(jLoc);
                    int NpBase    = Np / NoOfSpc;
                    int NpBaseLow = Np1 / NoOfSpc;
                    IdxHighBlockOffset[iVar] = new int[NoOfSpc + 1];
                    IdxHighOffset[iVar]      = new int[NoOfSpc];

                    for (int iSpc = 0; iSpc < NoOfSpc; iSpc++)
                    {
                        int n          = 0;
                        int cellOffset = NpBase * iSpc;
                        IdxHighOffset[iVar][iSpc] = Map.GlobalUniqueIndex(iVar, jLoc, cellOffset + NpBaseLow);

                        for (; n < NpBaseLow; n++)
                        {
                            int Lidx = Map.LocalUniqueIndex(iVar, jLoc, n + cellOffset);
                            LsubIdx.Add(Lidx); //local block mapping Coarse Matrix (low order entries) to original matrix

                            int Gidx = Map.GlobalUniqueIndex(iVar, jLoc, n + cellOffset);
                            GsubIdx.Add(Gidx); //global mapping Coarse Matrix (low order entries) to original matrix
                        }

                        for (; n < NpBase; n++)
                        {
                            int Lidx = Map.LocalUniqueIndex(iVar, jLoc, n + cellOffset);
                            LhiIdx.Add(Lidx); //local block mapping of high order entries to original matrix

                            //int Gidx = Map.GlobalUniqueIndex(iVar, jLoc, n);
                            //GhiIdx.Add(Gidx);
                        }

                        IdxHighBlockOffset[iVar][iSpc] = NpHiTot;
                        NpHiTot += (NpBase - NpBaseLow);
                    }
                    IdxHighBlockOffset[iVar][NoOfSpc] = NpHiTot;

                    Debug.Assert(GsubIdx.Last() == Map.GlobalUniqueIndex(iVar, jLoc, (NoOfSpc - 1) * NpBase + NpBaseLow - 1));
                    Debug.Assert(LhiIdx.Last() == Map.LocalUniqueIndex(iVar, jLoc, NoOfSpc * NpBase - 1));
                }

                // Save high order blocks for later smoothing
                if (NpHiTot > 0)
                {
                    HighOrderBlocks_LU[jLoc]      = MultidimensionalArray.Create(NpHiTot, NpHiTot);
                    HighOrderBlocks_indices[jLoc] = LhiIdx.ToArray();

                    for (int iVar = 0; iVar < NoVars; iVar++)
                    {
                        for (int jVar = 0; jVar < NoVars; jVar++)
                        {
                            for (int iSpc = 0; iSpc < BS[jVar].GetNoOfSpecies(jLoc); iSpc++)
                            {
                                int i0_hi  = IdxHighOffset[iVar][iSpc];
                                int j0_hi  = IdxHighOffset[jVar][iSpc];
                                int Row_i0 = IdxHighBlockOffset[iVar][iSpc];
                                int Col_i0 = IdxHighBlockOffset[jVar][iSpc];
                                int Row_ie = IdxHighBlockOffset[iVar][iSpc + 1];
                                int col_ie = IdxHighBlockOffset[jVar][iSpc + 1];

                                //debugerSW.WriteLine("Block {0}: i0={1} j0={2} iVar={3}", jLoc, i0_hi, j0_hi, iVar);

                                m_op.OperatorMatrix.ReadBlock(i0_hi, j0_hi,
                                                              HighOrderBlocks_LU[jLoc].ExtractSubArrayShallow(new int[] { Row_i0, Col_i0 }, new int[] { Row_ie - 1, col_ie - 1 }));
                            }
                        }
                    }

                    HighOrderBlocks_LUpivots[jLoc] = new int[NpHiTot];
                    HighOrderBlocks_LU[jLoc].FactorizeLU(HighOrderBlocks_LUpivots[jLoc]);
                }

                cnt += lowLocalBlocks__N[jLoc];
            }



            m_LsubIdx = LsubIdx.ToArray();

            BlockPartitioning localBlocking = new BlockPartitioning(GsubIdx.Count, lowLocalBlocks_i0, lowLocalBlocks__N, Map.MPI_Comm, i0isLocal: true);
            var P01SubMatrix = new BlockMsrMatrix(localBlocking);

            op.OperatorMatrix.AccSubMatrixTo(1.0, P01SubMatrix, GsubIdx, default(int[]), GsubIdx, default(int[]));

            intSolver = new PARDISOSolver()
            {
                CacheFactorization = true,
                UseDoublePrecision = false
            };
            intSolver.DefineMatrix(P01SubMatrix);

            /*
             * LsubIdx.SaveToTextFileDebug("LsubIdx");
             * GsubIdx.SaveToTextFileDebug("GsubIdx");
             * P01SubMatrix.SaveToTextFileSparseDebug("lowM");
             * m_op.OperatorMatrix.SaveToTextFileSparseDebug("M");
             * P01SubMatrix.SaveToTextFileSparse("lowM_full");
             * m_op.OperatorMatrix.SaveToTextFileSparse("M_full");
             *
             * debugerSW.WriteLine("Dim of lowMatrix: {0}",GsubIdx.Count);
             * debugerSW.Flush();
             * debugerSW.Close();
             */
        }