/// <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); } }
/// <summary> /// ctor. /// </summary> /// <param name="__AgglomerationTreshold">see <see cref="AgglomerationThreshold"/></param> /// <param name="oldTs__AgglomerationTreshold"> /// Agglomeration thresholds for _previous_ timesteps, correlates with <paramref name="oldCcm"/>. /// </param> /// <param name="AgglomerateNewborn"> /// 'Newborn' cut-cells /// are agglomerated to cells which already exist in the previous timestep. /// </param> /// <param name="AgglomerateDecased"> /// 'Deceased' cut-cells are agglomerated to cells which exist in the next timestep. /// </param> /// <param name="ExceptionOnFailedAgglomeration"> /// If true, an exception is thrown for /// any cell which should be agglomerated, if no neighbour is found. /// </param> /// <param name="NewbornAndDecasedThreshold"> /// Volume fraction threshold at which a cut-cell counts as newborn, resp. deceased, see <paramref name="AgglomerateNewbornAndDeceased"/>; /// </param> /// <param name="CutCellsQuadOrder"></param> /// <param name="CutCellsQuadType"></param> /// <param name="lsTrk"></param> internal MultiphaseCellAgglomerator( LevelSetTracker lsTrk, SpeciesId[] Spc, int CutCellsQuadOrder, double __AgglomerationTreshold, bool AgglomerateNewborn = false, bool AgglomerateDecased = false, bool ExceptionOnFailedAgglomeration = true, double[] oldTs__AgglomerationTreshold = null, double NewbornAndDecasedThreshold = 1.0e-6) { if (__AgglomerationTreshold < 0.0 || __AgglomerationTreshold >= 1.0) throw new ArgumentOutOfRangeException(); if (NewbornAndDecasedThreshold < 0.0 || NewbornAndDecasedThreshold >= 1.0) throw new ArgumentOutOfRangeException(); this.Tracker = lsTrk; this.XDGSpaceMetrics = lsTrk.GetXDGSpaceMetrics(Spc, CutCellsQuadOrder, 1); this.NonAgglomeratedMetrics = lsTrk.GetXDGSpaceMetrics(Spc, CutCellsQuadOrder, 1).CutCellMetrics; this.AgglomerationThreshold = __AgglomerationTreshold; this.AgglomerationThreshold_Oldtimesteps = oldTs__AgglomerationTreshold; CutCellMetrics[] oldCcm; if (AgglomerateNewborn || AgglomerateDecased) { oldCcm = new CutCellMetrics[oldTs__AgglomerationTreshold.Length]; for (int iHistory = 0; iHistory < oldCcm.Length; iHistory++) { oldCcm[iHistory] = lsTrk.GetXDGSpaceMetrics(Spc, CutCellsQuadOrder, -iHistory).CutCellMetrics; } } else { oldCcm = null; } if ((oldCcm == null) != (oldTs__AgglomerationTreshold == null)) { throw new ArgumentException(); } if (oldCcm != null) { if (oldCcm.Length != oldTs__AgglomerationTreshold.Length) throw new ArgumentException(); foreach (double alpha in oldTs__AgglomerationTreshold) { if (alpha < 0.0 || alpha >= 1.0) throw new ArgumentOutOfRangeException(); } } //var fullCel = CellMask.GetFullMask(this.Tracker.GridDat); //var fullEdg = EdgeMask.GetFullMask(this.Tracker.GridDat); //foreach (string spc in new string[] { "A", "B" }) { // SpeciesId spId = this.Tracker.GetSpeciesId(spc); // var Vol = this.NonAgglomeratedMetrics.CutCellVolumes[spId]; // var Edg = this.NonAgglomeratedMetrics.CutEdgeAreas[spId]; // fullCel.ToTxtFile("CellVol-" + spc + ".csv", false, ((double[] CoordGlobal, int ItemIndex) => Vol[ItemIndex])); // fullEdg.ToTxtFile("EdgeArea-" + spc + ".csv", false, ((double[] CoordGlobal, int ItemIndex) => Edg[ItemIndex])); //} // perform agglomeration foreach (var spc in this.SpeciesList) { IEnumerable<Tuple<int, int>> ai = FindAgglomeration( this.Tracker, spc, AgglomerationThreshold, this.NonAgglomeratedMetrics.CutCellVolumes[spc], this.NonAgglomeratedMetrics.CutEdgeAreas[spc], AgglomerateNewborn, AgglomerateDecased, ExceptionOnFailedAgglomeration, oldCcm != null ? oldCcm.Select(a => a.CutCellVolumes[spc]).ToArray() : null, oldTs__AgglomerationTreshold, NewbornAndDecasedThreshold); var m_agglomeration = new CellAgglomerator(this.Tracker.GridDat, ai); this.DictAgglomeration.Add(spc, m_agglomeration); } this.TotalNumberOfAgglomerations = this.DictAgglomeration.Values.Sum(agg => agg.TotalNumberOfAgglomerations); // compute metrics of AGGLOMERATED cut cells this.LengthScaleAgg(); }