예제 #1
0
        /// <summary>
        /// Retrieves all polynomial for the given <paramref name="element"/>
        /// that must be an element of <paramref name="refElements"/>
        /// </summary>
        /// <param name="g"></param>
        /// <param name="element"></param>
        /// <param name="p"></param>
        /// <returns></returns>
        private static IEnumerable <Polynomial> GetPolynomials(
            GridData g, RefElement element, int p)
        {
            //var ret = new IEnumerable<Polynomial>[refElements.Length];

            int D = element.SpatialDimension;

            // hotfix to get the correct spatial dimension on all polynomials:
            var P = GetPolynomials(element, p).ToArray();

            for (int iP = 0; iP < P.Length; iP++)
            {
                if (P[iP].Coeff.Length == 0)
                {
                    Debug.Assert(P[iP].Exponents.GetLength(0) == 0);
                    P[iP].Exponents = new int[0, D];
                }
            }

            //for (int i = 0; i < ret.Length; i++) {
            //    if (object.ReferenceEquals(refElements[i], element)) {
            //        ret[i] = P;
            //    } else {
            //        ret[i] = new Polynomial[P.Count()];
            //    }
            //}

            return(P);
        }
            public EdgeMask GetEdges4RefElement(RefElement Kref)
            {
                if (m_Edges4RefElement == null)
                {
                    m_Edges4RefElement = new EdgeMask[this.EdgeRefElements.Length];
                }

                int iKref = this.EdgeRefElements.IndexOf(Kref, (a, b) => object.ReferenceEquals(a, b));

                if (m_Edges4RefElement[iKref] == null)
                {
                    EdgeMask parrEdg = m_Owner.ParentGrid.iGeomEdges.GetEdges4RefElement(Kref);
                    EdgeMask thisAll = EdgeMask.GetFullMask(this.m_Owner, MaskType.Geometrical);
                    if (parrEdg.MaskType != MaskType.Geometrical)
                    {
                        throw new ApplicationException("expecting a geometrical mask");
                    }
                    if (thisAll.MaskType != MaskType.Geometrical)
                    {
                        throw new ApplicationException("expecting a geometrical mask");
                    }

                    BitArray parrBitmask = parrEdg.GetBitMask().CloneAs();
                    BitArray thisBitMask = thisAll.GetBitMask();
                    Debug.Assert(parrBitmask.Length == thisBitMask.Length);

                    BitArray intersect = parrBitmask.And(thisBitMask);
                    Debug.Assert(object.ReferenceEquals(intersect, parrBitmask));

                    m_Edges4RefElement[iKref] = new EdgeMask(m_Owner, intersect, MaskType.Geometrical);
                }

                return(m_Edges4RefElement[iKref]);
            }
        /// <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;
        }
예제 #4
0
            /// <summary>
            /// Cell-Mask of all cells which share the same reference element.
            /// </summary>
            public CellMask GetCells4Refelement(RefElement Kref)
            {
                var KRefs = this.RefElements;
                int iKref = KRefs.IndexOf(Kref, (A, B) => object.ReferenceEquals(A, B));

                if (iKref < 0 || iKref >= KRefs.Length)
                {
                    throw new ArgumentException();
                }

                if (m_RefElementMask == null)
                {
                    m_RefElementMask = new CellMask[KRefs.Length];
                }

                if (iKref < 0 || iKref >= KRefs.Length)
                {
                    throw new ArgumentOutOfRangeException();
                }

                if (m_RefElementMask[iKref] == null)
                {
                    int      J  = this.NoOfLocalUpdatedCells;
                    BitArray ba = new BitArray(J);

                    for (int j = 0; j < J; j++)
                    {
                        ba[j] = (this.GetRefElementIndex(j) == iKref);
                    }

                    m_RefElementMask[iKref] = new CellMask(this.m_owner, ba);
                }

                return(m_RefElementMask[iKref]);
            }
예제 #5
0
            /// <summary>
            /// Defines a mapping between BoSSS elements (<see cref="RefElement"/>)
            /// and the Tecplot representations.
            /// </summary>
            /// <returns>The Tecplot zone type for the current grid</returns>
            private ZoneType GetZoneType(RefElement Kref)
            {
                ZoneType zoneType;

                if (Kref.GetType() == typeof(Line))
                {
                    zoneType = ZoneType.FELineSeg;
                }
                else if (Kref.GetType() == typeof(Square))
                {
                    zoneType = ZoneType.FEQuad;
                }
                else if (Kref.GetType() == typeof(Triangle))
                {
                    zoneType = ZoneType.FETriangle;
                }
                else if (Kref.GetType() == typeof(Cube))
                {
                    zoneType = ZoneType.FEBrick;
                }
                else if (Kref.GetType() == typeof(Tetra))
                {
                    zoneType = ZoneType.FETetrahedron;
                }
                else
                {
                    throw new NotSupportedException(Kref.GetType().ToString() + " - simplex currently not supported in tecplot.");
                }
                return(zoneType);
            }
예제 #6
0
        /// <summary>
        /// Transformation matrices, for cell subdivision, as computed by <see cref="RefElement.SubdivisionTreeNode.GetBasisTrafo(int)"/>,
        /// are cached by this method.
        /// </summary>
        /// <param name="iKref">Reference element index, correlates with 1st index of <see cref="KrefS_SubdivLeaves"/>.</param>
        /// <param name="iSubdiv">Subdivision leaf index, correlates with 2nd index of <see cref="KrefS_SubdivLeaves"/>.</param>
        /// <param name="p">Requested polynomial degree.</param>
        /// <returns></returns>
        public MultidimensionalArray GetSubdivBasisTransform(int iKref, int iSubdiv, int p)
        {
            if (Subdiv_BasisTransform == null)
            {
                Subdiv_BasisTransform = new MultidimensionalArray[KrefS_SubdivLeaves.Length][];
            }

            if (Subdiv_BasisTransform[iKref] == null)
            {
                Subdiv_BasisTransform[iKref] = new MultidimensionalArray[KrefS_SubdivLeaves[iKref].Length];
            }

            RefElement Kref = KrefS_SubdivLeaves[iKref][0].RefElement;
            int        Np   = Kref.GetNoOfOrthonormalPolynomialsUptoDegree(p);

            if (Subdiv_BasisTransform[iKref][iSubdiv] == null || Subdiv_BasisTransform[iKref][iSubdiv].NoOfCols < Np)
            {
                Subdiv_BasisTransform[iKref][iSubdiv] = KrefS_SubdivLeaves[iKref][iSubdiv].GetBasisTrafo(p);
            }

            if (Subdiv_BasisTransform[iKref][iSubdiv].NoOfCols >= Np)
            {
                return(Subdiv_BasisTransform[iKref][iSubdiv].ExtractSubArrayShallow(new[] { 0, 0 }, new[] { Np - 1, Np - 1 }));
            }
            else
            {
                Debug.Assert(Subdiv_BasisTransform[iKref][iSubdiv].NoOfCols == Np);
                Debug.Assert(Subdiv_BasisTransform[iKref][iSubdiv].NoOfRows == Np);
                return(Subdiv_BasisTransform[iKref][iSubdiv]);
            }
        }
예제 #7
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);
        }
예제 #8
0
파일: ElementTests.cs 프로젝트: xyuan/BoSSS
        public void Bla([Values(0, 1, 2, 3)] int refElementIndex, [Values(0, 1, 2)] int foreignTypeIndex)
        {
            RefElement Element = ListElementsMain.Elements[refElementIndex];

            RefElement.ExchangeFormats ft = ListElementsMain.ForeignTypes[foreignTypeIndex];

            foreach (var type in Element.SupportedCellTypes)
            {
                try {
                    int    fnum;
                    string fname;
                    Element.GetForeignElementType(type, ft, out fname, out fnum);
                } catch (NotSupportedException) {
                    // Combination of element type and foreign convection
                    // simply does not exist, swallow exception.
                }

                // Check any of these methods throws an exception
                MultidimensionalArray InterpolationNodes = Element.GetInterpolationNodes(type);
                int[] NodeType    = Element.GetInterpolationNodes_NodeType(type);
                int[] EntityIndex = Element.GetInterpolationNodes_EntityIndices(type);
                int   NoOfNodes   = InterpolationNodes.GetLength(0);
                var   R           = Element.GetForeignElementMapping(type, ft);
            }
        }
예제 #9
0
        /// <summary>
        /// Constructs a new segment with the given start and end points
        /// </summary>
        /// <param name="spatialDimension">
        /// The spatial dimension of start and end points
        /// </param>
        /// <param name="start">
        /// The start point of the segment
        /// </param>
        /// <param name="end">
        /// The end point of the segment
        /// </param>
        /// <param name="iVertexStart">
        /// Optional vertex index of the start point in some list of vertices
        /// containing <paramref name="start"/>. Used by some callers to evade
        /// equality comparisons of double values.
        /// </param>
        /// <param name="iVertexEnd">
        /// Optional vertex index of the end point in some list of vertices
        /// containing <paramref name="end"/>. Used by some callers to evade
        /// equality comparisons of double values.
        /// </param>
        /// <param name="Kräf">
        /// Reference element.
        /// </param>
        /// <param name="rootFindingAlgorithm">
        /// The desired root finding algorithm. By default,
        /// <see cref="DefaultRootFindingAlgorithm"/> will be used.
        /// </param>
        public LineSegment(
            int spatialDimension,
            RefElement Kräf,
            Vector start,
            Vector end,
            int iVertexStart = -1,
            int iVertexEnd   = -1,
            IRootFindingAlgorithm rootFindingAlgorithm = null)
        {
            if (start.Dim != spatialDimension)
            {
                throw new ArgumentException();
            }
            if (end.Dim != spatialDimension)
            {
                throw new ArgumentException();
            }

            this.m_Kref          = Kräf;
            this.iVertexStart    = iVertexStart;
            this.iVertexEnd      = iVertexEnd;
            this.Start           = start;
            this.End             = end;
            RootFindingAlgorithm = rootFindingAlgorithm ?? DefaultRootFindingAlgorithm;
        }
예제 #10
0
 /// <summary>
 /// Constructs a quad rule factory using the given subdivision
 /// strategy.
 /// </summary>
 /// <param name="subdivisionStrategy">
 /// <see cref="SubdivisionStrategy"/>
 /// </param>
 /// <param name="leafDivisions">
 /// The additional number of subdivisions for the quadrature rule to be
 /// used in cut leaves (see <see cref="SubdivisionNode.IsCut"/>).
 /// </param>
 public CutCellQuadRuleFactory(ISubdivisionStrategy subdivisionStrategy, int leafDivisions)
 {
     SubdivisionStrategy = subdivisionStrategy;
     if (leafDivisions >= 0)
     {
         cutNodeRule = RefElement.GetBruteForceQuadRule(leafDivisions, 1);
     }
 }
예제 #11
0
 /// <summary>
 /// ctor.
 /// </summary>
 public StandardDoubleEdgeRuleFactory(IGridData g, RefElement KrefEdge)
 {
     if (!g.iGeomEdges.EdgeRefElements.Contains(KrefEdge, (a, b) => object.ReferenceEquals(a, b)))
     {
         throw new ArgumentException("The reference element provided is not an edge reference element of the given grid.", "KrefEdge");
     }
     this.RefElement = KrefEdge;
 }
예제 #12
0
        /// <summary>
        /// Creates an empty rule.
        /// </summary>
        new public static DoubleEdgeQuadRule CreateEmpty(RefElement Kref, int noOfNodes, int D)
        {
            DoubleEdgeQuadRule rule = new DoubleEdgeQuadRule();

            rule.Nodes            = new NodeSet(Kref, noOfNodes, D);
            rule.Weights          = MultidimensionalArray.Create(noOfNodes);
            rule.OrderOfPrecision = 0;
            return(rule);
        }
예제 #13
0
        /// <summary>
        /// Uses <see cref="Grid.RefElement.GetQuadratureRule"/> to create a quad rule
        /// (i.e., the quad rule is the same for all elements of
        /// <paramref name="mask"/>)
        /// </summary>
        /// <param name="mask">
        /// <see cref="IQuadRuleFactory{QuadRule}.GetQuadRuleSet"/>
        /// </param>
        /// <param name="order">
        /// <see cref="IQuadRuleFactory{QuadRule}.GetQuadRuleSet"/>
        /// </param>
        /// <returns>
        /// <see cref="Grid.RefElement.GetQuadratureRule"/>
        /// </returns>
        public IEnumerable <IChunkRulePair <QuadRule> > GetQuadRuleSet(ExecutionMask mask, int order)
        {
            QuadRule rule = RefElement.GetQuadratureRule(order);

            Debug.Assert(rule.Nodes.IsLocked, "Error: non-locked quad rule from reference element.");
            Debug.Assert(object.ReferenceEquals(rule.Nodes.RefElement, RefElement), "Error: quad rule from reference element has not the right reference elment assigned.");

            return(mask.Select(chunk => new ChunkRulePair <QuadRule>(chunk, rule)));
        }
예제 #14
0
        /// <summary>
        /// creates a empty (i.e. all entries set to 0.0) <see cref="QuadRule"/> object
        /// with <paramref name="noOfNodes"/> quadrature nodes.
        /// </summary>
        /// <param name="noOfNodes"></param>
        /// <param name="D">spatial dimension</param>
        /// <param name="Kref">reference element for which this quadrature rule is valid</param>
        /// <returns>an empty (i.e. all weights are 0.0) quadrature rule</returns>
        public static QuadRule CreateEmpty(RefElement Kref, int noOfNodes, int D)
        {
            QuadRule ret = new QuadRule();

            ret.Nodes            = new NodeSet(Kref, noOfNodes, D);
            ret.Weights          = MultidimensionalArray.Create(noOfNodes);
            ret.OrderOfPrecision = 0;
            return(ret);
        }
예제 #15
0
        /// <summary>
        /// Creates an empty rule.
        /// </summary>
        public static CellBoundaryQuadRule CreateEmpty(RefElement Kref, int noOfNodes, int D, int noOfEdges)
        {
            CellBoundaryQuadRule rule = new CellBoundaryQuadRule();

            rule.Nodes                 = new NodeSet(Kref, noOfNodes, D);
            rule.Weights               = MultidimensionalArray.Create(noOfNodes);
            rule.OrderOfPrecision      = 0;
            rule.NumbersOfNodesPerFace = new int[noOfEdges];
            return(rule);
        }
예제 #16
0
            /// <summary>
            /// Cell-Mask of all cells which share the same reference element.
            /// </summary>
            public CellMask GetCells4Refelement(RefElement Kref)
            {
                var KRefs = this.RefElements;
                int iKref = KRefs.IndexOf(Kref, (A, B) => object.ReferenceEquals(A, B));

                if (iKref < 0 || iKref >= KRefs.Length)
                {
                    throw new ArgumentException();
                }

                return(GetCells4Refelement(iKref));
            }
예제 #17
0
 public ComboFactoryWrapper(
     Action <ExecutionMask, int> comboRuleEvaluator,
     IEnumerable <IChunkRulePair <QuadRule> > Rule,
     RefElement RefElem,
     Status ruleStatus,
     QuadratureType quadType)
 {
     rule               = Rule;
     refElem            = RefElem;
     ComboRuleEvaluator = comboRuleEvaluator;
     RuleStatus         = ruleStatus;
     quadMode           = quadType;
 }
예제 #18
0
 /// <summary>
 /// Creates a node set with all nodes set to 0 -- these values can still be changed.
 /// Use this constructor with care!
 /// Note that this node set is in an invalid state until <see cref="MultidimensionalArray.LockForever"/> is called.
 /// </summary>
 public NodeSet(RefElement r, int NoOfNodes, int D)
     : base(2) //
 {
     base.Allocate(NoOfNodes, D);
     this.RefElement = r;
     lock (syncRoot) {
         this.Reference = RefCounter;
         if (RefCounter >= int.MaxValue)
         {
             throw new ApplicationException("NodeSet ref-counter overflow.");
         }
         RefCounter++;
     }
 }
예제 #19
0
        /// <summary>
        /// Uses <see cref="Grid.RefElement.GetQuadratureRule"/> to create a quad rule
        /// (i.e., the quad rule is the same for all elements of
        /// <paramref name="mask"/>)
        /// </summary>
        /// <param name="mask">
        /// <see cref="IQuadRuleFactory{QuadRule}.GetQuadRuleSet"/>
        /// </param>
        /// <param name="order">
        /// <see cref="IQuadRuleFactory{QuadRule}.GetQuadRuleSet"/>
        /// </param>
        /// <returns>
        /// <see cref="Grid.RefElement.GetQuadratureRule"/>
        /// </returns>
        public IEnumerable <IChunkRulePair <QuadRule> > GetQuadRuleSet(ExecutionMask mask, int order)
        {
            if (mask.MaskType != MaskType.Geometrical)
            {
                throw new ArgumentException("Expecting a geometrical mask.");
            }

            QuadRule rule = RefElement.GetQuadratureRule(order);

            Debug.Assert(rule.Nodes.IsLocked, "Error: non-locked quad rule from reference element.");
            Debug.Assert(object.ReferenceEquals(rule.Nodes.RefElement, RefElement), "Error: quad rule from reference element has not the right reference elment assigned.");

            return(mask.Select(chunk => new ChunkRulePair <QuadRule>(chunk, rule)));
        }
예제 #20
0
        static MultidimensionalArray Transform(RefElement Kref, Cell Cl, NodeSet Nodes)
        {
            int                   D                 = Kref.SpatialDimension;
            PolynomialList        polys             = Kref.GetInterpolationPolynomials(Cl.Type);
            MultidimensionalArray polyVals          = polys.Values.GetValues(Nodes);
            MultidimensionalArray GlobalVerticesOut = MultidimensionalArray.Create(Nodes.NoOfNodes, D);

            for (int d = 0; d < D; d++)
            {
                GlobalVerticesOut.ExtractSubArrayShallow(-1, d)
                .Multiply(1.0, polyVals, Cl.TransformationParams.ExtractSubArrayShallow(-1, d), 0.0, "k", "kn", "n");
            }

            return(GlobalVerticesOut);
        }
예제 #21
0
        /// <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;
        }
예제 #22
0
 public ExactCircleLevelSetIntegration(int iLs, GridData c, RefElement simplex)
 {
     if (!Rem)
     {
         for (int i = 0; i < RADIUS.Length; i++)
         {
             Console.WriteLine("ACHTUNG: ExactCircleLevelSetIntegration; Radius = " + RADIUS[i]);
         }
         Rem = true;
     }
     if (simplex.GetType() != typeof(Square))
     {
         throw new ArgumentOutOfRangeException();
     }
     this.RefElement = simplex;
     this.iLevSet    = iLs;
     this._Context   = c;
 }
예제 #23
0
        /// <summary>
        /// Fills up the volume scheme for species <paramref name="sp"/>.
        /// </summary>
        public CellQuadratureScheme GetVolumeQuadScheme(SpeciesId sp, bool UseDefaultFactories = true, CellMask IntegrationDomain = null, int?fixedOrder = null)
        {
            if (!this.SpeciesList.Contains(sp))
            {
                throw new ArgumentException("Given species (id = " + sp.cntnt + ") is not supported.");
            }

            if (IntegrationDomain != null)
            {
                if (IntegrationDomain.MaskType != MaskType.Logical)
                {
                    throw new ArgumentException();
                }
            }

            CellMask CellMask = GetCellMask(sp, IntegrationDomain);

            /// Debugging Code
            //if (IntegrationDomain != null) {
            //    CellMask.ToTxtFile("VolDom-" + this.lsTrk.GridDat.MyRank + "of" + this.lsTrk.GridDat.Size + ".csv", false);
            //}

            // default rule for "normal" cells
            var volQrIns = (new CellQuadratureScheme(UseDefaultFactories, CellMask));

            // now: rules for the cut-cells:
            for (int iLevSet = 0; iLevSet < XDGSpaceMetrics.NoOfLevelSets; iLevSet++)   // loop over level sets
            {
                var cutDom   = XDGSpaceMetrics.LevelSetRegions.GetCutCellMask4LevSet(iLevSet).ToGeometicalMask();
                var cutCells = cutDom.Intersect(CellMask);

                var jmp = IdentifyWing(iLevSet, sp);

                for (int iKref = 0; iKref < XDGSpaceMetrics.GridDat.Grid.RefElements.Length; iKref++)
                {
                    RefElement Kref    = XDGSpaceMetrics.GridDat.Grid.RefElements[iKref];
                    var        _cutDom = cutCells.Intersect(XDGSpaceMetrics.GridDat.Cells.GetCells4Refelement(iKref));
                    var        factory = this.XDGSpaceMetrics.XQuadFactoryHelper.GetVolRuleFactory(iLevSet, jmp, Kref);
                    volQrIns.AddFactoryDomainPair(factory, _cutDom, fixedOrder);
                }
            }

            return(volQrIns);
        }
예제 #24
0
        /// <summary>
        /// Creates an empty rule
        /// </summary>
        /// <param name="noOfNodes">
        /// The desired number of nodes
        /// </param>
        /// <param name="element">
        /// The selected reference element
        /// </param>
        /// <returns>
        /// A quadrature rule with <paramref name="noOfNodes"/> nodes where all
        /// relevant entries are zero.
        /// </returns>
        public static CellEdgeBoundaryQuadRule CreateEmpty(int noOfNodes, RefElement element)
        {
            if (element.SpatialDimension < 3)
            {
                throw new ArgumentException("Only makes sense for 3D objects");
            }

            CellEdgeBoundaryQuadRule rule = new CellEdgeBoundaryQuadRule()
            {
                Nodes                       = new NodeSet(element, noOfNodes, element.SpatialDimension),
                Weights                     = MultidimensionalArray.Create(noOfNodes),
                OrderOfPrecision            = 0,
                NumbersOfNodesPerFace       = new int[element.NoOfFaces],
                NumbersOfNodesPerFaceOfFace =
                    new int[element.NoOfFaces, element.FaceRefElement.NoOfFaces]
            };

            return(rule);
        }
예제 #25
0
        public static SayeGaussComboRuleFactory SayeGaussRule_Combo(
            LevelSetTracker.LevelSetData _lsData,
            IRootFindingAlgorithm RootFinder)
        {
            RefElement refElem = _lsData.GridDat.Grid.GetRefElement(0);

            if (refElem is Grid.RefElements.Square)
            {
                return(SayeGaussRule_Combo2D(_lsData, RootFinder));
            }
            else if (refElem is Grid.RefElements.Cube)
            {
                return(SayeGaussRule_Combo3D(_lsData, RootFinder));
            }
            else
            {
                throw new NotImplementedException("Saye quadrature not available for this RefElement");
            }
        }
            public CellMask GetCells4Refelement(RefElement Kref)
            {
                int iKref = Array.IndexOf(this.RefElements, Kref);

                if (m_Cells4Refelement == null)
                {
                    m_Cells4Refelement = new CellMask[this.RefElements.Length];
                }

                if (m_Cells4Refelement[iKref] == null)
                {
                    var OrgMsk = m_Owner.ParentGrid.iGeomCells.GetCells4Refelement(Kref);
                    Debug.Assert(OrgMsk.MaskType == MaskType.Geometrical);
                    Debug.Assert(object.ReferenceEquals(OrgMsk.GridData, m_Owner.ParentGrid));

                    m_Cells4Refelement[iKref] = new CellMask(m_Owner, OrgMsk, MaskType.Geometrical);
                }
                return(m_Cells4Refelement[iKref]);
            }
예제 #27
0
 /// <summary>
 /// Constructor: initializes this node set
 /// containing only one point <paramref name="point"/>.
 /// </summary>
 public NodeSet(RefElement r, double[] point)
     : base(2) //
 {
     if (point.Length > 3)
     {
         throw new ArgumentException("Spatial dimension is expected to be lower or equal to 3.");
     }
     base.Allocate(1, point.Length);
     base.ExtractSubArrayShallow(0, -1).SetVector(point);
     base.LockForever();
     this.RefElement = r;
     lock (syncRoot) {
         this.Reference = RefCounter;
         if (RefCounter >= int.MaxValue)
         {
             throw new ApplicationException("NodeSet ref-counter overflow.");
         }
         RefCounter++;
     }
 }
예제 #28
0
        /// <summary>
        /// Initializes the subdivision of the given simplex. Initially, the
        /// simplex remains undivided.
        /// </summary>
        /// <param name="refElement">
        /// The simplex to subdivide.
        /// </param>
        /// <param name="tracker">
        /// The level set tracker. Allows for the check if a simplex ist cut.
        /// </param>
        /// <param name="levSetIndex">Index of the level set</param>
        /// <param name="maxDivisions">
        /// The maximum number of subdivisions of the simplex
        /// </param>
        public AdaptiveSubdivisionStrategy(RefElement refElement, LevelSetTracker.LevelSetData levelSetData, int maxDivisions)
        {
            this.RefElement    = refElement;
            this.maxDivisions  = maxDivisions;
            this.baseVertexSet = new NestedVertexSet(refElement.SpatialDimension);
            this.LevelSetData  = levelSetData;

            int verticesPerCell = refElement.Vertices.GetLength(0);

            int[] simplexVertices = new int[verticesPerCell];
            for (int i = 0; i < verticesPerCell; i++)
            {
                double[] vertex = refElement.Vertices.GetRow(i);
                simplexVertices[i] = baseVertexSet.RegisterVertex(vertex);
            }
            this.subdivisionTree = new SimplexSubdivisionTree(
                refElement, baseVertexSet, simplexVertices);

            this.subdivisionTree.SetSavePoint();
        }
예제 #29
0
 /// <summary>
 /// Constructor: initializes this node set as a (non-shallow) clone of the array <paramref name="nds"/>.
 /// </summary>
 public NodeSet(RefElement r, double[,] nds)
     : base(2) //
 {
     if (nds.GetLength(1) > 3)
     {
         throw new ArgumentException("Spatial dimension is expected to be lower or equal to 3.");
     }
     base.Allocate(nds.GetLength(0), nds.GetLength(1));
     base.Set2DArray(nds);
     base.LockForever();
     this.RefElement = r;
     lock (syncRoot) {
         this.Reference = RefCounter;
         if (RefCounter >= int.MaxValue)
         {
             throw new ApplicationException("NodeSet ref-counter overflow.");
         }
         RefCounter++;
     }
 }
예제 #30
0
            /// <summary>
            /// Computes the bounding box of cell <paramref name="j"/>.
            /// </summary>
            /// <param name="j">local cell index.</param>
            /// <param name="bb">
            /// on exit, the bounding box of cell j.
            /// </param>
            public void GetCellBoundingBox(int j, BoundingBox bb)
            {
                int D = bb.D;

                if (bb.D != m_owner.SpatialDimension)
                {
                    throw new ArgumentException("wrong dimension of bounding box.");
                }
                bb.Clear();

                Cell       Cj          = this.GetCell(j);
                RefElement Kref        = this.GetRefElement(j);
                NodeSet    verticesLoc = Kref.GetInterpolationNodes(Cj.Type);

                MultidimensionalArray verticesGlob = MultidimensionalArray.Create(1, verticesLoc.GetLength(0), verticesLoc.GetLength(1));

                m_owner.TransformLocal2Global(verticesLoc, j, 1, verticesGlob, 0);
                bb.AddPoints(verticesGlob
                             .ExtractSubArrayShallow(0, -1, -1));
            }
예제 #31
0
		private bool m_matched; //see Matched property

		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Constructor for a ChapterVerseInfo object
		/// </summary>
		/// ------------------------------------------------------------------------------------
		public ChapterVerseInfo(RefElement type, string sNumber, int iRunMin, int iRunLim)
		{
			Type = type;
			NumberString = sNumber;
			iRunMinText = iRunMin;
			iRunLimText = iRunLim;
			m_matched = false;
		}
예제 #32
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Determine if the given paragraph contents begins with a chapter or verse number.
		/// If so, export notes prior to this chapter or verse. If the paragraph starts with
		/// a chapter number, then export the \c field and related stuff.
		/// </summary>
		/// <param name="tss">given paragraph contents</param>
		/// <param name="sectionVerseRefStart"> if we are processing the start of a section,
		/// VerseRefStart information for the section; zero otherwise</param>
		/// <param name="runTypeFound">out: Chapter, Verse, or None</param>
		/// ------------------------------------------------------------------------------------
		private void ProcessParaStart(ITsString tss, int sectionVerseRefStart,
			out RefElement runTypeFound)
		{
			int number;
			bool invalidSyntax;
			string numText;
			CheckParaStartForChapterOrVerse(tss, out runTypeFound, out number, out invalidSyntax,
				out numText);

			// If para begins with a verse, export pending notes now
			if (runTypeFound == RefElement.Verse)
			{
				if (number > 0)
					ExportNotesForPriorVerse(RefElement.Verse, number, null);
				else
				{
					// Verse is non-numeric, output notes for previous end verse
					if (m_textOutputBegunInCurrentSection)
						//						if (m_lastNumericEndVerseNum > 0) // only if numeric verse previously found
						ExportNotesForPriorVerse(runTypeFound, m_lastNumericEndVerseNum + 1, null);
				}
			}

			// If the paragraph starts with a chapter number run,
			// the \c field needs to be written now, before the paragraph or section markers.
			if (runTypeFound == RefElement.Chapter)
			{
				bool wroteNumericTag;
				wroteNumericTag = OutputChapterNumberAndRelated(number, invalidSyntax, numText,
					sectionVerseRefStart, null);

				// See if the chapter we just wrote out needs to output a \v 1 for an
				//  implicit first verse.
				if (wroteNumericTag)
					m_v1NeededForImplicitFirstVerse = ParaBeginsWithImplicitFirstVerse(tss, 0);
			}
		}
예제 #33
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Checks to see if the paragraph begins with a chapter or verse number.
		/// </summary>
		/// <param name="tssPara">The paragraph contents to check.</param>
		/// <param name="runType">out: Chapter, Verse, or None</param>
		/// <param name="number">out: The value of the chapter or verse begin number found in the
		/// first run (even if invalid syntax), or 0 if no digits found.</param>
		/// <param name="invalidSyntax">out: True if chapter or verse number (in numText) does
		/// not meet standard format syntax requirements</param>
		/// <param name="numText">out: the text of the number found, or null if none</param>
		/// ------------------------------------------------------------------------------------
		private void CheckParaStartForChapterOrVerse(ITsString tssPara,
			out RefElement runType, out int number, out bool invalidSyntax, out string numText)
		{
			runType = RefElement.None;
			number = 0;
			invalidSyntax = false;
			numText = null;
			if (tssPara.Length == 0)
				return;

			// Check the first run.
			ITsTextProps runProps = tssPara.get_Properties(0);
			if (runProps.Style() == ScrStyleNames.VerseNumber)
			{
				runType = RefElement.Verse;
				numText = tssPara.get_RunText(0).Trim();
				number = VerseBeginNumToInt(numText, out invalidSyntax);
			}
			else if (runProps.Style() == ScrStyleNames.ChapterNumber)
			{
				runType = RefElement.Chapter;
				numText = tssPara.get_RunText(0).Trim();
				number = ChapterNumStringToInt(numText, out invalidSyntax);
			}
		}
예제 #34
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Export all of the back translation fields that occur before the given chapter
		/// or verse number. This is used for Toolbox markup only.
		/// </summary>
		/// <param name="cmTrans">back-translation object (potentially multiple WS's)</param>
		/// <param name="btVersesByWs">Array with an element for each desired writing system.
		/// Each element is a List of ChapterVerseInfo objects.</param>
		/// <param name="type">The type of number we must try to match: Chapter, Verse number,
		/// or None if no match needed and we will write all remaining  back translation fields
		/// </param>
		/// <param name="givenNumber">current chapter or verse number to match. All back
		/// translation fields up until this chapter/verse will be output.</param>
		/// <param name="vernFootnotes">If this is a non-interleaved back translation, this is
		/// the list of footnotes in the (vernacular) paragraph being exported.</param>
		/// ------------------------------------------------------------------------------------
		private void ExportBackTransForPriorVerse(ICmTranslation cmTrans, List<ChapterVerseInfo>[] btVersesByWs,
			RefElement type, string givenNumber, List<IScrFootnote> vernFootnotes)
		{
			givenNumber = givenNumber.Trim();

			// Process each of the back translation sets by writing system
			for (int iWs = 0; iWs < m_requestedAnalWS.Length; iWs++)
			{
				// get the back translation string for this WS
				ITsString tssBt = cmTrans.Translation.get_String(m_requestedAnalWS[iWs]);

				// If all items are requested then output all
				if (type == RefElement.None)
				{
					foreach (ChapterVerseInfo info in btVersesByWs[iWs])
						OutputBTInfo(info, tssBt, iWs);
					btVersesByWs[iWs].Clear();
				}
				else
				{
					// Look for chapter/verse info that matches the given givenNumber
					ChapterVerseInfo matchInfo = null;
					List<ChapterVerseInfo> verseInfoSet = btVersesByWs[iWs];
					if (verseInfoSet != null)
					{
						foreach (ChapterVerseInfo info in verseInfoSet)
						{
							if (info.Type == type && info.NumberString == givenNumber)
							{
								matchInfo = info;
								// remember that this info has a match in the vernacular
								info.Matched = true;
								break;
							}
						}
					}

					// If a match was found, then output all BT items before the one found
					if (matchInfo != null)
					{
						while (verseInfoSet[0] != matchInfo)
						{
							OutputBTInfo(verseInfoSet[0], tssBt, iWs);
							verseInfoSet.RemoveAt(0);
						}
					}
					else
					{
						// A match was not found for the current chapter/verse number;
						// so output everything that was previously matched.
						while (verseInfoSet.Count > 0 && verseInfoSet[0].Matched)
						{
							OutputBTInfo(verseInfoSet[0], tssBt, iWs);
							verseInfoSet.RemoveAt(0);
						}
					}
				}
			}
		}
예제 #35
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Export annotations and footnotes for verse(s) prior to reference represented by the
		/// given number.
		/// </summary>
		/// <param name="type">The type of number we must try to match: Chapter, Verse, or Book.
		/// </param>
		/// <param name="nextNumber">current chapter, verse number or book number to match.
		/// All note fields prior to this chapter/verse/book will be output.</param>
		/// <param name="vernFootnotes">If this is a non-interleaved back translation, this is
		/// the list of footnotes in the (vernacular) paragraph being exported.</param>
		/// <remarks>Annotations are sorted by reference, but annotations to a single reference
		/// are not necessarily in the order they were added.</remarks>
		/// ------------------------------------------------------------------------------------
		private void ExportNotesForPriorVerse(RefElement type, int nextNumber,
			List<IScrFootnote> vernFootnotes)
		{
			if (!ExportNotesDomain && (vernFootnotes == null || vernFootnotes.Count == 0))
				return;

			// Determine the next begin ref
			ScrReference nextBeginRef;
			switch (type)
			{
				case RefElement.Chapter:
					//					if (nextNumber >= m_lastChapterWritten) // equal is okay because chapter num may have been preprocessed in ExportSection or ExportPara
					nextBeginRef = new ScrReference(m_currentBookOrd, nextNumber, 1,
						m_scr.Versification);
					//					else
					//					{
					//						// since chapterNum is not in order (or zero), use the last chapter num to export the annotations
					//						nextBeginRef = new ScrReference(m_currentBookOrd, m_lastChapterWritten + 1, 1);
					//					}
					break;
				case RefElement.Verse:
					int verse = nextNumber;
					//					// if given verse number is not numeric, estimate from last numeric value
					//					if (verse == 0)
					//						verse = m_lastNumericEndVerseNum + 1;
					nextBeginRef = new ScrReference(m_currentBookOrd, m_currentChapterRef,
						verse, m_scr.Versification);
					break;
				case RefElement.Book:
				default:
					// write all remaining notes fields for the current book
					nextBeginRef = new ScrReference(nextNumber, 0, 0, m_scr.Versification);
					break;
			}

			if (vernFootnotes != null)
			{
				for (int iFn = 0; iFn < vernFootnotes.Count; iFn++)
				{
					IScrFootnote footnote = vernFootnotes[iFn];
					if (footnote.EndRef < nextBeginRef)
					{
						ExportFootnote(footnote, ExportMode.BackTransOnly, 0);
						vernFootnotes.RemoveAt(iFn--);
					}
				}
			}

			if (!ExportNotesDomain)
				return;

			// loop through the relevant annotations
			IScrScriptureNote annotation;
			BCVRef noteBeginRef;
			int annotationIndex = 0;
			while (annotationIndex < m_annotationList.Count)
			{
				annotation = m_annotationList[annotationIndex];
				noteBeginRef = annotation.BeginRef;

				// if note ref is prior to the given next reference...
				if (noteBeginRef < nextBeginRef)
				{
					// write out this annotation
					ExportNote(annotation);
					m_annotationList.RemoveAt(annotationIndex);
				}
				else
					annotationIndex++;

				if (noteBeginRef >= nextBeginRef)
					break; // we are done for now
			}
		}