示例#1
0
        private double PerformSurfaceQuadrature(Modes mode, IQuadRuleFactory <QuadRule> volumeFactory, IQuadRuleFactory <QuadRule> edgeFactory, SubGrid cutCellGrid, int order, Stopwatch timer)
        {
            using (new FuncTrace()) {
                CellQuadratureScheme volInstr = new CellQuadratureScheme(
                    volumeFactory, cutCellGrid.VolumeMask);
                CellBoundaryQuadratureScheme edgeInstr = new CellBoundaryQuadratureScheme(
                    new CellBoundaryFromEdgeRuleFactory <CellBoundaryQuadRule>(
                        GridData, Grid.RefElements[0], edgeFactory),
                    cutCellGrid.VolumeMask);

                ScalarFieldLevelSetIntegrator quadrature = new ScalarFieldLevelSetIntegrator(
                    levelSetTracker,
                    SinglePhaseField,
                    volInstr.Compile(GridData, order),
                    edgeInstr.Compile(GridData, order),
                    order,
                    cutCellGrid,
                    0);

                timer.Start();
                double result = quadrature.ExecuteA().Storage.Sum();
                timer.Stop();

                return(result);
            }
        }
示例#2
0
        /// <summary>
        /// Calculates surface and volume quadrature rules in one step, which is faster when both rules
        /// are needed. Before calling GetSurfaceRule() or GetVolumeRule() to receive the respective factories, call
        /// CalculateComboQuadRuleSet(...).
        /// </summary>
        /// <param name="ComboRule"></param>
        public SayeGaussComboRuleFactory(ISayeGaussComboRule ComboRule, CellMask maxGrid)
        {
            comboRule = ComboRule;

            rulez = new[] {
                new List <ChunkRulePair <QuadRule> >(),
                new List <ChunkRulePair <QuadRule> >()
            };

            ComboStatus = new Status
            {
                Initialized      = false,
                Order            = -1,
                MaxGrid          = maxGrid,
                ReferenceElement = comboRule.RefElement
            };

            volumeRuleFactory = new SayeFactoryWrapper(
                CalculateComboQuadRuleSet,
                rulez[0],
                ComboStatus);
            surfaceRuleFactory = new SayeFactoryWrapper(
                CalculateComboQuadRuleSet,
                rulez[1],
                ComboStatus);
        }
        /// <summary>
        /// Calculates surface and volume quadrature rules in one step, which is faster when both rules
        /// are needed. Before calling GetSurfaceRule() or GetVolumeRule() to receive the respective factories, call
        /// CalculateComboQuadRuleSet(...).
        /// </summary>
        /// <param name="ComboRule"></param>
        public SayeGaussComboRuleFactory(ISayeGaussComboRule ComboRule, Mode recalculationMode)
        {
            comboRule = ComboRule;

            rulez = new[] {
                new List <ChunkRulePair <QuadRule> >(),
                new List <ChunkRulePair <QuadRule> >()
            };

            ComboStatus = new Status
            {
                initialized       = false,
                order             = 0,
                RecalculationMode = recalculationMode
            };

            volumeRuleFactory = new ComboFactoryWrapper(
                CalculateComboQuadRuleSet,
                rulez[0],
                comboRule.RefElement,
                ComboStatus,
                ComboFactoryWrapper.QuadratureType.Volume);
            surfaceRuleFactory = new ComboFactoryWrapper(
                CalculateComboQuadRuleSet,
                rulez[1],
                comboRule.RefElement,
                ComboStatus,
                ComboFactoryWrapper.QuadratureType.Surface);
        }
        /// <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;
        }
示例#5
0
 /// <summary>
 /// adds a factory to a quadrature scheme
 /// </summary>
 public static R AddFactory <R, TQuadRule, TDomain>(this R scheme, IQuadRuleFactory <TQuadRule> factory, TDomain domain = null)
     where R : QuadratureScheme <TQuadRule, TDomain>
     where TQuadRule : QuadRule
     where TDomain : ExecutionMask
 {
     scheme.AddFactoryDomainPair(factory, domain);
     return(scheme);
 }
 /// <summary>
 /// Alternative constructor that saves a single call to
 /// <see cref="QuadratureScheme{S,T}.AddFactoryDomainPair"/>
 /// </summary>
 /// <param name="useDefaultFactories"></param>
 /// <param name="factory"></param>
 /// <param name="domain"></param>
 public CellEdgeBoundaryQuadratureScheme(
     bool useDefaultFactories,
     IQuadRuleFactory <CellEdgeBoundaryQuadRule> factory,
     CellMask domain = null)
     : base(useDefaultFactories, domain)
 {
     AddFactoryDomainPair(factory, domain);
 }
示例#7
0
        private void WriteVolumeNodes(StreamWriter log, IQuadRuleFactory <QuadRule> ruleFactory, int order, SubGrid subGrid, ITestCase testCase, int selectedCell = -1)
        {
            foreach (var chunkRulePair in ruleFactory.GetQuadRuleSet(subGrid.VolumeMask, order))
            {
                foreach (int cell in chunkRulePair.Chunk.Elements)
                {
                    QuadRule rule = chunkRulePair.Rule;

                    MultidimensionalArray globalVertices = MultidimensionalArray.Create(
                        1, rule.NoOfNodes, Grid.SpatialDimension);
                    MultidimensionalArray metrics = levelSetTracker.DataHistories[0].Current.GetLevelSetNormalReferenceToPhysicalMetrics(
                        rule.Nodes, cell, 1);
                    GridData.TransformLocal2Global(rule.Nodes, cell, 1, globalVertices, 0);

                    if (selectedCell >= 0 && cell != selectedCell)
                    {
                        continue;
                    }

                    for (int k = 0; k < rule.NoOfNodes; k++)
                    {
                        double weight = rule.Weights[k];

                        if (testCase is ISurfaceTestCase)
                        {
                            // Use to get correct HMF weights in reference coordinate
                            // system (surface weights are already divided by $metrics
                            // to save this step in actual quadrature)
                            //weight *= metrics[0, k];
                        }

                        if (Grid.SpatialDimension == 2)
                        {
                            log.WriteLine(
                                "{0}\t{1}\t{2}\t{3}\t{4}",
                                cell,
                                k,
                                globalVertices[0, k, 0].ToString(formatInfo),
                                globalVertices[0, k, 1].ToString(formatInfo),
                                Math.Round(weight, 2).ToString(formatInfo));
                        }
                        else
                        {
                            log.WriteLine(
                                "{0}\t{1}\t{2}\t{3}\t{4}\t{5}",
                                cell,
                                k,
                                globalVertices[0, k, 0].ToString(formatInfo),
                                globalVertices[0, k, 1].ToString(formatInfo),
                                globalVertices[0, k, 2].ToString(formatInfo),
                                weight.ToString(formatInfo));
                        }
                    }
                }
            }
        }
示例#8
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="owner"></param>
 /// <param name="edgeRuleFactory"></param>
 /// <param name="mask"></param>
 public LambdaCellBoundaryQuadrature(
     LevelSetVolumeQuadRuleFactory owner, IQuadRuleFactory <CellBoundaryQuadRule> edgeRuleFactory, CellMask mask)
     : base(new int[] { owner.GetNumberOfLambdas(owner.lambdaBasis.MaxAbsoluteDegree) },
            owner.LevelSetData.GridDat,
            (new CellBoundaryQuadratureScheme(edgeRuleFactory, mask)).Compile(owner.LevelSetData.GridDat, owner.lambdaBasis.MaxAbsoluteDegree + 1),
            CoordinateSystem.Reference) //
 {
     this.owner       = owner;
     NoOfItemsLocally = mask.NoOfItemsLocally;
 }
示例#9
0
        /// <summary>
        /// Creates a new composite quadrature rules of minimal order
        /// <paramref name="order"/> from a single quadrature rule factory and
        /// an associated domain of integration.
        /// </summary>
        /// <typeparam name="TDomain">
        /// The type of the domain to be integrated over.
        /// </typeparam>
        /// <param name="ruleFactory">
        /// The quadrature rule factory to be used to create the quadrature
        /// rules for the given domain.
        /// </param>
        /// <param name="order">
        /// The minimal order of the quadrature rules to be used. See
        /// <see cref="IQuadRuleFactory{T}.GetQuadRuleSet"/>.
        /// </param>
        /// <param name="domain">
        /// The domain to be integrated over.
        /// </param>
        /// <returns>
        /// A composite rule containing the quadrature rules associated with
        /// all elements of the given domain.
        /// </returns>
        /// <remarks>
        /// The main specialty about the resulting composite rule is that the
        /// implementation guarantees that the sets of nodes and weights
        /// associated to the respective quadrature rules share the <b>same</b>
        /// objects of their contents are equal. This is allows for the
        /// optimization of the execution of the quadrature itself.
        /// </remarks>
        public static CompositeQuadRule <TQuadRule> Create <TDomain>(
            IQuadRuleFactory <TQuadRule> ruleFactory, int order, TDomain domain)
            where TDomain : ExecutionMask
        {
            CompositeQuadRule <TQuadRule> compositeRule = new CompositeQuadRule <TQuadRule>();
            // BEWARE: This check may cause nasty trouble in parallel runs
            // where a domain is only present on some domains and has thus been
            // removed by Björn
            //if (domain.NoOfItemsLocally == 0) {
            //    return compositeRule;
            //}
            var ruleSet = ruleFactory.GetQuadRuleSet(domain, order);

            var nodes    = new List <NodeSet>();
            var nodesMap = new Dictionary <MultidimensionalArray, int>();

            var weights    = new List <MultidimensionalArray>();
            var weightsMap = new Dictionary <MultidimensionalArray, int>();

            foreach (var chunkRulePair in ruleSet)
            {
                Chunk     chunk = chunkRulePair.Chunk;
                TQuadRule rule  = chunkRulePair.Rule;

                Debug.Assert(rule.Nodes.IsLocked, "Error in quadrature rule creation: factory delivered some rule non-locked node set.");

                int iNode;
                if (!nodesMap.TryGetValue(rule.Nodes, out iNode))
                {
                    // nodes must be added
                    nodes.Add(rule.Nodes);
                    iNode = nodes.Count - 1;
                    nodesMap.Add(rule.Nodes, iNode);
                }

                int iWeight;
                if (!weightsMap.TryGetValue(rule.Weights, out iWeight))
                {
                    // weights must be added
                    weights.Add(rule.Weights);
                    iWeight = weights.Count - 1;
                    weightsMap.Add(rule.Weights, iWeight);
                }

                // Make sure arrays are not only equal but identical (i.e.,
                // reference equals)
                rule.Nodes   = nodes[iNode];
                rule.Weights = weights[iWeight];

                compositeRule.chunkRulePairs.Add(
                    new ChunkRulePair <TQuadRule>(chunk, rule));
            }

            return(compositeRule);
        }
示例#10
0
 /// <summary>
 /// Allows to add factories to <see cref="FactoryChain"/>. Factories
 /// added <b>later</b> will <b>dominate</b> over the ones that have
 /// been added earlier. That is, in case of conflicts (more than one
 /// factory assigned to the same (sub-)domain), the one added later
 /// will be chosen.
 /// </summary>
 /// <param name="factory">
 /// The factory to be added.
 /// </param>
 /// <param name="domain">
 /// The domain on which <paramref name="factory"/> should act.
 /// </param>
 /// <param name="order">
 /// An optional order that overrides the order passed to
 /// <see cref="Compile"/>.
 /// </param>
 /// <returns>
 /// This object (to allow for fluent addition of multiple factories).
 /// </returns>
 public QuadratureScheme <TQuadRule, TDomain> AddFactoryDomainPair(
     IQuadRuleFactory <TQuadRule> factory, TDomain domain = null, int?order = null)
 {
     //
     if (factory == null)
     {
         throw new ArgumentNullException();
     }
     factoryChain.Add(new FactoryDomainPair(factory, domain, order));
     return(this);
 }
示例#11
0
 public RegularizedQuadRuleFactory(IQuadRuleFactory <QuadRule> baseFactory, LevelSetTracker tracker, int levSetIndex, RegularizationPolynomoial polynomial, double width)
 {
     this.baseFactory = baseFactory;
     this.polynomial  = polynomial;
     this.width       = width;
     this.tracker     = tracker;
     if (tracker.LevelSets.Count <= levSetIndex)
     {
         throw new ArgumentOutOfRangeException("Please specify a valid index for the level set.");
     }
     this.levSetIndex = levSetIndex;
 }
        /// <summary>
        /// Ctor
        /// </summary>
        public LevelSetEdgeSurfaceQuadRuleFactory(LevelSetTracker.LevelSetData lsData, IQuadRuleFactory <CellEdgeBoundaryQuadRule> edgeRuleFactory, JumpTypes jumpType)
        {
            //this.tracker = lsData.Tracker;
            this.levelSetIndex   = lsData.LevelSetIndex;
            this.edgeRuleFactory = edgeRuleFactory;
            this.jumpType        = jumpType;
            this.LevelSetData    = lsData;

            if (lsData.GridDat.Cells.RefElements.Length > 1)
            {
                throw new NotSupportedException("Currently no support for mixed-type grids.");
            }
        }
示例#13
0
        private void WriteSurfaceNodes(StreamWriter log, IQuadRuleFactory <QuadRule> ruleFactory, int order, SubGrid subGrid)
        {
            var edgeRules = ruleFactory.GetQuadRuleSet(
                levelSetTracker.Regions.GetCutCellSubGrid().AllEdgesMask, order);

            foreach (var chunkRulePair in edgeRules)
            {
                foreach (int edge in chunkRulePair.Chunk.Elements)
                {
                    QuadRule rule = chunkRulePair.Rule;

                    int cell = GridData.iGeomEdges.CellIndices[edge, 0];

                    NodeSet volumeVertices = new NodeSet(
                        GridData.iGeomCells.GetRefElement(cell),
                        rule.NoOfNodes, Grid.SpatialDimension);
                    Grid.RefElements[0].TransformFaceCoordinates(
                        GridData.iGeomEdges.FaceIndices[edge, 0], rule.Nodes, volumeVertices);
                    volumeVertices.LockForever();

                    MultidimensionalArray globalVertices = MultidimensionalArray.Create(
                        1, rule.NoOfNodes, Grid.SpatialDimension);
                    GridData.TransformLocal2Global(volumeVertices, cell, 1, globalVertices, 0);
                    for (int k = 0; k < rule.NoOfNodes; k++)
                    {
                        if (Grid.SpatialDimension == 2)
                        {
                            log.WriteLine(
                                "{0}\t{1}\t{2}\t{3}\t{4}",
                                cell,
                                k,
                                globalVertices[0, k, 0].ToString(formatInfo),
                                globalVertices[0, k, 1].ToString(formatInfo),
                                rule.Weights[k].ToString(formatInfo));
                        }
                        else
                        {
                            log.WriteLine(
                                "{0}\t{1}\t{2}\t{3}\t{4}\t{5}",
                                cell,
                                k,
                                globalVertices[0, k, 0].ToString(formatInfo),
                                globalVertices[0, k, 1].ToString(formatInfo),
                                globalVertices[0, k, 2].ToString(formatInfo),
                                rule.Weights[k].ToString(formatInfo));
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="owner"></param>
 /// <param name="edgeRuleFactory"></param>
 /// <param name="maxLambdaDegree"></param>
 /// <param name="mask"></param>
 public LambdaEdgeBoundaryQuadrature(
     LevelSetEdgeVolumeQuadRuleFactory owner,
     IQuadRuleFactory <CellEdgeBoundaryQuadRule> edgeRuleFactory,
     int maxLambdaDegree,
     CellMask mask)
     : base(
         new int[] { owner.GetNumberOfLambdas() },
         owner.LevelSetData.GridDat,
         (new CellEdgeBoundaryQuadratureScheme(false, edgeRuleFactory, mask)).Compile(owner.LevelSetData.GridDat, maxLambdaDegree),
         CoordinateSystem.Reference)
 {
     this.owner       = owner;
     noOfItemsLocally = mask.NoOfItemsLocally;
 }
        /// <summary>
        /// Constructs a wrapper for <paramref name="edgeRuleFactory"/>.
        /// </summary>
        /// <param name="context">Omnipresent context</param>
        /// <param name="edgeRuleFactory">
        /// The factory to be wrapped
        /// </param>
        /// <param name="s">
        /// some reference element of the grid, see <see cref="GridCommons.RefElements"/>
        /// </param>
        public CellBoundaryFromEdgeRuleFactory(IGridData context, RefElement s, IQuadRuleFactory <QuadRule> edgeRuleFactory)
        {
            this.context         = context;
            this.edgeRuleFactory = edgeRuleFactory;

            if (!context.iGeomEdges.EdgeRefElements.Contains(edgeRuleFactory.RefElement))
            {
                throw new ArgumentException("Edge rule factory required");
            }
            if (!context.iGeomCells.RefElements.Contains(s))
            {
                throw new ArgumentException("unknown simplex.");
            }

            this.RefElement = s;
        }
示例#16
0
        /// <summary>
        /// constructor.
        /// </summary>
        /// <param name="lsData">
        /// </param>
        /// <param name="edgeRuleFactory">
        /// Some factory that provides quadrature rules for the integration
        /// over
        /// \f[
        ///  \partial K \cap \{ \vec{x}; \varphi(\vec{x}) {\leq \atop \geq} 0 \}.
        /// \f]
        /// Here, \f$ \partial K\f$  the boundary of
        /// some cell \f$ K\f$  and
        /// \f$ \varphi\f$  denotes the level set function
        /// </param>
        /// <param name="surfaceRuleFactory">
        /// Some factory that provides quadrature rules for the integration
        /// over the zero level set, i.e.
        /// \f[
        ///   \{ \vec{x}; \varphi(\vec{x}) = 0 \} \cap K.
        /// \f]
        /// (ere, \f$ \partial K\f$  the boundary of some
        /// cell \f$ K\f$  and
        /// \f$ \varphi\f$  denotes the level set function
        /// </param>
        /// <param name="levSetIndex">
        /// Index of the considered level set in <paramref name="tracker"/>
        /// </param>

        public LevelSetVolumeQuadRuleFactory(
            LevelSetTracker.LevelSetData lsData,
            IQuadRuleFactory <CellBoundaryQuadRule> edgeRuleFactory,
            IQuadRuleFactory <QuadRule> surfaceRuleFactory,
            JumpTypes jumpType = JumpTypes.Heaviside)
        {
            if (jumpType == JumpTypes.Implicit)
            {
                throw new NotSupportedException();
            }

            this.levelSetIndex      = lsData.LevelSetIndex;
            this.edgeRuleFactory    = edgeRuleFactory;
            this.surfaceRuleFactory = surfaceRuleFactory;
            this.jumpType           = jumpType;
            this.LevelSetData       = lsData;
        }
示例#17
0
        /// <summary>
        /// Allows to add factories to <see cref="FactoryChain"/>. Factories
        /// added <b>later</b> will <b>dominate</b> over the ones that have
        /// been added earlier. That is, in case of conflicts (more than one
        /// factory assigned to the same (sub-)domain), the one added later
        /// will be chosen.
        /// </summary>
        /// <param name="factory">
        /// The factory to be added.
        /// </param>
        /// <param name="domain">
        /// The domain on which <paramref name="factory"/> should act.
        /// </param>
        /// <param name="order">
        /// An optional order that overrides the order passed to
        /// <see cref="Compile"/>.
        /// </param>
        /// <returns>
        /// This object (to allow for fluent addition of multiple factories).
        /// </returns>
        public QuadratureScheme <TQuadRule, TDomain> AddFactoryDomainPair(
            IQuadRuleFactory <TQuadRule> factory, TDomain domain = null, int?order = null)
        {
            //
            if (factory == null)
            {
                throw new ArgumentNullException();
            }
            if (domain != null)
            {
                if (domain.MaskType != MaskType.Geometrical)
                {
                    throw new ArgumentException("expecting geometrical mask");
                }
            }

            factoryChain.Add(new FactoryDomainPair(factory, domain, order));
            return(this);
        }
示例#18
0
        private double PerformVolumeQuadrature(Modes mode, IQuadRuleFactory <QuadRule> factory, SubGrid cutCellGrid, int order, Stopwatch timer)
        {
            using (new FuncTrace()) {
                ScalarFieldQuadrature quadrature;
                CellQuadratureScheme  quadInstr = new CellQuadratureScheme(
                    factory, cutCellGrid.VolumeMask);
                if (testCase is ISurfaceTestCase)
                {
                    quadrature = new ScalarFieldQuadrature(GridData, SinglePhaseField, quadInstr, order);
                }
                else
                {
                    quadrature = new ScalarFieldQuadrature(GridData, XDGField, quadInstr, order);
                }

                timer.Start();
                quadrature.Execute();
                timer.Stop();

                return(quadrature.Result);
            }
        }
示例#19
0
        /// <summary>
        /// Ctor.
        /// </summary>
        /// <param name="tracker"></param>
        /// <param name="iLevSet"></param>
        /// <param name="_SurfaceNodesOnZeroLevset">if true, the nodes for the surface integration are 'projected' onto the zero-level-set</param>
        /// <param name="_DoCheck">
        /// if true, the accuracy of the quadrature is checked after solution of the system
        /// </param>
        /// <param name="_LevelSetBoundaryLineFactory"></param>
        /// <param name="cellFaceFactory"></param>
        /// <param name="_UseGauß"></param>
        /// <param name="_UseStokes"></param>
        public LevelSetQuadRuleFactory2(LevelSetTracker.LevelSetData levelSetData,
                                        IQuadRuleFactory <CellBoundaryQuadRule> cellFaceFactory,
                                        IQuadRuleFactory <CellBoundaryQuadRule> _LevelSetBoundaryLineFactory,
                                        bool _UseStokes, bool _UseGauß,
                                        bool _SurfaceNodesOnZeroLevset = false,
                                        bool _DoCheck = false)
        {
            this.UseStokes    = _UseStokes;
            this.UseGauß      = _UseGauß;
            this.LevelSetData = levelSetData;

            this.SurfaceNodesOnZeroLevset = _SurfaceNodesOnZeroLevset;
            this.Docheck = _DoCheck;

            //if(_UseGauß && !object.ReferenceEquals(cellFaceFactory.RefElement, _LevelSetBoundaryLineFactory.RefElement))
            //    throw new ArgumentException("boundary factory and boundary lne factory must operate on the same reference element.");
            //if(_UseStokes && _LevelSetBoundaryLineFactory == null)
            //    throw new ArgumentException();

            this.Kref = cellFaceFactory.RefElement;
            if (!levelSetData.GridDat.Grid.RefElements.Contains(Kref, ReferenceComparer.Instance))
            {
                throw new ArgumentOutOfRangeException(
                          "simplex", "'simplex' must be a volume - reference element");
            }

            this.LevelSetIndex               = levelSetData.LevelSetIndex;
            this.cellFaceFactory             = cellFaceFactory;
            this.SurfaceNodesOnZeroLevset    = _SurfaceNodesOnZeroLevset;
            this.LevelSetBoundaryLineFactory = _LevelSetBoundaryLineFactory;

            int iKref = this.tracker.GridDat.Grid.RefElements.IndexOf(Kref);

            this.MaxGrid = levelSetData.GridDat.Cells.GetCells4Refelement(iKref).Intersect(
                levelSetData.Region.GetCutCellMask4LevSet(this.LevelSetIndex));
        }
示例#20
0
 public RegularizedQuadRuleFactory(IQuadRuleFactory <QuadRule> baseFactory, LevelSetTracker tracker, RegularizationPolynomoial polynomial, double width)
     : this(baseFactory, tracker, 0, polynomial, width)
 {
 }
示例#21
0
 /// <summary>
 /// adds a factory to an edge quadrature scheme
 /// </summary>
 public static EdgeQuadratureScheme AddFactory <TQuadRule>(this EdgeQuadratureScheme scheme, IQuadRuleFactory <TQuadRule> factory)
     where TQuadRule : QuadRule
 {
     scheme.AddFactoryDomainPair(factory, default(EdgeMask));
     return(scheme);
 }
示例#22
0
 /// <summary>
 /// Just stores the given values.
 /// </summary>
 /// <param name="ruleFactory">
 /// <see cref="RuleFactory"/>
 /// </param>
 /// <param name="domain">
 /// <see cref="Domain"/>
 /// </param>
 /// <param name="order">
 /// The desired order of the quadrature rule. Note that this is
 /// order not necessarily achieved by all
 /// <paramref name="ruleFactory"/>s
 /// </param>
 public FactoryDomainPair(IQuadRuleFactory <TQuadRule> ruleFactory, TDomain domain, int?order = null)
 {
     this.RuleFactory = ruleFactory;
     this.Domain      = domain;
     this.Order       = order;
 }
示例#23
0
        /// <summary>
        /// Generates a quadrature rule factory for the cut volume integrals.
        /// </summary>
        public IQuadRuleFactory <QuadRule> GetVolRuleFactory(int levSetIndex, JumpTypes jmp, RefElement Kref)
        {
            CheckJmp(jmp);
            var ctx = this.m_LevelSetDatas[levSetIndex].GridDat;

            if (jmp == JumpTypes.Heaviside)
            {
                if (m_SurfaceFactory == null)
                {
                    m_SurfaceFactory = new IQuadRuleFactory <QuadRule> [m_LevelSetDatas.Length];
                }
                if (m_VolumeFactory == null)
                {
                    m_VolumeFactory = new IQuadRuleFactory <QuadRule> [m_LevelSetDatas.Length];
                }

                if (m_VolumeFactory[levSetIndex] == null)
                {
                    switch (CutCellQuadratureType)
                    {
                    case MomentFittingVariants.Classic:
                        m_VolumeFactory[levSetIndex] = new LevelSetVolumeQuadRuleFactory(
                            this.m_LevelSetDatas[levSetIndex],
                            GetCellFaceFactory(levSetIndex, Kref),
                            GetSurfaceFactory(levSetIndex, Kref),
                            jumpType: jmp);
                        break;

                    case MomentFittingVariants.OneStepGauss:
                    case MomentFittingVariants.OneStepGaussAndStokes:
                    {
                        bool bStokes = CutCellQuadratureType == MomentFittingVariants.OneStepGaussAndStokes;
                        LevelSetComboRuleFactory2 ComboRuleFactroy = new LevelSetComboRuleFactory2(
                            this.m_LevelSetDatas[levSetIndex],
                            this.GetCellFaceFactory(levSetIndex, Kref),
                            bStokes ? this._GetSurfaceElement_BoundaryRuleFactory(levSetIndex, Kref) : null,
                            _UseAlsoStokes: bStokes,
                            _SurfaceNodesOnZeroLevset: false,
                            _DoCheck: CheckQuadRules);

                        m_VolumeFactory[levSetIndex]  = ComboRuleFactroy.GetVolumeFactory();
                        m_SurfaceFactory[levSetIndex] = ComboRuleFactroy.GetSurfaceFactory();
                        break;
                    }

                    case MomentFittingVariants.TwoStepStokesAndGauss:
                    case MomentFittingVariants.ExactCircle:
                    {
                        m_VolumeFactory[levSetIndex] = (new LevelSetVolumeQuadRuleFactory2b(Kref,
                                                                                            this.m_LevelSetDatas[levSetIndex],
                                                                                            GetCellFaceFactory(levSetIndex, Kref),
                                                                                            GetSurfaceFactory(levSetIndex, Kref),
                                                                                            jmp));
                        break;
                    }

                    case MomentFittingVariants.Saye:
                        var comboFactory = Quadrature.SayeFactories.SayeGaussRule_Combo(
                            this.m_LevelSetDatas[levSetIndex],
                            new LineSegment.SafeGuardedNewtonMethod(1e-14));
                        m_VolumeFactory[levSetIndex]  = comboFactory.GetVolumeFactory();
                        m_SurfaceFactory[levSetIndex] = comboFactory.GetSurfaceFactory();
                        break;

                    default:
                        throw new NotSupportedException(String.Format(
                                                            "Variant {0} not implemented.", CutCellQuadratureType));
                    }
                }

                return(m_VolumeFactory[levSetIndex]);
            }
            else if (jmp == JumpTypes.OneMinusHeaviside)
            {
                return(new ComplementaryRuleFactory(GetVolRuleFactory(levSetIndex, JumpTypes.Heaviside, Kref)));
            }
            else
            {
                throw new ArgumentOutOfRangeException("unsupported jump type");
            }
        }
示例#24
0
 /// <summary>
 /// Convenience constructor that allows for the construction of a
 /// scheme with a predefined factory. Equivalent to creating an empty
 /// scheme and calling
 /// <see cref="QuadratureScheme{S, T}.AddFactoryDomainPair"/>(<paramref name="factory"/>, <paramref name="domain"/>).
 /// </summary>
 /// <param name="factory">
 /// <see cref="QuadratureScheme{S, T}.AddFactoryDomainPair"/>
 /// </param>
 /// <param name="domain">
 /// <see cref="QuadratureScheme{S, T}.AddFactoryDomainPair"/>
 /// </param>
 public CellBoundaryQuadratureScheme(IQuadRuleFactory <CellBoundaryQuadRule> factory, CellMask domain = null)
     : base(false, domain)
 {
     AddFactoryDomainPair(factory, domain);
 }
示例#25
0
 /// <summary>
 /// adds a factory to a cell-boundary quadrature scheme
 /// </summary>
 public static CellBoundaryQuadratureScheme AddFactory <TQuadRule>(this CellBoundaryQuadratureScheme scheme, IQuadRuleFactory <TQuadRule> factory)
     where TQuadRule : CellBoundaryQuadRule
 {
     scheme.AddFactoryDomainPair(factory, default(CellMask));
     return(scheme);
 }
示例#26
0
 /// <summary>
 /// Convenience constructor that allows for the construction of a
 /// scheme with a predefined factory. Equivalent to creating an empty
 /// scheme and calling
 /// <see cref="QuadratureScheme{S, T}.AddFactoryDomainPair"/>(<paramref name="factory"/>, <paramref name="domain"/>).
 /// </summary>
 /// <param name="factory">
 /// <see cref="QuadratureScheme{S, T}.AddFactoryDomainPair"/>
 /// </param>
 /// <param name="domain">
 /// <see cref="QuadratureScheme{S, T}.AddFactoryDomainPair"/>
 /// </param>
 public EdgeQuadratureScheme(IQuadRuleFactory <QuadRule> factory, EdgeMask domain = null)
     : base(false, ConvDomain(domain))
 {
     AddFactoryDomainPair(factory, ConvDomain(domain));
 }
示例#27
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));
        }
 /// <summary>
 /// constructor
 /// </summary>
 public EdgeRuleFromCellBoundaryFactory(Grid.Classic.GridData g, IQuadRuleFactory <CellBoundaryQuadRule> cellBndQF, CellMask maxDomain)
 {
     m_cellBndQF = cellBndQF;
     grd         = g;
     m_maxDomain = maxDomain;
 }
示例#29
0
 public ComplementaryRuleFactory(IQuadRuleFactory <QuadRule> orgRule)
 {
     m_orgrule = orgRule;
 }
示例#30
0
 public LinearReconstructionQuadRuleFactory(LevelSetTracker tracker, LineAndPointQuadratureFactory lineAndPointFactory)
 {
     this.tracker     = tracker;
     this.rootFactory = lineAndPointFactory.GetPointFactory();
 }