/// <summary> /// For each edge \f$ E\f$ of each cell in /// the given range and for each /// \f$ \vec{\Lambda}\f$ in /// <see cref="LevelSetEdgeVolumeQuadRuleFactory.lambdaBasis"/>: /// Computes /// \f$ /// \int_{ \{ \vec{x}; \varphi(\vec{x}) = 0 \} \cap E} \vec{\Lambda} \cdot \vec{n}_I \;ds, /// \f$ /// where \f$ \varphi\f$ is the level set /// function and \f$ \vec{n}_I\f$ denotes the /// unit normal vector on /// \f$ \varphi \cap E\f$ /// (<b>not</b> \f$ E\f$ !) /// </summary> /// <param name="i0"></param> /// <param name="Length"></param> /// <param name="NoOfNodes"></param> /// <param name="EvalResult"></param> protected override void Evaluate(int i0, int Length, CellBoundaryQuadRule CBQR, MultidimensionalArray EvalResult) { NodeSet QuadNodes = CBQR.Nodes; int D = gridData.SpatialDimension; for (int i = 0; i < Length; i++) { MultidimensionalArray lambdaValues = owner.EvaluateLambdas(i0 + i, CurrentRule); int nodeIndex = -1; for (int e = 0; e < gridData.iGeomCells.RefElements[0].NoOfFaces; e++) { MultidimensionalArray levelSetNormals = LevelSetEdgeSurfaceQuadRuleFactory.EvaluateRefNormalsOnEdge(this.owner.LevelSetData, i0 + i, CurrentRule, e); //MultidimensionalArray metrics = LevelSetEdgeSurfaceQuadRuleFactory.GetMetricTermsOnEdge( // owner.tracker, owner.levSetInd, CurrentRule, i0 + i, e); for (int j = 0; j < CurrentRule.NumbersOfNodesPerFace[e]; j++) { nodeIndex++; for (int k = 0; k < IntegralCompDim[0]; k++) { for (int d = 0; d < D; d++) { EvalResult[i, nodeIndex, k] += lambdaValues[nodeIndex, k, d] * levelSetNormals[j, d]; } //EvalResult[i, nodeIndex, k] *= metrics[j]; } } } } }
/// <summary> /// Constructor /// </summary> /// <param name="lsData"></param> /// <param name="rootFindingAlgorithm"> /// One-dimensional root-finding algorithm for determining roots of the /// level set function on edges of the edges of the volume simplex. /// Default is <see cref="LineSegment.DefaultRootFindingAlgorithm"/> /// </param> /// <param name="jumpType"> /// Determines the level set region to be integrated over (negative /// level set values, positive level set values, or both) /// </param> public LevelSetEdgeVolumeQuadRuleFactory( LevelSetTracker.LevelSetData lsData, LineSegment.IRootFindingAlgorithm rootFindingAlgorithm = null, JumpTypes jumpType = JumpTypes.Heaviside) { if (lsData.GridDat.Cells.RefElements.Length > 1) { throw new NotImplementedException( "Multiple reference elements currently not supported"); } this.LevelSetData = lsData; this.jumpType = jumpType; this.levelSetIndex = lsData.LevelSetIndex; CoFaceQuadRuleFactory = new CutLineOnEdgeQuadRuleFactory(lsData, rootFindingAlgorithm, jumpType); edgeSurfaceRuleFactory = new LevelSetEdgeSurfaceQuadRuleFactory(lsData, CoFaceQuadRuleFactory, jumpType); // Use vertices; Since it is only used on edges that are considered // uncut, they _should_ all have the same sign RefElement simplex = LevelSetData.GridDat.Grid.RefElements[0]; RefElement edgeSimplex = simplex.FaceRefElement; QuadRule signEdgeRule = new QuadRule() { Nodes = edgeSimplex.Vertices, Weights = MultidimensionalArray.Create(edgeSimplex.NoOfVertices) }; signTestRule = new CellBoundaryFromEdgeRuleFactory <CellBoundaryQuadRule>( LevelSetData.GridDat, simplex, new FixedRuleFactory <QuadRule>(signEdgeRule)). GetQuadRuleSet(new CellMask(LevelSetData.GridDat, Chunk.GetSingleElementChunk(0)), -1). First().Rule; }
public PhiQuadrature(LevelSetTracker.LevelSetData lsData, LevelSetEdgeSurfaceQuadRuleFactory owner, int maxPhiDegree, int element) : base( new int[] { owner.GetNumberOfPhis() }, lsData.GridDat, new CellEdgeBoundaryQuadratureScheme( false, owner.edgeRuleFactory, new CellMask(lsData.GridDat, Chunk.GetSingleElementChunk(element), MaskType.Geometrical)) .Compile(lsData.GridDat, maxPhiDegree), CoordinateSystem.Reference) { this.LevelSetData = lsData; this.owner = owner; if (lsData.GridDat.Cells.RefElements.Length > 1) { throw new NotSupportedException(); } }