/// <summary> /// Constructs a new factory /// </summary> /// <param name="tracker"> /// Tracker for the considered level set /// </param> /// <param name="Kref"> /// Reference element index /// </param> /// <param name="lsData"></param> /// <param name="rootFindingAlgorithm"> /// Selected root-finding algorithm for the line segments. Default is /// <see cref="LineSegment.DefaultRootFindingAlgorithm"/> /// </param> /// <param name="jumpType"> /// Determines the domain of integration, i.e. whether the rule should /// be valid for positive level set values, negative level set values, /// or even for both /// </param> /// <param name="tolerace"> /// Tolerance for the sign of the level set function. Using the example /// of <see cref="JumpTypes.Heaviside"/>, values phi with /// phi - Tolerance > 0 are considered 'positive'. /// </param> public CutLineQuadRuleFactory( LevelSetTracker.LevelSetData lsData, RefElement Kref, LineSegment.IRootFindingAlgorithm rootFindingAlgorithm = null, JumpTypes jumpType = JumpTypes.Heaviside, double tolerace = 1.0e-13) { this.RefElement = Kref; this.RootFindingAlgorithm = rootFindingAlgorithm ?? LineSegment.DefaultRootFindingAlgorithm; this.referenceLineSegments = GetReferenceLineSegments(); this.jumpType = jumpType; this.levelSetData = lsData; this.iKref = lsData.GridDat.Grid.RefElements.IndexOf(this.RefElement, (A, B) => object.ReferenceEquals(A, B)); if (this.iKref < 0) { throw new ArgumentException("Reference element cannot be found in the provided grid."); } this.levelSetIndex = lsData.LevelSetIndex; if (tolerace < 0.0) { throw new ArgumentOutOfRangeException(); } this.Tolerance = tolerace; emptyrule = CellBoundaryQuadRule.CreateEmpty(this.RefElement, 1, levelSetData.GridDat.SpatialDimension, referenceLineSegments.Length); // create a rule with just one node and weight zero; // this should avoid some special-case handling for empty rules emptyrule.NumbersOfNodesPerFace[0] = 1; emptyrule.Nodes.LockForever(); //tracker.Subscribe(this); }
/// <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; }
/// <summary> /// Constructor /// </summary> /// <param name="tracker"></param> /// <param name="levelSetIndex"></param> /// <param name="rootFindingAlgorithm"></param> /// <param name="jumpType"></param> public CutLineOnEdgeQuadRuleFactory(LevelSetTracker.LevelSetData __lsData, LineSegment.IRootFindingAlgorithm rootFindingAlgorithm = null, JumpTypes jumpType = JumpTypes.Heaviside) { if (__lsData.GridDat.SpatialDimension < 3) { throw new ArgumentException("Only applicable in 3d", "tracker"); } if (__lsData.GridDat.Cells.RefElements.Length > 1) { throw new NotSupportedException(); } this.lsData = __lsData; this.RootFindingAlgorithm = rootFindingAlgorithm ?? LineSegment.DefaultRootFindingAlgorithm; this.jumpType = jumpType; this.levelSetIndex = lsData.LevelSetIndex; this.referenceLineSegments = GetReferenceLineSegments(); //tracker.Subscribe(this); }
private Tuple <double, int, int> PerformConfiguration( Modes mode, int order, int division = 0, StreamWriter volumeNodesLog = null, StreamWriter surfaceNodesLog = null, int leafDivisions = -1, int vanishingMoment = -1, int continuousDerivative = -1, double width = double.NaN, double hBase = double.NaN, LineSegment.IRootFindingAlgorithm rootFindingAlgorithm = null, int logVolumeNodes_selectedCell = -1) { SubGrid cutCellGrid = levelSetTracker.Regions.GetCutCellSubGrid(); IQuadRuleFactory <QuadRule> volumeFactory = null; IQuadRuleFactory <QuadRule> edgeFactory = null; switch (mode) { case Modes.Standard: // { volumeFactory = new StandardQuadRuleFactory(Grid.RefElements[0]); edgeFactory = new StandardQuadRuleFactory( Grid.RefElements[0].FaceRefElement); break; } case Modes.BruteForce: // { volumeFactory = (IQuadRuleFactory <QuadRule>) new CutCellQuadRuleFactory( new BruteForceSubdivisionStrategy( Grid.RefElements[0], division), order); edgeFactory = new CutCellQuadRuleFactory( new BruteForceSubdivisionStrategy( Grid.RefElements[0].FaceRefElement, division), order); break; } case Modes.Adaptive: // { volumeFactory = (IQuadRuleFactory <QuadRule>) new CutCellQuadRuleFactory( new AdaptiveSubdivisionStrategy( Grid.RefElements[0], levelSetTracker.DataHistories[0].Current, division), leafDivisions); edgeFactory = new CutCellQuadRuleFactory( new AdaptiveSubdivisionStrategy( Grid.RefElements[0].FaceRefElement, levelSetTracker.DataHistories[0].Current, division), leafDivisions); break; } case Modes.Regularized: // { volumeFactory = new RegularizedQuadRuleFactory( new StandardQuadRuleFactory(Grid.RefElements[0]), levelSetTracker, testCase.GetPolynomial(vanishingMoment, continuousDerivative), 0.5 * width * hBase); edgeFactory = null; break; } case Modes.HMFClassic: // { IQuadRuleFactory <CellBoundaryQuadRule> volumeRuleFactoryEdge; if (Grid.SpatialDimension == 2) { LineAndPointQuadratureFactory bndrule = new LineAndPointQuadratureFactory( this.Grid.RefElements[0], levelSetTracker.DataHistories[0].Current, true, rootFindingAlgorithm); volumeRuleFactoryEdge = bndrule.GetLineFactory(); //volumeRuleFactoryEdge = new CutLineQuadRuleFactory( // levelSetTracker, // Grid.RefElements[0], // rootFindingAlgorithm: rootFindingAlgorithm); } else { volumeRuleFactoryEdge = new LevelSetEdgeVolumeQuadRuleFactory( levelSetTracker.DataHistories[0].Current, rootFindingAlgorithm, JumpTypes.Heaviside); } LevelSetSurfaceQuadRuleFactory surfaceFactory = new LevelSetSurfaceQuadRuleFactory( levelSetTracker.DataHistories[0].Current, volumeRuleFactoryEdge); if (testCase is ISurfaceTestCase) { volumeFactory = surfaceFactory; } else { volumeFactory = new LevelSetVolumeQuadRuleFactory( levelSetTracker.DataHistories[0].Current, volumeRuleFactoryEdge, surfaceFactory, JumpTypes.Heaviside); } edgeFactory = null; break; } case Modes.HMFOneStepGauss: // { if (Grid.SpatialDimension != 2) { throw new NotImplementedException(); } LineAndPointQuadratureFactory bndrule = new LineAndPointQuadratureFactory( this.Grid.RefElements[0], levelSetTracker.DataHistories[0].Current, true, rootFindingAlgorithm); LevelSetComboRuleFactory2 Factory = new LevelSetComboRuleFactory2( levelSetTracker.DataHistories[0].Current, bndrule.GetLineFactory(), null, _SurfaceNodesOnZeroLevset: false, _UseAlsoStokes: false, _DoCheck: false); if (testCase is ISurfaceTestCase) { volumeFactory = Factory.GetSurfaceFactory(); } else { volumeFactory = Factory.GetVolumeFactory(); } edgeFactory = null; break; } case Modes.HMFOneStepGaussAndStokes: // { if (Grid.SpatialDimension != 2) { throw new NotImplementedException(); } LineAndPointQuadratureFactory bndrule = new LineAndPointQuadratureFactory( this.Grid.RefElements[0], levelSetTracker.DataHistories[0].Current, true, rootFindingAlgorithm); LevelSetComboRuleFactory2 Factory = new LevelSetComboRuleFactory2( levelSetTracker.DataHistories[0].Current, bndrule.GetLineFactory(), bndrule.GetPointFactory(), _SurfaceNodesOnZeroLevset: false, _UseAlsoStokes: true, _DoCheck: false); if (testCase is ISurfaceTestCase) { volumeFactory = Factory.GetSurfaceFactory(); } else { volumeFactory = Factory.GetVolumeFactory(); } edgeFactory = null; break; } case Modes.SayeGaussRules: // { SayeGaussComboRuleFactory FactoryFactory = SayeFactories.SayeGaussRule_Combo( levelSetTracker.DataHistories[0].Current, rootFindingAlgorithm ); if (testCase is ISurfaceTestCase) { volumeFactory = FactoryFactory.GetSurfaceFactory(); } else { volumeFactory = FactoryFactory.GetVolumeFactory(); } edgeFactory = null; break; } case Modes.EquivalentPolynomials: // { var lineAndPointFactory = new LineAndPointQuadratureFactory( Grid.RefElements[0], levelSetTracker.DataHistories[0].Current, true, rootFindingAlgorithm); if (testCase is ISurfaceTestCase) { volumeFactory = new LinearReconstructionQuadRuleFactory( levelSetTracker, lineAndPointFactory); } else { volumeFactory = new EquivalentPolynomialQuadRuleFactory( new StandardQuadRuleFactory(Grid.RefElements[0]), levelSetTracker, lineAndPointFactory); } edgeFactory = null; break; } } if (volumeNodesLog != null) { WriteVolumeNodes(volumeNodesLog, volumeFactory, order, cutCellGrid, testCase, logVolumeNodes_selectedCell); } if (surfaceNodesLog != null) { WriteSurfaceNodes(surfaceNodesLog, edgeFactory, order, cutCellGrid); } Stopwatch timer = new Stopwatch(); Stopwatch localTimer = new Stopwatch(); double result = double.NaN; timer.Start(); if (testCase is IVolumeTestCase || mode == Modes.Regularized || mode == Modes.HMFClassic || mode == Modes.HMFOneStepGauss || mode == Modes.HMFOneStepGaussAndStokes || mode == Modes.EquivalentPolynomials || mode == Modes.SayeGaussRules) { result = PerformVolumeQuadrature( mode, volumeFactory, cutCellGrid, order, localTimer); } else { result = PerformSurfaceQuadrature( mode, volumeFactory, edgeFactory, cutCellGrid, order, localTimer); } timer.Stop(); return(new Tuple <double, int, int>( result, (int)timer.ElapsedMilliseconds, (int)localTimer.ElapsedMilliseconds)); }
public MakeshiftCutLineQuadRuleFactory(LevelSetTracker tracker, int levSetIndex, LineSegment.IRootFindingAlgorithm rootFindingAlgorithm) { this.tracker = tracker; if (tracker.LevelSets.Count <= levSetIndex) { throw new ArgumentOutOfRangeException("Please provide a valid index for the level set."); } this.levSetIndex = levSetIndex; this.RootFindingAlgorithm = rootFindingAlgorithm; this.referenceLineSegments = GetReferenceLineSegments(); }