示例#1
0
        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);
        }
示例#2
0
        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");
     }
 }
示例#4
0
        public override void UpdateLevelSet(ILevelSet levelSet)
        {
            LevelSet levelSetField = levelSet as LevelSet;

            if (levelSetField == null)
            {
                throw new ArgumentException();
            }

            levelSetField.ProjectField(LevelSetInitialValue);
        }
示例#5
0
        /// <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;
 }
示例#7
0
        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);
        }
示例#8
0
        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");
                        }
                    }
                }
示例#10
0
 public override void UpdateLevelSet(ILevelSet levelSet)
 {
     ((LevelSet)levelSet).ProjectField(LevelSetInitialValue);
 }
示例#11
0
            /// <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);
            }
示例#12
0
            /// <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());
            }
示例#13
0
文件: TestCase.cs 项目: xyuan/BoSSS
 /// <summary>
 /// <see cref="ITestCase.UpdateLevelSet"/>
 /// </summary>
 public abstract void UpdateLevelSet(ILevelSet levelSet);