protected override void AdaptMesh(int TimestepNo, out GridCommons newGrid, out GridCorrelation old2NewGrid)
        {
            if (TimestepNo > 3 && TimestepNo % 3 != 0)
            {
                //{
                newGrid     = null;
                old2NewGrid = null;
                return;
            }

            // Check grid changes
            // ==================
            bool                     AnyChange;
            List <int>               CellsToRefineList;
            List <int[]>             Coarsening;
            GridRefinementController gridRefinementController = new GridRefinementController((GridData)this.GridData, LsTrk.Regions.GetCutCellMask());

            if (MPISize > 1)
            {
                List <Tuple <int, BitArray> > cellMaskRefinementLevel = GetCellMaskWithRefinementLevels();
                AnyChange = gridRefinementController.ComputeGridChange(cellMaskRefinementLevel, out CellsToRefineList, out Coarsening);
            }
            else
            {
                AnyChange = gridRefinementController.ComputeGridChange(LevelIndicator, out CellsToRefineList, out Coarsening);
            }
            int NoOfCellsToRefine  = 0;
            int NoOfCellsToCoarsen = 0;

            if (AnyChange)
            {
                int[] glb = (new int[] {
                    CellsToRefineList.Count,
                    Coarsening.Sum(L => L.Length),
                }).MPISum();
                NoOfCellsToRefine  = glb[0];
                NoOfCellsToCoarsen = glb[1];
            }
            int oldJ = this.GridData.CellPartitioning.TotalLength;

            // Update Grid
            // ===========

            if (AnyChange)
            {
                Console.WriteLine("       Refining " + NoOfCellsToRefine + " of " + oldJ + " cells");
                Console.WriteLine("       Coarsening " + NoOfCellsToCoarsen + " of " + oldJ + " cells");


                newGrid = ((GridData)this.GridData).Adapt(CellsToRefineList, Coarsening, out old2NewGrid);
            }
            else
            {
                newGrid     = null;
                old2NewGrid = null;
            }
        }
Exemple #2
0
        /// <summary>
        /// control of mesh adaptation
        /// </summary>
        protected override void AdaptMesh(int TimestepNo, out GridCommons newGrid, out GridCorrelation old2NewGrid)
        {
            if (this.Control.AdaptiveMeshRefinement && TimestepNo > 1)
            {
                int oldJ = this.GridData.CellPartitioning.TotalLength;

                double LocNormPow2         = this.ResiualKP1.CoordinateVector.L2NormPow2(); // norm of residual on this processor
                double TotNormPow2         = LocNormPow2.MPISum();                          //                          norm of residual over all processors
                double MeanNormPow2PerCell = TotNormPow2 / oldJ;                            //                    mean norm per cell

                double maxSoFar = 0;
                int    jMax     = -1;
                for (int j = 0; j < oldJ; j++)
                {
                    double CellNorm = Error.Coordinates.GetRow(j).L2NormPow2();

                    if (CellNorm > maxSoFar)
                    {
                        jMax     = j;
                        maxSoFar = CellNorm;
                    }
                }


                int LevelIndicator(int j, int CurrentLevel)
                {
                    double CellNorm = this.ResiualKP1.Coordinates.GetRow(j).L2NormPow2();

                    if (j == jMax)
                    {
                        return(CurrentLevel + 1);
                    }
                    else
                    {
                        return(CurrentLevel);
                    }
                }

                bool AnyChange          = GridRefinementController.ComputeGridChange((GridData)(this.GridData), null, LevelIndicator, out List <int> CellsToRefineList, out List <int[]> Coarsening);
                int  NoOfCellsToRefine  = 0;
                int  NoOfCellsToCoarsen = 0;
                if (AnyChange)
                {
                    int[] glb = (new int[] {
                        CellsToRefineList.Count,
                        Coarsening.Sum(L => L.Length),
                    }).MPISum();

                    NoOfCellsToRefine  = glb[0];
                    NoOfCellsToCoarsen = glb[1];
                }

                // Update Grid
                // ===========

                if (AnyChange)
                {
                    Console.WriteLine("       Refining " + NoOfCellsToRefine + " of " + oldJ + " cells");
                    Console.WriteLine("       Coarsening " + NoOfCellsToCoarsen + " of " + oldJ + " cells");

                    newGrid = ((GridData)(this.GridData)).Adapt(CellsToRefineList, Coarsening, out old2NewGrid);
                }
                else
                {
                    newGrid     = null;
                    old2NewGrid = null;
                }
            }
            else
            {
                newGrid     = null;
                old2NewGrid = null;
            }
        }
 /// <summary>
 /// Locally refine p-Order in Cutcells
 /// </summary>
 protected override void AdaptMesh(int TimestepNo, out GridCommons newGrid, out GridCorrelation old2NewGrid)
 {
     throw new NotImplementedException();
 }
Exemple #4
0
        /// <summary>
        /// Apply the resorting (including mesh adaptation).
        /// </summary>
        public void Resort(GridCorrelation r, GridData NewGrid)
        {
            using (new FuncTrace()) {
                this.GridAdaptation = false;
                m_Old2NewCorr       = r;
                m_OldGrid           = null;
                m_OldTracker        = null;
                m_NewGrid           = NewGrid;
                m_newJ = m_NewGrid.iLogicalCells.NoOfLocalUpdatedCells;

                // fix the sequence in which we serialize/de-serialize fields
                string[] FieldNames = this.m_oldDGFieldData.Keys.ToArray();
                int      NoFields   = FieldNames.Length;

                // format data for serialization
                double[][] oldFieldsData = new double[m_oldJ][];                                                     // 1st: cell; 2nd enum
                {
                    double[][][] oldFields = FieldNames.Select(rstring => this.m_oldDGFieldData[rstring]).ToArray(); // 1st: field; 2nd: cell; 3rd: DG coord

                    for (int j = 0; j < m_oldJ; j++)
                    {
                        int Ntot = 0;
                        for (int iF = 0; iF < NoFields; iF++)
                        {
                            Ntot += oldFields[iF][j].Length;
                        }

                        // pack the DG coords for each field into one array of the form
                        // { Np_f1, DGcoords_f1, Np_f2, DGcoords_f2, .... };

                        double[] data_j = new double[Ntot + NoFields];
                        int      cnt    = 0;
                        for (int iF = 0; iF < NoFields; iF++)
                        {
                            double[] data_iF_j = oldFields[iF][j];
                            int      Nj        = data_iF_j.Length;
                            data_j[cnt] = Nj;
                            cnt++;
                            for (int n = 0; n < Nj; n++)
                            {
                                data_j[cnt] = data_iF_j[n];
                                cnt++;
                            }
                        }
                        oldFieldsData[j] = data_j;
                    }
                    oldFields        = null;
                    m_oldDGFieldData = null;
                }

                // redistribute data
                double[][][] newFieldsData = new double[m_newJ][][];
                {
                    //Resorting.ApplyToVector(oldFieldsData, newFieldsData, m_NewGrid.CellPartitioning);
                    r.ApplyToVector(oldFieldsData, newFieldsData, m_NewGrid.CellPartitioning);
                    oldFieldsData = null;
                    Debug.Assert(newFieldsData.Length == m_newJ);
                }

                // re-format re-distributed data
                m_newDGFieldData_GridAdapta = new Dictionary <string, double[][][]>();
                {
                    double[][][][] newFields = new double[FieldNames.Length][][][]; // indices: [field, cell idx, enum over coarsening, DG mode]
                    for (int iF = 0; iF < NoFields; iF++)
                    {
                        newFields[iF] = new double[m_newJ][][];
                    }
                    for (int j = 0; j < m_newJ; j++)
                    {
                        double[][] data_j = newFieldsData[j];
                        int        L      = data_j.Length; // cell cluster size (equal 1 for refined or conserved cells)

                        for (int iF = 0; iF < NoFields; iF++)
                        {
                            newFields[iF][j] = new double[L][];
                        }

                        for (int l = 0; l < L; l++)
                        {
                            double[] data_jl = data_j[l];

                            int cnt = 0;
                            for (int iF = 0; iF < NoFields; iF++)
                            {
                                int Nj = (int)data_jl[cnt];
                                cnt++;
                                double[] data_iF_jl = new double[Nj];
                                for (int n = 0; n < Nj; n++)
                                {
                                    data_iF_jl[n] = data_jl[cnt];
                                    cnt++;
                                }
                                newFields[iF][j][l] = data_iF_jl;
                            }
                            Debug.Assert(cnt == data_jl.Length);
                        }
                    }

                    for (int iF = 0; iF < NoFields; iF++)
                    {
                        m_newDGFieldData_GridAdapta.Add(FieldNames[iF], newFields[iF]);
                    }
                }
            }
        }
Exemple #5
0
        static private void DoCellj(int j, DGField f, GridData NewGrid, int pDeg, int[] TargMappingIdx_j, double[][] ReDistDGCoords_j, int l, GridCorrelation Old2NewCorr, int N0rcv, int N0acc, int Np, double[] ReDistDGCoords_jl, double[] Coords_j)
        {
            Debug.Assert(ReDistDGCoords_j.Length == TargMappingIdx_j.Length);

            int iKref = NewGrid.Cells.GetRefElementIndex(j);

            Debug.Assert(Coords_j.Length == Np);
            Debug.Assert(ReDistDGCoords_jl.Length == Np);

            for (int n = 0; n < Np; n++)
            {
                Coords_j[n] = f.Coordinates[j, N0acc + n];
            }

            int L = ReDistDGCoords_j.Length;


            if (TargMappingIdx_j.Length == 1)
            {
                // ++++++++++
                // refinement
                // ++++++++++
                Debug.Assert(l == 0);
                MultidimensionalArray Trafo = Old2NewCorr.GetSubdivBasisTransform(iKref, TargMappingIdx_j[0], pDeg);

                for (int n = 0; n < Np; n++)
                {
                    ReDistDGCoords_jl[n] = ReDistDGCoords_j[0][N0rcv + n];
                }
                Trafo.gemv(1.0, ReDistDGCoords_jl, 1.0, Coords_j, transpose: false);
            }
            else
            {
                // ++++++++++
                // coarsening
                // ++++++++++


                var Trafo = Old2NewCorr.GetSubdivBasisTransform(iKref, TargMappingIdx_j[l], pDeg);

                for (int n = 0; n < Np; n++)
                {
                    ReDistDGCoords_jl[n] = ReDistDGCoords_j[l][N0rcv + n];
                }

                Trafo.gemv(1.0, ReDistDGCoords_jl, 1.0, Coords_j, transpose: true);
            }

            for (int n = 0; n < Np; n++)
            {
                f.Coordinates[j, N0acc + n] = Coords_j[n];
            }
        }
Exemple #6
0
        static private void DoCellj(int j, DGField f, GridData NewGrid, int pDeg, int[] TargMappingIdx_j, double[][] ReDistDGCoords_j, int l, GridCorrelation Old2NewCorr, int N0rcv, int N0acc, int Np, double[] ReDistDGCoords_jl, double[] Coords_j)
        {
            Debug.Assert(ReDistDGCoords_j.Length == TargMappingIdx_j.Length);
            Debug.Assert(object.ReferenceEquals(NewGrid, f.GridDat));

            int iKref = NewGrid.Cells.GetRefElementIndex(j);

            Debug.Assert(Coords_j.Length == Np);
            Debug.Assert(ReDistDGCoords_jl.Length == Np);

            for (int n = 0; n < Np; n++)
            {
                Coords_j[n] = f.Coordinates[j, N0acc + n]; // for coarsening, we 'touch' each cell multiple times -- therefore, values must be accumulated
            }

            int L = ReDistDGCoords_j.Length;


            if (TargMappingIdx_j.Length == 1)
            {
                // ++++++++++
                // refinement
                // ++++++++++
                Debug.Assert(l == 0);
                MultidimensionalArray Trafo = Old2NewCorr.GetSubdivBasisTransform(iKref, TargMappingIdx_j[0], pDeg).Item1;
                double scale = Old2NewCorr.GetSubdivBasisTransform(iKref, TargMappingIdx_j[0], pDeg).Item2;

                for (int n = 0; n < Np; n++)
                {
                    ReDistDGCoords_jl[n] = ReDistDGCoords_j[0][N0rcv + n];
                }
                Trafo.gemv(1.0, ReDistDGCoords_jl, 1.0, Coords_j, transpose: false);
                BckTrafo(Coords_j, Np, 0, NewGrid, j, pDeg, scale.Sqrt());
            }
            else
            {
                // ++++++++++
                // coarsening
                // ++++++++++
                var    Trafo = Old2NewCorr.GetSubdivBasisTransform(iKref, TargMappingIdx_j[l], pDeg).Item1;
                double scale = Old2NewCorr.GetSubdivBasisTransform(iKref, TargMappingIdx_j[l], pDeg).Item2;

                for (int n = 0; n < Np; n++)
                {
                    ReDistDGCoords_jl[n] = ReDistDGCoords_j[l][N0rcv + n];
                }
                //if (!Oasch) {
                //    Trafo.gemv(1.0, ReDistDGCoords_jl, 1.0, Coords_j, transpose: true);
                //} else {
                double[] buf = new double[Np];
                Trafo.gemv(1.0, ReDistDGCoords_jl, 1.0, buf, transpose: true);
                BckTrafo(buf, Np, 0, NewGrid, j, pDeg, 1.0 / scale.Sqrt());

                Coords_j.AccV(1.0, buf);
                //}
            }

            for (int n = 0; n < Np; n++)
            {
                f.Coordinates[j, N0acc + n] = Coords_j[n];
            }
        }