protected override void CreateFields() { levelSet = testCase.GetLevelSet((BoSSS.Foundation.Grid.Classic.GridData)GridData); levelSetTracker = new LevelSetTracker((BoSSS.Foundation.Grid.Classic.GridData)GridData, XQuadFactoryHelper.MomentFittingVariants.Classic, // should have no effect, this app creates its own quad-rules independent of the tracker 1, new string[] { "A", "B" }, levelSet); XDGField = new XDGField( new XDGBasis(levelSetTracker, testCase.IntegrandDegree), "XDGField"); SinglePhaseField = new SinglePhaseField( new Basis(GridData, testCase.IntegrandDegree), "SinglePhaseField"); if (levelSet is LevelSet) { m_IOFields.Add((LevelSet)levelSet); } else { LevelSet projectedLevelSet = new LevelSet(new Basis(GridData, 4), "projectedAnalyticLevelSet"); projectedLevelSet.ProjectField(testCase.GetLevelSet((BoSSS.Foundation.Grid.Classic.GridData)GridData).Evaluate); m_IOFields.Add(projectedLevelSet); } m_IOFields.Add(XDGField); m_IOFields.Add(SinglePhaseField); }
public override void UpdateLevelSet(ILevelSet levelSet) { ((LevelSet)levelSet).ProjectField(LevelSetInitialValue); //AnalyticEllipsoidLevelSet analyticeLevelSet = levelSet as AnalyticEllipsoidLevelSet; //if (analyticeLevelSet == null) { // throw new Exception(); //} //analyticeLevelSet.SetOffset(CurrentShift.OffsetX, CurrentShift.OffsetY, CurrentShift.OffsetZ); }
public double[] GetRoots(LineSegment segment, ILevelSet levelSet, int cell, int iKref) { if (levelSet is IAnalyticLevelSet) { return(((IAnalyticLevelSet)levelSet).GetRoots(segment, cell).ToArray()); } else { throw new ArgumentException("Level set must implement IAnalyticLevelSet", "levelSet"); } }
public override void UpdateLevelSet(ILevelSet levelSet) { LevelSet levelSetField = levelSet as LevelSet; if (levelSetField == null) { throw new ArgumentException(); } levelSetField.ProjectField(LevelSetInitialValue); }
/// <summary> /// Determines all roots of <paramref name="levelSet"/> on this segment /// in cell <paramref name="cell"/>. /// </summary> /// <param name="levelSet"> /// The level set whose roots are of interest /// </param> /// <param name="cell"> /// The cell where the evaluation takes place /// </param> /// <param name="iKref"> /// Reference element index. /// </param> /// <returns> /// The parameter t of each root of <paramref name="levelSet"/> on this /// segment in cell <paramref name="cell"/> /// </returns> public double[] GetRoots(ILevelSet levelSet, int cell, int iKref) { return(RootFindingAlgorithm.GetRoots(this, levelSet, cell, iKref)); // Caching currently deactivated since it didn't really help... //Tuple<ILevelSet, int> key = Tuple.Create(levelSet, cell); //double[] roots; //if (!rootsCache.TryGetValue(key, out roots)) { // roots = RootFindingAlgorithm.GetRoots(this, levelSet, cell); // rootsCache.Add(key, roots); //} //return roots; }
/// <summary> /// Constructs an integrator for the given field /// <paramref name="field"/>. /// </summary> /// <param name="trk"> /// The tracker containing the level set to be integrated over /// </param> /// <param name="field"> /// The field to be integrated /// </param> /// <param name="volumeFactory"> /// <see cref="LevelSetIntegrator.LevelSetIntegrator"/> /// </param> /// <param name="boundaryFactory"> /// <see cref="LevelSetIntegrator.LevelSetIntegrator"/> /// </param> /// <param name="quadOrder"> /// <see cref="LevelSetIntegrator.LevelSetIntegrator"/> /// </param> /// <param name="sgrd"></param> /// <param name="LevSetIdx"></param> public ScalarFieldLevelSetIntegrator( LevelSetTracker trk, SinglePhaseField field, ICompositeQuadRule <QuadRule> volumeFactory, ICompositeQuadRule <CellBoundaryQuadRule> boundaryFactory, int quadOrder, SubGrid sgrd, int LevSetIdx) : base(trk, 1, volumeFactory, boundaryFactory, quadOrder, sgrd, LevSetIdx) { m_levSet = trk.LevelSets[0]; m_Field = field; }
public override void UpdateLevelSet(ILevelSet levelSet) { //AnalyticStarLevelSet analyticLevelSet = levelSet as AnalyticStarLevelSet; //if (analyticLevelSet == null) { // throw new Exception(); //} //analyticLevelSet.SetParameters(CurrentShift.OffsetX, CurrentShift.OffsetY); LevelSet levelSetField = levelSet as LevelSet; if (levelSetField == null) { throw new Exception(); } levelSetField.ProjectField(LevelSetInitialValue); }
public override void UpdateLevelSet(ILevelSet levelSet) { //AnalyticSphereLevelSet analyticLevelSet = levelSet as AnalyticSphereLevelSet; //if (analyticLevelSet == null) { // throw new Exception(); //} //analyticLevelSet.SetOffset(CurrentShift.OffsetX, CurrentShift.OffsetY, CurrentShift.OffsetZ); LevelSet field = levelSet as LevelSet; if (field == null) { throw new Exception(); } field.ProjectField(LevelSetInitialValue); }
private void ComputeValuesNonField(ILevelSet levelSet, NodeSet NS, int j0, int Len, MultidimensionalArray output) { int noOfNodes = NS.NoOfNodes; int D = NS.SpatialDimension; var R = m_owner.m_owner.GridDat.Cells.Transformation; var JacDet = m_owner.m_owner.GridDat.ChefBasis.Scaling; var Cells = m_owner.m_owner.GridDat.Cells; MultidimensionalArray physGradient = m_owner.GetLevelSetGradients(NS, j0, Len); for (int i = 0; i < Len; i++) { int jCell = j0 + i; if (Cells.IsCellAffineLinear(jCell)) { double det = JacDet[j0 + i]; for (int j = 0; j < noOfNodes; j++) { for (int d = 0; d < D; d++) { double r = 0.0; for (int dd = 0; dd < D; dd++) { r += R[i + j0, dd, d] * physGradient[i, j, dd]; } output[i, j, d] = r / det; } } } else { throw new NotImplementedException("todo: nonlinear cell"); } } }
public override void UpdateLevelSet(ILevelSet levelSet) { ((LevelSet)levelSet).ProjectField(LevelSetInitialValue); }
/// <summary> /// Uses a safe-guarded Newton method to find all roots on /// <paramref name="segment"/> /// </summary> /// <param name="segment"></param> /// <param name="levelSet"></param> /// <param name="cell"></param> /// <param name="iKref"></param> /// <returns></returns> public double[] GetRoots(LineSegment segment, ILevelSet levelSet, int cell, int iKref) { LevelSet levelSetField = levelSet as LevelSet; if (levelSetField == null) { throw new NotImplementedException("Method currently only works for polynomial level sets"); } int maxNoOfCoefficientsPerDimension = levelSetField.Basis.Degree + 1; int noOfPolynomials = segment.ProjectedPolynomialCoefficients.GetLength(1); double[] coefficients = new double[maxNoOfCoefficientsPerDimension]; for (int i = 0; i < noOfPolynomials; i++) { double dgCoefficient = levelSetField.Coordinates[cell, i]; for (int j = 0; j < maxNoOfCoefficientsPerDimension; j++) { coefficients[j] += dgCoefficient * segment.ProjectedPolynomialCoefficients[iKref, i, j]; } } //if(coefficients.L2NormPow2() < this.Tolerance) { // // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // // special case : // // the zero-level-set is probably parallel to this line segment // // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // return new double[] { -1.0, 1.0 }; //} double[] roots; unsafe { fixed(double *pCoeff = &coefficients[coefficients.Length - 1]) { double xLow = -1.0; double xHigh = 1.0; int NO_OF_BRACKETS = 8; List <double> lowerBounds = new List <double>(); List <double> upperBounds = new List <double>(); double dx2 = 2.0 / NO_OF_BRACKETS; double x = xLow; double fOld = Eval(x, pCoeff, coefficients.Length); for (int i = 0; i < NO_OF_BRACKETS; i++) { x += dx2; double fNew = Eval(x, pCoeff, coefficients.Length); if (i == 0 && fOld.Abs() < Tolerance) { lowerBounds.Add(x - dx2); upperBounds.Add(x); fOld = fNew; continue; } else { if (fNew.Abs() < Tolerance) { lowerBounds.Add(x - dx2); upperBounds.Add(x); x += dx2; fOld = Eval(x, pCoeff, coefficients.Length); continue; } } if (fNew * fOld <= 0.0) { lowerBounds.Add(x - dx2); upperBounds.Add(x); } fOld = fNew; } // Actual Newton-Raphson int MAX_ITERATIONS = 50; roots = new double[lowerBounds.Count]; for (int j = 0; j < lowerBounds.Count; j++) { xLow = lowerBounds[j]; xHigh = upperBounds[j]; double fLeft = Eval(xLow, pCoeff, coefficients.Length); double fRight = Eval(xHigh, pCoeff, coefficients.Length); if (fLeft.Abs() < Tolerance) { roots[j] = xLow; break; } if (fRight.Abs() < Tolerance) { roots[j] = xHigh; break; } if (fLeft.Sign() == fRight.Sign()) { throw new Exception(); } if (fLeft > 0.0) { xLow = upperBounds[j]; xHigh = lowerBounds[j]; } double root = 0.5 * (xLow + xHigh); double f; double df; Eval(root, pCoeff, coefficients.Length, out f, out df); double dxOld = (xHigh - xLow).Abs(); double dx = dxOld; int i = 0; while (true) { if (i > MAX_ITERATIONS) { throw new Exception("Max iterations exceeded"); } double a = ((root - xHigh) * df - f) * ((root - xLow) * df - f); if (a > 0.0 || 2.0 * Math.Abs(f) > Math.Abs(dxOld * df)) { // Newton out of range or too slow -> Bisect dxOld = dx; dx = 0.5 * (xHigh - xLow); root = xLow + dx; } else { // Take Newton step dxOld = dx; dx = -f / df; //// Convergence acceleration according to Yao2014 //double fDelta = Eval(root + dx, pCoeff, coefficients.Length); //dx = -(f + fDelta) / df; root += dx; } Eval(root, pCoeff, coefficients.Length, out f, out df); if (Math.Abs(f) <= Tolerance) { roots[j] = root; break; } if (f < 0.0) { xLow = root; } else { xHigh = root; } i++; } } } } return(roots); }
/// <summary> /// Finds the roots using <see cref="GSL.gsl_poly_complex_solve"/> /// </summary> /// <param name="segment"></param> /// <param name="levelSet"></param> /// <param name="cell"></param> /// <param name="iKref"></param> /// <returns></returns> public double[] GetRoots(LineSegment segment, ILevelSet levelSet, int cell, int iKref) { LevelSet levelSetField = levelSet as LevelSet; if (levelSetField == null) { throw new NotImplementedException("Method currently only works for polynomial level sets"); } int maxNoOfCoefficientsPerDimension = levelSetField.Basis.Degree + 1; int noOfPolynomials = segment.ProjectedPolynomialCoefficients.GetLength(1); double[] coefficients = new double[maxNoOfCoefficientsPerDimension]; for (int i = 0; i < noOfPolynomials; i++) { double dgCoefficient = levelSetField.Coordinates[cell, i]; for (int j = 0; j < maxNoOfCoefficientsPerDimension; j++) { coefficients[j] += dgCoefficient * segment.ProjectedPolynomialCoefficients[iKref, i, j]; } } // Make sure "leading" coefficient (i.e., the last element of the // list of coefficients) is not too small since this will make gsl // crash (or lead to bogus results) int newLength = coefficients.Length; while (newLength > 0 && Math.Abs(coefficients[newLength - 1]) < EPSILON) { newLength--; } if (newLength != coefficients.Length) { coefficients = coefficients.Take(newLength).ToArray(); } // Make sure polynomial is not constant since this will make gsl crash if (newLength < 2) { return(new double[0]); } int maxNoOfRoots = coefficients.Length - 1; double[] roots = new double[2 * maxNoOfRoots]; GCHandle coefficientHandle = GCHandle.Alloc(coefficients, GCHandleType.Pinned); GCHandle rootsHandle = GCHandle.Alloc(roots, GCHandleType.Pinned); IntPtr workSpace = GSL.gsl_poly_complex_workspace_alloc(coefficients.Length); GSL.gsl_poly_complex_solve( coefficientHandle.AddrOfPinnedObject(), coefficients.Length, workSpace, rootsHandle.AddrOfPinnedObject()); GSL.gsl_poly_complex_workspace_free(workSpace); coefficientHandle.Free(); rootsHandle.Free(); List <double> realRoots = new List <double>(levelSetField.Basis.Degree); for (int i = 0; i < maxNoOfRoots; i++) { double realPart = roots[2 * i]; double imaginaryPart = roots[2 * i + 1]; // Exclude |$realPart| == 1.0 since it doesn't matter if (imaginaryPart == 0.0 && Math.Abs(realPart) <= 1.0 - EPSILON) { realRoots.Add(realPart); } } return(realRoots.OrderBy(d => d).ToArray()); }
/// <summary> /// <see cref="ITestCase.UpdateLevelSet"/> /// </summary> public abstract void UpdateLevelSet(ILevelSet levelSet);