/// <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; }
/// <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]); }
/// <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); }
/// <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]); } }
/// <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); }
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); } }
/// <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; }
/// <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); } }
/// <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; }
/// <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); }
/// <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))); }
/// <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); }
/// <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); }
/// <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)); }
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; }
/// <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++; } }
/// <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))); }
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); }
/// <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; }
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; }
/// <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); }
/// <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); }
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]); }
/// <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++; } }
/// <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(); }
/// <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++; } }
/// <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)); }
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; }
/// ------------------------------------------------------------------------------------ /// <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); } }
/// ------------------------------------------------------------------------------------ /// <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); } }
/// ------------------------------------------------------------------------------------ /// <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); } } } } }
/// ------------------------------------------------------------------------------------ /// <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 } }