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); } }
/// <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; }
/// <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); }
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)); } } } } }
/// <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; }
/// <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); }
/// <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); }
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."); } }
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; }
/// <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; }
/// <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); }
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); } }
/// <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)); }
public RegularizedQuadRuleFactory(IQuadRuleFactory <QuadRule> baseFactory, LevelSetTracker tracker, RegularizationPolynomoial polynomial, double width) : this(baseFactory, tracker, 0, polynomial, width) { }
/// <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); }
/// <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; }
/// <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"); } }
/// <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); }
/// <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); }
/// <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)); }
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; }
public ComplementaryRuleFactory(IQuadRuleFactory <QuadRule> orgRule) { m_orgrule = orgRule; }
public LinearReconstructionQuadRuleFactory(LevelSetTracker tracker, LineAndPointQuadratureFactory lineAndPointFactory) { this.tracker = tracker; this.rootFactory = lineAndPointFactory.GetPointFactory(); }