示例#1
0
        /// <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;
        }
示例#3
0
        /// <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);
        }
示例#4
0
        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));
        }
示例#5
0
 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();
 }