Example #1
0
        /// <summary>
        /// ctor.
        /// </summary>
        internal XDGSpaceMetrics(LevelSetTracker lsTrk, XQuadFactoryHelper qfHelper, int __quadorder, SpeciesId[] speciesIds, int HistoyIndex)
        {
            using (new FuncTrace("XDGSpaceMetrics.ctor")) {
                // ----
                // init
                // ----

                if (!speciesIds.IsSubsetOf(lsTrk.SpeciesIdS))
                {
                    throw new ArgumentException();
                }
                CutCellQuadOrder   = __quadorder;
                m_qfHelper         = qfHelper;
                this.Tracker       = lsTrk;
                this.m_SpeciesList = speciesIds.ToArray();

                m_LevelSetRegions = lsTrk.RegionsHistory[HistoyIndex];
                m_LevelSetData    = lsTrk.DataHistories.Select(his => his[HistoyIndex]).ToList().AsReadOnly();
                foreach (var lsData in m_LevelSetData)
                {
                    Debug.Assert(lsData.HistoryIndex == HistoyIndex);
                }

                // ---------------------
                // compute all the stuff
                // ---------------------

                m_CutCellMetrics    = new CutCellMetrics(this);
                m_MassMatrixFactory = new MassMatrixFactory(this);
                m_XQuadSchemeHelper = new XQuadSchemeHelper(this);
            }
        }
Example #2
0
        /// <summary>
        /// Computes Cell-volumes and edge areas before agglomeration.
        /// </summary>
        void ComputeNonAgglomeratedMetrics()
        {
            var gd = XDGSpaceMetrics.GridDat;
            int JE = gd.Cells.NoOfCells;
            int J  = gd.Cells.NoOfLocalUpdatedCells;
            int D  = gd.SpatialDimension;
            int EE = gd.Edges.Count;

            SpeciesId[] species = this.SpeciesList.ToArray();
            int         NoSpc   = species.Count();

            int[,] E2C = gd.Edges.CellIndices;

            var schH = new XQuadSchemeHelper(XDGSpaceMetrics);

            double[] vec_cellMetrics = new double[JE * NoSpc * 2];

            // collect all per-cell-metrics in the same MultidimArry, for MPI-exchange
            // 1st index: cell
            // 2nd index: species
            // 3rd index: 0 for interface surface per cell, 1 for cut-cell-volume
            MultidimensionalArray cellMetrics = MultidimensionalArray.CreateWrapper(vec_cellMetrics, JE, NoSpc, 2);

            this.CutEdgeAreas   = new Dictionary <SpeciesId, MultidimensionalArray>();
            this.CutCellVolumes = new Dictionary <SpeciesId, MultidimensionalArray>();
            this.InterfaceArea  = new Dictionary <SpeciesId, MultidimensionalArray>();

            //var schS = new List<CellQuadratureScheme>();
            //var rulz = new List<ICompositeQuadRule<QuadRule>>();


            // edges and volumes
            // =================
            for (int iSpc = 0; iSpc < species.Length; iSpc++)
            {
                var cellVol = cellMetrics.ExtractSubArrayShallow(-1, iSpc, 1);
                var spc     = species[iSpc];

                MultidimensionalArray edgArea = MultidimensionalArray.Create(EE);
                this.CutEdgeAreas.Add(spc, edgArea);

                // compute cut edge area
                // ---------------------

                var edgeScheme = schH.GetEdgeQuadScheme(spc);
                var edgeRule   = edgeScheme.Compile(gd, this.CutCellQuadratureOrder);

                BoSSS.Foundation.Quadrature.EdgeQuadrature.GetQuadrature(
                    new int[] { 1 }, gd,
                    edgeRule,
                    _Evaluate : delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) //
                {
                    EvalResult.SetAll(1.0);
                },
                    _SaveIntegrationResults : delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) //
                {
                    for (int i = 0; i < Length; i++)
                    {
                        int iEdge = i + i0;
                        Debug.Assert(edgArea[iEdge] == 0);
                        edgArea[iEdge] = ResultsOfIntegration[i, 0];
                        Debug.Assert(!(double.IsNaN(edgArea[iEdge]) || double.IsInfinity(edgArea[iEdge])));
                    }
                }).Execute();

                // compute cut cell volumes
                // ------------------------

                var volScheme = schH.GetVolumeQuadScheme(spc);
                var volRule   = volScheme.Compile(gd, this.CutCellQuadratureOrder);

                //schS.Add(volScheme);
                //rulz.Add(volRule);

                BoSSS.Foundation.Quadrature.CellQuadrature.GetQuadrature(
                    new int[] { 1 }, gd,
                    volRule,
                    _Evaluate : delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) //
                {
                    EvalResult.SetAll(1.0);
                },
                    _SaveIntegrationResults : delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) //
                {
                    for (int i = 0; i < Length; i++)
                    {
                        int jCell = i + i0;
                        Debug.Assert(cellVol[jCell] == 0);
                        cellVol[jCell] = ResultsOfIntegration[i, 0];
                        Debug.Assert(!(double.IsNaN(cellVol[jCell]) || double.IsInfinity(cellVol[jCell])));
                    }
                }).Execute();
            }


            // interface surface
            // =================

            // loop over all possible pairs of species

            /*
             * for (int iSpcA = 0; iSpcA < species.Length; iSpcA++) {
             *  var SpeciesA = species[iSpcA];
             *  var SpeciesADom = lsTrk.GetSpeciesMask(SpeciesA);
             *  if (SpeciesADom.NoOfItemsLocally <= 0)
             *      continue;
             *
             *  for (int iSpcB = iSpcA + 1; iSpcB < species.Length; iSpcB++) {
             *      var SpeciesB = species[iSpcB];
             *      var SpeciesBDom = lsTrk.GetSpeciesMask(SpeciesB);
             *      if (SpeciesBDom.NoOfItemsLocally <= 0)
             *          continue;
             *
             *      var SpeciesCommonDom = SpeciesADom.Intersect(SpeciesBDom);
             *      if (SpeciesCommonDom.NoOfItemsLocally <= 0)
             *          continue;
             *
             *      // loop over level-sets
             *      int NoOfLs = lsTrk.LevelSets.Count;
             *      for (int iLevSet = 0; iLevSet < NoOfLs; iLevSet++) {
             *
             *
             *          var LsDom = lsTrk.GetCutCellMask4LevSet(iLevSet);
             *          var IntegrationDom = LsDom.Intersect(SpeciesCommonDom);
             *
             *          if (IntegrationDom.NoOfItemsLocally > 0) {
             *              CellQuadratureScheme SurfIntegration = schH.GetLevelSetquadScheme(iLevSet, IntegrationDom);
             *              var rule = SurfIntegration.Compile(gd, this.HMForder);
             *
             *
             *              BoSSS.Foundation.Quadrature.CellQuadrature.GetQuadrature(
             *                  new int[] { 1 }, gd,
             *                  rule,
             *                  _Evaluate: delegate (int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) //
             *                  {
             *                      EvalResult.SetAll(1.0);
             *                  },
             *                  _SaveIntegrationResults: delegate (int i0, int Length, MultidimensionalArray ResultsOfIntegration) //
             *                  {
             *                      for (int i = 0; i < Length; i++) {
             *                          int jCell = i + i0;
             *                          if (cellMetrics[jCell, iSpcA, 0] != 0.0)
             *                              throw new NotSupportedException("More than one zero-level-set per cell is not supported yet.");
             *                          if (cellMetrics[jCell, iSpcB, 0] != 0.0)
             *                              throw new NotSupportedException("More than one zero-level-set per cell is not supported yet.");
             *
             *                          cellMetrics[jCell, iSpcA, 0] = ResultsOfIntegration[i, 0];
             *                          cellMetrics[jCell, iSpcB, 0] = ResultsOfIntegration[i, 0];
             *                      }
             *                  }).Execute();
             *          }
             *      }
             *  }
             * }*/

            // loop over level-sets
            if (species.Length > 0)
            {
                // find domain of all species:
                CellMask SpeciesCommonDom = XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(species[0]);
                for (int iSpc = 1; iSpc < species.Length; iSpc++)
                {
                    SpeciesCommonDom = SpeciesCommonDom.Union(XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(species[iSpc]));
                }
                BitArray[] SpeciesBitMask = species.Select(spc => XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(spc).GetBitMask()).ToArray();

                int NoOfLs  = XDGSpaceMetrics.NoOfLevelSets;
                int NoOfSpc = species.Length;
                for (int iLevSet = 0; iLevSet < NoOfLs; iLevSet++)
                {
                    var LsDom          = XDGSpaceMetrics.LevelSetRegions.GetCutCellMask4LevSet(iLevSet);
                    var IntegrationDom = LsDom.Intersect(SpeciesCommonDom);

                    //if (IntegrationDom.NoOfItemsLocally > 0) { -> Doesn't work if Bjoerns HMF is used, eds up in an mpi dead lock
                    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                    // this level-set is actually relevant for someone in 'species'
                    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                    CellQuadratureScheme SurfIntegration = schH.GetLevelSetquadScheme(iLevSet, IntegrationDom);
                    var rule = SurfIntegration.Compile(gd, this.CutCellQuadratureOrder);

                    BoSSS.Foundation.Quadrature.CellQuadrature.GetQuadrature(
                        new int[] { 1 }, gd,
                        rule,
                        _Evaluate : delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) {
                        EvalResult.SetAll(1.0);
                    },
                        _SaveIntegrationResults : delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) {
                        for (int i = 0; i < Length; i++)
                        {
                            int jCell = i + i0;



                            //if (cellMetrics[jCell, iSpcA, 0] != 0.0)
                            //    throw new NotSupportedException("More than one zero-level-set per cell is not supported yet.");
                            //if (cellMetrics[jCell, iSpcB, 0] != 0.0)
                            //    throw new NotSupportedException("More than one zero-level-set per cell is not supported yet.");

                            //cellMetrics[jCell, iSpcA, 0] = ResultsOfIntegration[i, 0];
                            //cellMetrics[jCell, iSpcB, 0] = ResultsOfIntegration[i, 0];


                            for (int iSpc = 0; iSpc < NoOfSpc; iSpc++)
                            {
                                if (SpeciesBitMask[iSpc][jCell])
                                {
                                    cellMetrics[jCell, iSpc, 0] += ResultsOfIntegration[i, 0];
                                    Debug.Assert(!(double.IsNaN(cellMetrics[jCell, iSpc, 0]) || double.IsInfinity(cellMetrics[jCell, iSpc, 0])));
                                }
                            }
                        }
                    }).Execute();
                    //}
                }
            }

            // MPI exchange & store
            // ====================

            if (species.Length > 0)
            {
                vec_cellMetrics.MPIExchange(gd);
            }

            for (int iSpc = 0; iSpc < species.Length; iSpc++)
            {
                var spc = species[iSpc];
                this.InterfaceArea.Add(spc, cellMetrics.ExtractSubArrayShallow(-1, iSpc, 0).CloneAs());
                this.CutCellVolumes.Add(spc, cellMetrics.ExtractSubArrayShallow(-1, iSpc, 1).CloneAs());
            }

            //Console.WriteLine("Erinn - debug code.");
            //for(int j = 0; j < J; j++) {
            //    double totVol = gd.Cells.GetCellVolume(j);

            //    double blaVol = 0;
            //    for(int iSpc = 0; iSpc < species.Length; iSpc++) {
            //        var spc = species[iSpc];
            //        var cellVolS = this.CutCellVolumes[spc][j];
            //        blaVol += cellVolS;
            //    }

            //    Debug.Assert(Math.Abs(totVol - blaVol) / totVol < 1.0e-8);

            //}
        }
Example #3
0
        /// <summary>
        /// Computes Cell-volumes and edge areas before agglomeration.
        /// </summary>
        void ComputeNonAgglomeratedMetrics()
        {
            using (new FuncTrace()) {
                MPICollectiveWatchDog.Watch();
                var         gd      = XDGSpaceMetrics.GridDat;
                int         JE      = gd.iLogicalCells.Count;
                int         J       = gd.iLogicalCells.NoOfLocalUpdatedCells;
                int         D       = gd.SpatialDimension;
                int         EE      = gd.Edges.Count;
                SpeciesId[] species = this.SpeciesList.ToArray();
                int         NoSpc   = species.Count();
                int[,] E2C = gd.iLogicalEdges.CellIndices;

                var schH = new XQuadSchemeHelper(XDGSpaceMetrics);


                // collect all per-cell-metrics in the same MultidimArry, for MPI-exchange (only 1 exchange instead of three, saving some overhead)
                // 1st index: cell
                // 2nd index: species
                // 3rd index: 0 for interface surface per cell, 1 for cut-cell-volume, 2 for cut-cell surface
                double[] vec_cellMetrics          = new double[JE * NoSpc * 3];
                MultidimensionalArray cellMetrics = MultidimensionalArray.CreateWrapper(vec_cellMetrics, JE, NoSpc, 3);

                this.CutEdgeAreas   = new Dictionary <SpeciesId, MultidimensionalArray>();
                this.CutCellVolumes = new Dictionary <SpeciesId, MultidimensionalArray>();
                this.InterfaceArea  = new Dictionary <SpeciesId, MultidimensionalArray>();
                this.CellSurface    = new Dictionary <SpeciesId, MultidimensionalArray>();

                //var schS = new List<CellQuadratureScheme>();
                //var rulz = new List<ICompositeQuadRule<QuadRule>>();


                // edges and volumes
                // =================
                for (int iSpc = 0; iSpc < species.Length; iSpc++)
                {
                    var cellVol = cellMetrics.ExtractSubArrayShallow(-1, iSpc, 1);
                    var spc     = species[iSpc];


                    // compute cut edge area
                    // ---------------------
                    MultidimensionalArray edgArea = MultidimensionalArray.Create(EE);
                    this.CutEdgeAreas.Add(spc, edgArea);

                    var edgeScheme = schH.GetEdgeQuadScheme(spc);
                    var edgeRule   = edgeScheme.Compile(gd, this.CutCellQuadratureOrder);

                    BoSSS.Foundation.Quadrature.EdgeQuadrature.GetQuadrature(
                        new int[] { 1 }, gd,
                        edgeRule,
                        _Evaluate : delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) //
                    {
                        EvalResult.SetAll(1.0);
                    },
                        _SaveIntegrationResults : delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) //
                    {
                        for (int i = 0; i < Length; i++)
                        {
                            int iEdge = i + i0;
                            Debug.Assert(edgArea[iEdge] == 0);
                            edgArea[iEdge] = ResultsOfIntegration[i, 0];
                            Debug.Assert(!(double.IsNaN(edgArea[iEdge]) || double.IsInfinity(edgArea[iEdge])));
                        }
                    }).Execute();

                    // sum up edges for surface
                    // ------------------------

                    var cellSurf = cellMetrics.ExtractSubArrayShallow(-1, iSpc, 2);

                    for (int e = 0; e < EE; e++)
                    {
                        double a      = edgArea[e];
                        int    jCell0 = E2C[e, 0];
                        int    jCell2 = E2C[e, 1];
                        cellSurf[jCell0] += a;
                        if (jCell2 >= 0)
                        {
                            cellSurf[jCell2] += a;
                        }
                    }

                    // compute cut cell volumes
                    // ------------------------

                    var volScheme = schH.GetVolumeQuadScheme(spc);
                    var volRule   = volScheme.Compile(gd, this.CutCellQuadratureOrder);

                    BoSSS.Foundation.Quadrature.CellQuadrature.GetQuadrature(
                        new int[] { 1 }, gd,
                        volRule,
                        _Evaluate : delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) //
                    {
                        EvalResult.SetAll(1.0);
                    },
                        _SaveIntegrationResults : delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) //
                    {
                        for (int i = 0; i < Length; i++)
                        {
                            int jCell = i + i0;
                            Debug.Assert(cellVol[jCell] == 0);
                            cellVol[jCell] = ResultsOfIntegration[i, 0];
                            Debug.Assert(!(double.IsNaN(cellVol[jCell]) || double.IsInfinity(cellVol[jCell])));
                        }
                    }).Execute();
                }


                // interface surface
                // =================

                // loop over level-sets
                if (species.Length > 0)
                {
                    // find domain of all species:
                    CellMask SpeciesCommonDom = XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(species[0]);
                    for (int iSpc = 1; iSpc < species.Length; iSpc++)
                    {
                        SpeciesCommonDom = SpeciesCommonDom.Union(XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(species[iSpc]));
                    }
                    BitArray[] SpeciesBitMask = species.Select(spc => XDGSpaceMetrics.LevelSetRegions.GetSpeciesMask(spc).GetBitMask()).ToArray();

                    int NoOfLs  = XDGSpaceMetrics.NoOfLevelSets;
                    int NoOfSpc = species.Length;
                    for (int iLevSet = 0; iLevSet < NoOfLs; iLevSet++)
                    {
                        var LsDom          = XDGSpaceMetrics.LevelSetRegions.GetCutCellMask4LevSet(iLevSet);
                        var IntegrationDom = LsDom.Intersect(SpeciesCommonDom);

                        //if (IntegrationDom.NoOfItemsLocally > 0) { -> Doesn't work if Bjoerns HMF is used, eds up in an mpi dead lock
                        // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                        // this level-set is actually relevant for someone in 'species'
                        // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

                        CellQuadratureScheme SurfIntegration = schH.GetLevelSetquadScheme(iLevSet, IntegrationDom);
                        var rule = SurfIntegration.Compile(gd, this.CutCellQuadratureOrder);

                        BoSSS.Foundation.Quadrature.CellQuadrature.GetQuadrature(
                            new int[] { 1 }, gd,
                            rule,
                            _Evaluate : delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) {
                            EvalResult.SetAll(1.0);
                        },
                            _SaveIntegrationResults : delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) {
                            for (int i = 0; i < Length; i++)
                            {
                                int jCell = i + i0;



                                //if (cellMetrics[jCell, iSpcA, 0] != 0.0)
                                //    throw new NotSupportedException("More than one zero-level-set per cell is not supported yet.");
                                //if (cellMetrics[jCell, iSpcB, 0] != 0.0)
                                //    throw new NotSupportedException("More than one zero-level-set per cell is not supported yet.");

                                //cellMetrics[jCell, iSpcA, 0] = ResultsOfIntegration[i, 0];
                                //cellMetrics[jCell, iSpcB, 0] = ResultsOfIntegration[i, 0];


                                for (int iSpc = 0; iSpc < NoOfSpc; iSpc++)
                                {
                                    if (SpeciesBitMask[iSpc][jCell])
                                    {
                                        cellMetrics[jCell, iSpc, 0] += ResultsOfIntegration[i, 0];
                                        Debug.Assert(!(double.IsNaN(cellMetrics[jCell, iSpc, 0]) || double.IsInfinity(cellMetrics[jCell, iSpc, 0])));
                                    }
                                }
                            }
                        }).Execute();
                        //}
                    }
                }

                // MPI exchange & store
                // ====================

                if (species.Length > 0)
                {
#if DEBUG
                    int NoOfSpc       = species.Length;
                    var cellMetricsB4 = cellMetrics.ExtractSubArrayShallow(new[] { 0, 0, 0 }, new[] { J - 1, NoOfSpc - 1, 1 }).CloneAs();
#endif
                    vec_cellMetrics.MPIExchange(gd);
#if DEBUG
                    var cellMetricsComp = cellMetrics.ExtractSubArrayShallow(new[] { 0, 0, 0 }, new[] { J - 1, NoOfSpc - 1, 1 }).CloneAs();
                    cellMetricsComp.Acc(-1.0, cellMetricsB4);
                    Debug.Assert(cellMetricsComp.L2Norm() == 0.0);
#endif
                }
                for (int iSpc = 0; iSpc < species.Length; iSpc++)
                {
                    var spc = species[iSpc];
                    this.InterfaceArea.Add(spc, cellMetrics.ExtractSubArrayShallow(-1, iSpc, 0).CloneAs());
                    this.CutCellVolumes.Add(spc, cellMetrics.ExtractSubArrayShallow(-1, iSpc, 1).CloneAs());
                    this.CellSurface.Add(spc, cellMetrics.ExtractSubArrayShallow(-1, iSpc, 2).CloneAs());

                    this.CellSurface[spc].Acc(1.0, this.InterfaceArea[spc]);
                }
            }
        }