/// <summary> /// Boundary quadrature for the surface elements, i.e. for each cut background-cell \f$ K_j \f$ a quadrature to approximate /// \f[ /// \int_{\partial K_j \cap \mathfrak{I} } \ldots \mathrm{dS} . /// \f] /// </summary> public EdgeQuadratureScheme GetEdgeQuadScheme(SpeciesId sp, bool UseDefaultFactories = true, EdgeMask IntegrationDomain = null, int?fixedOrder = null) { if (!this.SpeciesList.Contains(sp)) { throw new ArgumentException("Given species (id = " + sp.cntnt + ") is not supported."); } // determine domain // ================ var allRelevantEdges = GetEdgeMask(sp, IntegrationDomain); // create quadrature scheme // ======================== { // default rules for all edges: EdgeQuadratureScheme edgeQrIns = new EdgeQuadratureScheme(UseDefaultFactories, allRelevantEdges); // overwrite with cut-cell-rules in cut-cells: foreach (var Kref in XDGSpaceMetrics.GridDat.Grid.RefElements) { for (int iLevSet = 0; iLevSet < XDGSpaceMetrics.NoOfLevelSets; iLevSet++) // loop over level sets... { EdgeMask cutEdges = this.GetCutEdges(Kref, iLevSet).Intersect(allRelevantEdges); #if DEBUG CellMask difference = cutEdges.GetAdjacentCells(XDGSpaceMetrics.GridDat).Except(XDGSpaceMetrics.LevelSetRegions.GetCutCellMask4LevSet(iLevSet)); if (difference.Count() > 0) { throw new ArithmeticException("Edges of the Cells" + difference.GetSummary() + " are detected as cut, but these cells are not contained in the cut Cell-Mask of the Level-Set-Tracker"); } #endif var jmp = IdentifyWing(iLevSet, sp); var factory = this.XDGSpaceMetrics.XQuadFactoryHelper.GetEdgeRuleFactory(iLevSet, jmp, Kref); edgeQrIns.AddFactoryDomainPair(factory, cutEdges, fixedOrder); } } return(edgeQrIns); } }
/// <summary> /// Constructs the quadrature rules all edges of all cells in /// <paramref name="mask"/>. For edges that are not intersected by the /// zero iso-contour, standard Gaussian quadrature rules of /// sufficiently high order will be used. /// </summary> /// <param name="mask"> /// Cells for which quadrature rules shall be created /// </param> /// <param name="order"> /// Desired order of the moment-fitting system. Assuming that /// <see cref="edgeSurfaceRuleFactory"/> integrates the basis /// polynomials exactly over the zero iso-contour (which it usually /// doesn't!), the resulting quadrature rules will be exact up to this /// order. /// </param> /// <returns>A set of quadrature rules</returns> /// <remarks> /// Since the selected level set is generally discontinuous across cell /// boundaries, this method does not make use of the fact that /// neighboring cells share edges. That is, the optimization will be /// performed twice for each inner edge in <paramref name="mask"/>. /// </remarks> public IEnumerable <IChunkRulePair <CellBoundaryQuadRule> > GetQuadRuleSet(ExecutionMask mask, int order) { using (var tr = new FuncTrace()) { if (!(mask is CellMask)) { throw new ArgumentException("CellMask required", "mask"); } #if DEBUG CellMask differingCells = ((CellMask)mask).Except(this.LevelSetData.Region.GetCutCellMask4LevSet(this.levelSetIndex)); if (differingCells.NoOfItemsLocally > 0) { throw new ArgumentException("The provided mask has to be a sub-set of the cut cells. Cells " + differingCells.GetSummary() + " are not in the CutCellMaks of this tracker."); } #endif int noOfEdges = LevelSetData.GridDat.Grid.RefElements[0].NoOfFaces; subGrid = new SubGrid((CellMask)mask); localCellIndex2SubgridIndex = subGrid.LocalCellIndex2SubgridIndex; if (order != lastOrder) { cache.Clear(); SwitchOrder(order); } var result = new List <ChunkRulePair <CellBoundaryQuadRule> >(mask.NoOfItemsLocally); CellBoundaryQuadRule[] optimizedRules = GetOptimizedRules((CellMask)mask, order); int n = 0; foreach (Chunk chunk in mask) { foreach (int cell in chunk.Elements) { if (cache.ContainsKey(cell)) { result.Add(new ChunkRulePair <CellBoundaryQuadRule>( Chunk.GetSingleElementChunk(cell), cache[cell])); } else { cache.Add(cell, optimizedRules[n]); result.Add(new ChunkRulePair <CellBoundaryQuadRule>( Chunk.GetSingleElementChunk(cell), optimizedRules[n])); } n++; } } return(result); } }